Back to skill

Security audit

AANA Guardrail Skill Bundled Helper Variant

Security checks for vulnerabilities and agentic risk

Overview

This skill is a clearly scoped local guardrail helper, with one bounded implementation caveat around HTTP redirects.

Install only if you trust the local AANA bridge you configure. Keep payloads redacted, avoid secrets or full private records, and prefer a helper version that rejects redirects if strict localhost-only networking is required.

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

Warning
Location
bin/aana_guardrail_check.py:104
Finding

Localhost-Only Network Restriction Can Be Bypassed Through HTTP Redirects

Content
View full analysis

Vulnerability Details

File Location: bin/aana_guardrail_check.py, lines 104–114
Vulnerability Type: Improper validation of redirected network destinations
Risk Level: Medium

Vulnerable Code

python
def post_json(url: str, payload: dict, timeout: float) -> dict:
    data = json.dumps(payload, ensure_ascii=False).encode("utf-8")
    request = urllib.request.Request(
        validate_url(url),
        data=data,
        headers={"Content-Type": "application/json", "Accept": "application/json"},
        method="POST",
    )
    try:
        with urllib.request.urlopen(request, timeout=timeout) as response:
            body = response.read().decode("utf-8")

Technical Analysis

The helper validates only the initial URL passed to urllib.request.Request. Although validate_url() requires the initial hostname to be localhost, urllib.request.urlopen() automatically follows supported HTTP redirects. Redirect destinations are not passed through validate_url().

Consequently, a malicious or compromised localhost bridge can cause the helper to connect to an arbitrary remote destination. This violates the package's documented localhost-only security boundary.

For common POST redirect responses, Python may change the redirected request to a GET and omit the original POST body. This limits direct forwarding of the request body, but does not eliminate the vulnerability: the localhost bridge receives the payload first and can encode sensitive payload data into the redirect target's URL or query string.

Attack Path

  1. A user approves use of a bridge at the permitted localhost address.
  2. The helper posts the review event, including request summaries, candidate summaries, evidence, and metadata, to that bridge.
  3. A malicious or compromised bridge reads the submitted event.
  4. The bridge returns a supported HTTP redirect to an attacker-controlled remote URL, optionally embedding payload content in its path or query string.
  5. `url ...[truncated 807 chars]
Remediation
View remediation

Remediation Suggestions

  1. Disable automatic redirects by installing a custom urllib.request.HTTPRedirectHandler that rejects every redirect response.
  2. If redirects are required, validate every redirect target before following it rather than validating only the initial URL.
  3. Resolve the destination hostname and require every resolved address to be an IPv4 or IPv6 loopback address. This provides stronger enforcement than checking the hostname string alone.
  4. Reject redirects to URLs containing user information, unexpected ports, fragments, or non-HTTP(S) schemes.
  5. Set a strict redirect limit and reject cross-origin redirects.
  6. Add automated tests in which a localhost test server redirects to a non-local address, and verify that the helper refuses the redirected request.
  7. Continue requiring explicit user approval and redacted payloads, because destination controls do not prevent a malicious local bridge from reading the initial payload.
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep

Static analysis

No suspicious patterns detected.