UnifyWeaver

Chapter 4: Target Security

Different compilation targets have different security characteristics. This chapter covers the security considerations for each target and how to configure firewall policies accordingly.

Security Comparison Matrix

Target Compile Safety Runtime Sandbox Memory Safety Network Isolation Recommendation
Bash Low None N/A Manual Development only
AWK Low Limited N/A None Data processing
Python Medium Limited Managed Manual Controlled environments
Go High OS-level Safe Compile-time Production
Rust Very High OS-level Guaranteed Compile-time High-security
C#/.NET High CLR sandbox Managed CAS Enterprise
Prolog (SWI) Medium Limited Managed Manual Development
Prolog (GNU) Medium None Safe None Embedded

Bash Target Security

Risks

Risk Description Mitigation
Command injection User input in commands Strict quoting, validation
Shell expansion Glob, variable expansion Use set -f, quote variables
Privilege escalation sudo, setuid Never in generated code
Path manipulation PATH injection Absolute paths only

Firewall Policy

% .firewall for Bash-heavy projects

% Allow Bash only in development
:- allow(target(bash)) :- environment(development).
:- deny(target(bash)) :- environment(production).

% Deny dangerous features
:- deny(bash_feature(eval)).
:- deny(bash_feature(source)).
:- deny(bash_feature(sudo)).

Generated Code Safety

UnifyWeaver generates safe Bash by default:

#!/bin/bash
set -euo pipefail  # Exit on error, undefined vars, pipe failures

# Variables always quoted
input="${1:-}"

# Arithmetic in $((...)), not backticks
result=$((input * 2))

# No eval, no dynamic execution
echo "$result"

AWK Target Security

Risks

Risk Description Mitigation
System commands system() function Disable in policy
File access getline < file Restrict paths
Output redirection print > file Validate destinations

Firewall Policy

% .firewall for AWK

% Allow AWK for data processing
:- allow(target(awk)).

% Deny dangerous AWK features
:- deny(awk_feature(system)).
:- deny(awk_feature(getline_file)).
:- deny(awk_feature(output_redirect)).

Safe AWK Generation

#!/usr/bin/awk -f
# Generated by UnifyWeaver - no system() calls

BEGIN { FS="\t"; OFS="\t" }

# Safe field processing only
{
    ip = $1
    status = $2
    if (status >= 400) {
        print ip, status, "error"
    }
}

Python Target Security

Risks

Risk Description Mitigation
Import hijacking Malicious modules Module whitelist
Pickle attacks Unsafe deserialization Disable pickle
subprocess Shell commands Block subprocess
Network access HTTP, sockets Network policy

Firewall Policy

% .firewall for Python

% Allow Python with restrictions
:- allow(target(python)).

% Block dangerous modules
:- deny(python_import(subprocess)).
:- deny(python_import(os.system)).
:- deny(python_import(pickle)).
:- deny(python_import(eval)).

% Block network unless explicitly allowed
:- deny(python_import(socket)) :- \+ network_allowed.
:- deny(python_import(requests)) :- \+ network_allowed.
:- deny(python_import(urllib)) :- \+ network_allowed.

% Allow data processing modules
:- allow(python_import(json)).
:- allow(python_import(csv)).
:- allow(python_import(collections)).

Safe Python Generation

#!/usr/bin/env python3
"""Generated by UnifyWeaver - restricted imports"""

import json  # Allowed
import sys   # Allowed for stdin/stdout

# No subprocess, no os.system, no network
def process_record(record):
    return {
        'input': record.get('value'),
        'output': record.get('value', 0) * 2
    }

# Streaming from stdin
for line in sys.stdin:
    record = json.loads(line)
    result = process_record(record)
    print(json.dumps(result))

Go Target Security

Advantages

Feature Security Benefit
Static typing Compile-time type safety
No eval No code injection
Memory safety No buffer overflows
Compile-time imports No runtime import hijacking

Firewall Policy

% .firewall for Go

% Allow Go for production
:- allow(target(go)).
:- allow(target(go)) :- environment(production).

% Go-specific controls
:- deny(go_import("os/exec")) :- \+ shell_allowed.
:- deny(go_import("net/http")) :- \+ network_allowed.
:- allow(go_import("encoding/json")).
:- allow(go_import("bufio")).

Safe Go Generation

package main

import (
    "bufio"
    "encoding/json"
    "os"
)

// No os/exec, no unsafe, no cgo
func main() {
    scanner := bufio.NewScanner(os.Stdin)
    for scanner.Scan() {
        var record map[string]interface{}
        json.Unmarshal(scanner.Bytes(), &record)

        result := process(record)

        output, _ := json.Marshal(result)
        os.Stdout.Write(output)
        os.Stdout.Write([]byte("\n"))
    }
}

Rust Target Security

Advantages

Feature Security Benefit
Ownership system Memory safety guaranteed
No null pointers No null dereference
No data races Thread safety
Minimal runtime Small attack surface

Firewall Policy

% .firewall for Rust

% Allow Rust for high-security applications
:- allow(target(rust)).

% Rust-specific controls
:- deny(rust_feature(unsafe)) :- \+ unsafe_approved.
:- deny(rust_crate("libc")) :- \+ ffi_approved.
:- allow(rust_crate("serde")).
:- allow(rust_crate("serde_json")).

Safe Rust Generation

use std::io::{self, BufRead, Write};
use serde::{Deserialize, Serialize};

// No unsafe blocks, no FFI
#[derive(Deserialize)]
struct Input {
    value: i64,
}

#[derive(Serialize)]
struct Output {
    input: i64,
    output: i64,
}

fn main() {
    let stdin = io::stdin();
    let stdout = io::stdout();
    let mut stdout = stdout.lock();

    for line in stdin.lock().lines() {
        if let Ok(line) = line {
            if let Ok(input) = serde_json::from_str::<Input>(&line) {
                let output = Output {
                    input: input.value,
                    output: input.value * 2,
                };
                serde_json::to_writer(&mut stdout, &output).unwrap();
                writeln!(stdout).unwrap();
            }
        }
    }
}

C#/.NET Target Security

Advantages

Feature Security Benefit
CLR sandbox Runtime isolation
CAS (Code Access Security) Permission-based security
Type safety No memory corruption
Strong naming Assembly verification

Firewall Policy

% .firewall for C#

% Allow C# for enterprise applications
:- allow(target(csharp)).

% .NET-specific controls
:- deny(dotnet_namespace("System.Diagnostics.Process")).
:- deny(dotnet_namespace("System.Reflection.Emit")).
:- deny(dotnet_namespace("System.Runtime.InteropServices")).

% Allow safe namespaces
:- allow(dotnet_namespace("System.Text.Json")).
:- allow(dotnet_namespace("System.Collections.Generic")).
:- allow(dotnet_namespace("System.Linq")).

Prolog Target Security

SWI-Prolog

Feature Security Consideration
Library system Control imports
Network libraries Explicit enable
File I/O Path restrictions
Process execution Block by default

GNU Prolog

Feature Security Consideration
Native compilation Binary auditing harder
FFI Block unsafe bindings
Limited libraries Smaller attack surface

Firewall Policy

% .firewall for Prolog

% Dialect control
:- allow(prolog_target(swi)) :- environment(development).
:- allow(prolog_target(gnu)) :- environment(production).

% Module restrictions
:- deny(import_module(library(http/_))).
:- deny(import_module(library(process))).
:- deny(import_module(library(socket))).

% Compilation control
:- allow(compile(native)) :- environment(production).
:- deny(compile(native)) :- environment(development).

% Implies: If compiling, require code review
:- implies(compile(native), code_review(approved)).

Cross-Target Security

Pipeline Security

When chaining targets, each stage inherits restrictions:

% Pipeline: AWK β†’ Python β†’ Go
% Each stage must pass its own firewall checks

pipeline_firewall([
    stage(parse, awk, [deny(system)]),
    stage(transform, python, [deny(subprocess)]),
    stage(aggregate, go, [deny(os_exec)])
]).

Data Flow Security

Prevent secret leakage between stages:

% Secrets must not appear in intermediate formats
:- deny(data_flow(secret, tsv)).
:- deny(data_flow(secret, json_unencrypted)).
:- allow(data_flow(secret, encrypted_json)).

Environment-Based Policies

Development

% .firewall.development
:- firewall_mode(guidance).

% Permissive for development
:- allow(target(_)).
:- allow(compile(_)).
:- guidance(target(bash), 'Bash is fine for development').

Staging

% .firewall.staging
:- firewall_mode(enforce).

% Moderate restrictions
:- allow(target(go)).
:- allow(target(python)).
:- deny(target(bash)).
:- require(validation(passed)).

Production

% .firewall.production
:- firewall_mode(enforce).

% Strict production policy
:- allow(target(go)).
:- allow(target(rust)).
:- deny(target(bash)).
:- deny(target(python)).
:- require(validation(passed)).
:- require(code_review(approved)).
:- require(security_scan(passed)).

Summary

Target security considerations:

Target Best For Avoid When
Bash Quick scripts, glue Production, untrusted input
AWK Text processing Complex logic, network
Python Prototyping, ML Untrusted modules
Go Production services None (safe default)
Rust High-security Learning curve issue
C#/.NET Enterprise Non-Windows (historically)
Prolog Logic, meta-programming Native compilation concerns

Key principles:

  1. Least privilege: Only enable what’s needed
  2. Defense in depth: Multiple security layers
  3. Environment awareness: Different rules per environment
  4. Audit trail: Log all security decisions

The next chapter covers validation and fallback mechanisms.


← Previous: Chapter 3: Lifecycle Hooks πŸ“– Book 8: Security & Firewall Next: Chapter 5: Validation & Fallback β†’