ruvnet/ruflo · error · Error

WgFirewallService: refusing unsafe ${label}: ${JSON.stringif

Error message

WgFirewallService: refusing unsafe ${label}: ${JSON.stringify(s)}

What it means

Defense-in-depth guard in assertSafeRuleArg: before any value is spliced into an nftables/pf rule line it is checked against a strict character allowlist. Fires when a firewall rule argument (e.g. a peer endpoint, IP, or key taken from a possibly poisoned remote manifest) contains characters outside the set nft/pf syntax actually needs, meaning an injection attempt or corrupt data would otherwise escape its slot in the rule string.

Source

Thrown at v3/@claude-flow/plugin-agent-federation/src/domain/services/wg-firewall-service.ts:78

  switch (process.platform) {
    case 'linux': return 'linux-nftables';
    case 'darwin': return 'darwin-pf';
    default:
      // Other platforms (win32/freebsd) — fall back to linux-nftables since
      // most production federation hosts are linux. The operator can
      // override via config.platform.
      return 'linux-nftables';
  }
}

/**
 * Defense-in-depth: every value spliced into a rule line goes through this
 * filter. Allows the chars `nft`/`pf` syntax actually needs and refuses
 * anything else — a poisoned manifest can't escape the rule string.
 */
function assertSafeRuleArg(s: string, label: string): void {
  if (!/^[A-Za-z0-9_./:-]+$/.test(s)) {
    throw new Error(`WgFirewallService: refusing unsafe ${label}: ${JSON.stringify(s)}`);
  }
}

function projectRuleNftables(rule: WgPortRule, srcIP: string): string {
  if (rule.proto === 'all') {
    return `        ip saddr ${srcIP} accept`;
  }
  if (rule.port !== undefined) {
    return `        ip saddr ${srcIP} ${rule.proto} dport ${rule.port} accept`;
  }
  if (rule.portRange) {
    const [lo, hi] = rule.portRange;
    return `        ip saddr ${srcIP} ${rule.proto} dport ${lo}-${hi} accept`;
  }
  throw new Error(`projectRuleNftables: rule missing port/portRange/all: ${JSON.stringify(rule)}`);
}

function projectRulePf(rule: WgPortRule, iface: string, srcIP: string): string {

View on GitHub (pinned to fa13ee4ad6)

Solutions

  1. Sanitize the input so it contains only characters allowed for the given label.
  2. Construct firewall rules from validated structured fields instead of raw strings.
Defensive patterns

Strategy: validation

When it happens

Trigger: WgFirewallService rejects a rule/label value that contains unsafe characters or patterns.

Common situations: User-supplied firewall input containing shell metacharacters, newlines, or invalid tokens.


AI-assisted analysis of ruvnet/ruflo@fa13ee4ad6 (2026-08-18). Data as JSON: /api/errors/b0b13f4cd115bb0c. Report an issue: GitHub.