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:
- Least privilege: Only enable whatβs needed
- Defense in depth: Multiple security layers
- Environment awareness: Different rules per environment
- Audit trail: Log all security decisions
The next chapter covers validation and fallback mechanisms.
Navigation