Back to skill

Security audit

firewall-aiops

Security checks for vulnerabilities and agentic risk

Overview

This firewall administration skill is transparent and purpose-aligned, but it exposes high-impact firewall write operations over MCP without a built-in approval or read-only gate.

Install only with a read-only firewall API account by default, and grant write permissions only for controlled maintenance windows. Treat MCP write tools as capable of changing live firewall behavior or causing outages; require your own explicit approval workflow before apply_changes, reconfigure, reboot, kill_states, restart_service, or alias edits. Protect ~/.firewall-aiops, avoid putting long-lived master passwords in shared environments, and migrate away from legacy plaintext secret environment variables.

Vulnerability Patterns
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Error
Location
SKILL.md:200
Finding

Destructive MCP operations do not enforce user approval

Content
View full analysis

Vulnerability Details

File Location: SKILL.md:200-205; corroborated by references/agent-guardrails.md:45-46
Vulnerability Type: Missing authorization gate for privileged state-changing operations
Risk Level: High

Vulnerable Snippet

From SKILL.md:200-205:

markdown
> **Authorization is not this skill's job**: there is no read-only switch, policy
> file, or approval gate. Whether a write runs is the agent's judgement or the
> connecting account's permissions — point the tool at an API user without write
> scope and writes fail at the server. Every call is still audited.
> `FIREWALL_AUDIT_APPROVED_BY` / `FIREWALL_AUDIT_RATIONALE` are optional audit
> annotations, recorded when set but never required.

The absence of MCP confirmation is explicitly documented in references/agent-guardrails.md:45-46:

markdown
| "Confirm before anything destructive" | Every write takes `dry_run=True` for a preview that runs the same guards as the real call. ⚠️ **The double confirmation is a CLI feature, and only `toggle_rule` and `undo apply` have CLI commands** — `apply_changes`, `reconfigure`, `reboot`, `restart_service`, `kill_states`, `add_alias_entry` and `remove_alias_entry` are reachable only over MCP, where nothing prompts. Keep your own confirmation for those. |

Technical Analysis

The Skill exposes privileged MCP operations that can commit firewall configuration, restart services, terminate active network states, edit aliases, or reboot the firewall. Although these operations support dry-run behavior and are recorded in an audit database, neither dry-run nor explicit approval is enforced before execution.

The only effective authorization boundary is the permission level of the configured firewall API account. When that account has write access, an agent can directly execute destructive operations without:

  • A mandatory prior dry run.
  • An interactive user confirmation.
  • A required approval identity or rationale.
  • A read-on ...[truncated 2075 chars]
Remediation
View remediation

Remediation Suggestions

  1. Add a read-only mode and enable it by default. Do not register or expose state-changing MCP tools while this mode is active.
  2. Require a mandatory, short-lived approval token for every state-changing MCP operation. Bind the token to the target firewall, operation, normalized parameters, approving identity, and expiration time.
  3. Enforce a two-stage workflow for high-risk operations:
    • First call: mandatory dry run producing a stable operation digest.
    • Second call: execution requiring explicit approval of that exact digest.
  4. Reject execution when the proposed parameters differ from the approved dry-run parameters.
  5. Require FIREWALL_AUDIT_APPROVED_BY and FIREWALL_AUDIT_RATIONALE, or equivalent structured approval fields, for high-risk writes rather than treating them as optional annotations.
  6. Add explicit confirmation gates for reboot, kill_states, service restarts, configuration commits, and reconfiguration operations.
  7. Preserve least privilege by documenting and providing separate read-only and write-capable firewall roles. Encourage read-only credentials as the default configuration.
  8. Keep the existing audit and self-lockout protections as defense-in-depth, but do not treat them as substitutes for authorization.
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • Rogue AgentSelf-Modification, Session Persistence
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (9)

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/cli-reference.md (reported line 12)May include surrounding context.

firewall-aiops init # interactive wizard (asks for the platform: opnsense/pfsense) firewall-aiops doctor # check config, secrets, connectivity # firmware/version query on both platforms firewall-aiops doctor --skip-auth # config/secret checks only (no network) firewall-aiops mcp # start the MCP server (stdio)

text

Tool Parameter Abuse

High
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Content

Scanner excerpt · references/setup-guide.md (reported line 71)May include surrounding context.

firewall-aiops init # interactive wizard (asks for the platform: opnsense/pfsense) firewall-aiops doctor # check config, secrets, connectivity # firmware/version query on both platforms firewall-aiops doctor --skip-auth # config/secret checks only (no network) firewall-aiops mcp # start the MCP server (stdio)

text

Credential Access

High
Category
Privilege Escalation
Confidence
60% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/cli-reference.md (reported line 22)May include surrounding context.

firewall-aiops secret set [--value ] # store OPNsense secret / pfSense key (hidden prompt if no --value) firewall-aiops secret list # list target names with a stored secret (values never shown) firewall-aiops secret rm # delete a stored secret firewall-aiops secret migrate # import legacy plaintext .env into the encrypted store firewall-aiops secret rotate-password # re-encrypt under a new master password

text

Session Persistence

Medium
Category
Rogue Agent
Confidence
93% confidence
Finding

The skill explicitly persists sensitive operational data locally: an audit SQLite database and an encrypted credential store, with the master password optionally supplied via an environment variable and a legacy plaintext secret environment variable still honored. This creates a real persistence surface for secrets and privileged firewall actions; if the host, file permissions, process environment, backups, or logs are exposed, an attacker may recover credentials or detailed administrative history.

Content

Scanner excerpt · SKILL.md (reported line 23)May include surrounding context.

md
metadata: {"openclaw":{"requires":{"anyBins":["firewall-aiops","uvx"]},"optional":{"env":["FIREWALL_AIOPS_CONFIG","FIREWALL_AIOPS_MASTER_PASSWORD"]},"homepage":"https://github.com/AIops-tools/Firewall-AIops","emoji":"🛡️","os":["macos","linux"]}}
compatibility: >
  Standalone, self-governed firewall operations across OPNsense (REST API /api/..., API key+secret via HTTP Basic auth) and pfSense (REST API v2 /api/v2/..., API key via X-API-Key header). Each target in the config names its own platform, and a name-keyed platform registry selects the API shape, so the same tools work on both and one config can span a mixed estate. The governance harness (audit, policy, token/runaway budget, undo, risk-tiers) is bundled in the package — no external skill-family dependency.
  All write operations are audited to a local SQLite DB under ~/.firewall-aiops/ (relocatable via FIREWALL_AIOPS_HOME).
  Credentials: the OPNsense API secret (paired with the API key) or the pfSense API key is stored ENCRYPTED in ~/.firewall-aiops/secrets.enc (Fernet/AES-128 + scrypt-derived key) — never plaintext on disk. Run 'firewall-aiops init' to onboard (it asks for the platform), or 'firewall-aiops secret set <target>' to add one. The store is unlocked by a master password from FIREWALL_AIOPS_MASTER_PASSWORD (non-interactive/MCP/CI) or an interactive prompt (CLI on a TTY). A legacy plaintext env var FIREWALL_<TARGET_NAME_UPPER>_SECRET is still honoured as a fallback with a deprecation warning (migrate with 'firewall-aiops secret migrate'). The secret is presented as HTTP Basic auth (OPNsense) or an X-API-Key header (pfSense) at request time and held only in memory; secrets are never logged or echoed.
  State-changing operations pass through the @governed_tool decorator (budget guard + audit + a descriptive risk-tier label, not a gate). The high-risk commits (apply_changes, reconfigure) and reboot are risk=high with dry_run; reboot is irreversible. Reversible writes (toggle_rule, add_alias_entry, r
...[truncated 25 chars]

Session Persistence

Medium
Category
Rogue Agent
Confidence
78% confidence
Finding

The skill records inverse undo descriptors and prior object state for reversible writes, which means historical firewall configuration details are intentionally persisted after changes. In a firewall administration context, that stored before-state can reveal sensitive rules, aliases, addresses, or management paths and can be abused by anyone who gains local access to reconstruct or replay prior privileged configurations.

Content

Scanner excerpt · SKILL.md (reported line 150)May include surrounding context.

md
3. `firewall-aiops rules show <uuid>` → read the full rule before touching it.
4. `firewall-aiops rules toggle <uuid> --disable --dry-run` → prints the exact call,
   changes nothing.
5. `firewall-aiops rules toggle <uuid> --disable` → double-confirm; the write fetches the
   rule's real prior enabled flag and records an inverse undo descriptor with an `_undo_id`.
6. MCP `pending_changes` → read what the commit would actually make live, including
   whether any staged rule covers the endpoint this tool manages the firewall through.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

The guardrail explicitly states that the tool does not enforce read-only mode or approval prompts and that writes are reachable over MCP without confirmation. In a firewall-administration skill, this materially increases the chance that an LLM or calling agent can perform disruptive changes such as toggling rules, killing states, restarting services, or rebooting the appliance without an authorization checkpoint, causing outage or lockout.

Content

Scanner excerpt · references/agent-guardrails.md (reported line 15)May include surrounding context.

md
## Authorization is not this tool's job — decide it where it belongs

Whether a write should happen is your decision, or the account's. The tool does
not gate it — there is no read-only switch and no approval prompt to configure.
The two right places to control read vs write:

- **The account you connect with.** Give the OPNsense/pfSense API user a

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · references/cli-reference.md (reported line 12)May include surrounding context.

firewall-aiops init # interactive wizard (asks for the platform: opnsense/pfsense) firewall-aiops doctor # check config, secrets, connectivity # firmware/version query on both platforms firewall-aiops doctor --skip-auth # config/secret checks only (no network) firewall-aiops mcp # start the MCP server (stdio)

text

Unsafe Defaults

Medium
Category
Tool Misuse
Confidence
80% confidence
Finding

Tool defaults are unsafe or overly permissive (e.g. disabled TLS verification, no authentication, world-writable permissions). Unsafe defaults widen the attack surface.

Content

Scanner excerpt · references/setup-guide.md (reported line 71)May include surrounding context.

firewall-aiops init # interactive wizard (asks for the platform: opnsense/pfsense) firewall-aiops doctor # check config, secrets, connectivity # firmware/version query on both platforms firewall-aiops doctor --skip-auth # config/secret checks only (no network) firewall-aiops mcp # start the MCP server (stdio)

text

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · references/setup-guide.md (reported line 77)May include surrounding context.

md
## Security notes

- The secret (OPNsense API secret / pfSense API key) is **never** written to disk in
  plaintext — only the scrypt salt and Fernet ciphertext are stored (chmod 600). The
  master password is never stored.
- A legacy plaintext env var `FIREWALL_<TARGET_NAME_UPPER>_SECRET` is honoured as a
  fallback with a deprecation warning (migrate with `firewall-aiops secret migrate`).

Static analysis

No suspicious patterns detected.