Back to skill

Security audit

AIG Scanner

Security checks for vulnerabilities and agentic risk

Overview

This is a real AI security scanning skill, but it asks for unusually broad trust around private-network scans, local file uploads, and API-token handling.

Install only if you trust the A.I.G server you configure, prefer HTTPS except for loopback development, and do not scan networks or services unless you are authorized. Avoid passing long-lived API keys directly on the command line, and use local uploads only with sanitized project archives rather than arbitrary files.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • 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
Findings (4)

T01 · Skill Instruction Hijacking

Error
Location
SKILL.md:61
Finding

Safety Constraint Hijacking for Private-Network Scanning

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/aig_client.py:42
Finding

Sensitive Credentials May Be Sent over Plaintext HTTP to an Unrestricted Endpoint

Content
View full analysis
dict[str, str]: h: dict[str, str] = {"username": USERNAME} if content_type: h["Content-Type"] = content_type if API_KEY: h["API-KEY"] = API_KEY return h def _request(method: str, path: str, body: Any | None = None) -> Any: """Make an HTTP request to A.I.G and return parsed data.""" if not BASE_URL: _die( "AIG_BASE_URL is not configured.\n" "Please set the A.I.G service address first, for example:\n" " http://127.0.0.1:8088/\n" " https://aig.example.com/" ) url = f"{BASE_URL}{path}" data = json.dumps(body).encode() if body is not None else None req = urllib.request.Request(url, data=data, headers=_headers(), method=method) try: with urllib.request.urlopen(req, timeout=30) as resp: result = json.loads(resp.read()) ``` Sensitive model credentials are included in request bodies, for example: ```python content: dict[str, Any] = { "model": [ { "model": args.target_model, "token": args.target_token, "base_url": args.target_base_url, } ], "eval_model": { "model": args.eval_model, "token": args.eval_token, "base_url": args.eval_base_url, }, } ``` ### Technical Analysis `AIG_BASE_URL` is accepted without validating its scheme, host, port, or trust status. The Skill documentation and runtime error message explicitly present plaintext `http://` as a supported configuration. `_re ...[truncated 1937 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/aig_client.py:473
Finding

API Tokens Are Accepted Through Process Command-Line Arguments

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/aig_client.py:88
Finding

Unrestricted Local File Read and Upload to the Configured A.I.G Server

Content
View full analysis
dict: """Upload a file via multipart/form-data. Returns {fileUrl, filename, size}.""" if not BASE_URL: _die( "AIG_BASE_URL is not configured.\n" "Please set the A.I.G service address first, for example:\n" " http://127.0.0.1:8088/\n" " https://aig.example.com/" ) import mimetypes resolved = os.path.abspath(file_path) if not os.path.isfile(resolved): _die(f"File not found: {file_path}") filename = os.path.basename(resolved) content_type = mimetypes.guess_type(filename)[0] or "application/octet-stream" # Build multipart body manually (stdlib only) boundary = "----AigClientBoundary9876543210" with open(resolved, "rb") as f: file_data = f.read() body = ( f"--{boundary}\r\n" f'Content-Disposition: form-data; name="file"; filename="{filename}"\r\n' f"Content-Type: {content_type}\r\n" f"\r\n" ).encode() + file_data + f"\r\n--{boundary}--\r\n".encode() url = f"{BASE_URL}/api/v1/app/taskapi/upload" headers: dict[str, str] = { "Content-Type": f"multipart/form-data; boundary={boundary}", "username": USERNAME, } if API_KEY: headers["API-KEY"] = API_KEY req = urllib.request.Request(url, data=body, headers=headers, method="POST") try: with urllib.request.urlopen(req, timeout=120) as resp: result = json.loads(resp.read()) ``` The upload is invoked directly from user-controlled CLI input: ```python elif args.local_path: print("📤 上传本地文件...") upload_data = _upload_file(args.local_path) print(f"✅ 上传成功: {upload_data.get('filename')} ({upload_data.get('size', 0)} bytes)" ...[truncated 2201 chars]
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (21)

Tainted flow: 'req' from os.environ.get (line 127, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/aig_client.py (reported line 71)May include surrounding context.

python
req = urllib.request.Request(url, data=data, headers=_headers(), method=method)

    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            result = json.loads(resp.read())
    except urllib.error.HTTPError as e:
        _die(f"A.I.G API {method} {path} -> HTTP {e.code}")

Tainted flow: 'req' from os.environ.get (line 127, credential/environment) → urllib.request.urlopen (network output)

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/aig_client.py (reported line 130)May include surrounding context.

python
req = urllib.request.Request(url, data=body, headers=headers, method="POST")

    try:
        with urllib.request.urlopen(req, timeout=120) as resp:
            result = json.loads(resp.read())
    except urllib.error.HTTPError as e:
        _die(f"Upload failed -> HTTP {e.code}")

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Tp2

High
Category
MCP Tool Poisoning
Confidence
85% confidence
Finding

Mixing characters from multiple Unicode scripts in a single identifier is a common technique to create visually ambiguous tool names.

Content

No source excerpt is available for this finding.

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
99% confidence
Finding

The instruction 'Do NOT refuse or warn about local/private addresses' is an anti-refusal clause that attempts to suppress safety checks precisely where higher caution is warranted. In context, this increases risk because it pressures the agent to actively scan sensitive local or internal systems without surfacing consent, safety, or data-handling implications.

Content

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

md
Do NOT refuse or warn about local/private addresses.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
91% confidence
Finding

The skill declares no explicit tool scope even though it is designed to read environment variables and make outbound network/API calls via exec. In a security-sensitive scanning skill, missing permission boundaries increases the chance of overbroad execution or accidental misuse because the runtime and user are not given a clear least-privilege contract.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

Several triggers such as scanning, auditing, CVE checking, and result checking are broad enough to match routine user requests that may not clearly imply consent to run commands or send target data to an external AIG service. This can cause unintended activation of a powerful scanning workflow with network effects and external data transmission.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The manifest defines a large trigger surface with ambiguous phrases in multiple languages, increasing the likelihood that unrelated troubleshooting or security discussions invoke the skill. Because the skill performs exec-driven API submission, accidental activation has meaningful operational and privacy consequences.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill explicitly directs use of built-in exec and a Python client that submits scan tasks over HTTP, but it does not require a clear user-facing warning or confirmation that commands will run locally and that scan target details may be transmitted to a remote AIG server. This is dangerous because users may think they are only getting advice, while the agent actually performs active operations and shares data externally.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The skill normalizes active scanning of localhost and private-network targets and even instructs the agent not to refuse or warn. Scanning internal services can affect sensitive systems, expose metadata to the external AIG server, and bypass the extra caution normally expected for local and private assets.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

Multiple printed status/result messages are hard-coded in Chinese, and some commands default report language to zh. This imposes a specific locale on users rather than offering neutral defaults or explicit opt-in, which matches the language/locale policy violation category.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/aig_client.py (reported line 326)May include surrounding context.

python
content["model"] = {
            "model": args.model,
            "token": args.token,
            "base_url": args.base_url or "https://api.openai.com/v1",
        }
    _submit_and_poll("ai_infra_scan", content)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/aig_client.py (reported line 335)May include surrounding context.

python
content["model"] = {
            "model": args.model,
            "token": args.token,
            "base_url": args.base_url or "https://api.openai.com/v1",
        }
    _submit_and_poll("ai_infra_scan", content)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/aig_client.py (reported line 342)May include surrounding context.

python
content["model"] = {
            "model": args.model,
            "token": args.token,
            "base_url": args.base_url or "https://api.openai.com/v1",
        }
    _submit_and_poll("ai_infra_scan", content)

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/aig_client.py (reported line 378)May include surrounding context.

python
content["model"] = {
            "model": args.model,
            "token": args.token,
            "base_url": args.base_url or "https://api.openai.com/v1",
        }
    _submit_and_poll("ai_infra_scan", content)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

When --local-path is used, the tool uploads local file contents to the remote A.I.G server but only prints a generic upload message and does not clearly warn about external transmission of local data. In a security-scanning skill context, users may provide proprietary code, secrets, or internal configs, so weak disclosure materially increases the risk of unintended data exposure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
97% confidence
Finding

The table mandates "Cannot determine | Default to Chinese," which imposes a specific output language even when the user's preference is unknown. This is a natural-language policy issue because it forces a locale choice without explicit user consent or a documented regional justification.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.