Back to skill

Security audit

ai-data-delivery

Security checks for vulnerabilities and agentic risk

Overview

ClawScan marked this skill suspicious because scanners report risky service-management capabilities beyond its stated purpose and weaknesses that could affect the integrity of semantic metrics; the scan was partial.

The verdict is suspicious, so consider the reported scope and metric-integrity issues before installing. The scan inspected 139 of 145 components and marked coverage partial; several checks were degraded or reached parser/output limits, so the results do not establish that uninspected behavior is safe. The scanner recommends not installing.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Output HandlingUnvalidated Output Injection, Cross-Context Output, Unbounded Output
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
Findings (18)

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
88% confidence
Finding

The supplied code's primary function is service lifecycle management, not semantic modeling or validation. Although building and starting a local workbench could be a supporting implementation detail, this utility accepts configurable projects and commands without tying its operations to the declared semantic workbench. Its general build, launch, and process-replacement capabilities materially exceed the stated purpose. Process-ownership checks, restricted subprocess execution, and endpoint safeguards limit risk but do not resolve that scope mismatch.

Content

No source excerpt is available for this finding.

Cloud Metadata Access

High
Category
Server-Side Request Forgery
Confidence
90% confidence
Finding

Code accesses a cloud instance metadata endpoint (e.g. 169.254.169.254). A single request can return temporary IAM credentials, making this a high-value SSRF target for credential theft.

Content

Scanner excerpt · scripts/_network.py (reported line 21)May include surrounding context.

python
MAX_RESPONSE = 4 * 1024 * 1024
_PRIVATE = tuple(ipaddress.ip_network(x) for x in ('10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7'))
_NAT64 = ipaddress.ip_network('64:ff9b::/96')
_METADATA = {ipaddress.ip_address(x) for x in ('169.254.169.254', '100.100.100.200', '168.63.129.16', 'fd00:ec2::254')}
_METADATA_HOSTS = {'metadata.google.internal', 'metadata.google', 'instance-data.ec2.internal', 'instance-data'}

Cloud Metadata Access

High
Category
Server-Side Request Forgery
Confidence
85% confidence
Finding

Code accesses a cloud instance metadata endpoint (e.g. 169.254.169.254). A single request can return temporary IAM credentials, making this a high-value SSRF target for credential theft.

Content

Scanner excerpt · scripts/_network.py (reported line 21)May include surrounding context.

python
MAX_RESPONSE = 4 * 1024 * 1024
_PRIVATE = tuple(ipaddress.ip_network(x) for x in ('10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7'))
_NAT64 = ipaddress.ip_network('64:ff9b::/96')
_METADATA = {ipaddress.ip_address(x) for x in ('169.254.169.254', '100.100.100.200', '168.63.129.16', 'fd00:ec2::254')}
_METADATA_HOSTS = {'metadata.google.internal', 'metadata.google', 'instance-data.ec2.internal', 'instance-data'}

Cloud Metadata Access

High
Category
Server-Side Request Forgery
Confidence
85% confidence
Finding

Code accesses a cloud instance metadata endpoint (e.g. 169.254.169.254). A single request can return temporary IAM credentials, making this a high-value SSRF target for credential theft.

Content

Scanner excerpt · scripts/_network.py (reported line 21)May include surrounding context.

python
MAX_RESPONSE = 4 * 1024 * 1024
_PRIVATE = tuple(ipaddress.ip_network(x) for x in ('10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7'))
_NAT64 = ipaddress.ip_network('64:ff9b::/96')
_METADATA = {ipaddress.ip_address(x) for x in ('169.254.169.254', '100.100.100.200', '168.63.129.16', 'fd00:ec2::254')}
_METADATA_HOSTS = {'metadata.google.internal', 'metadata.google', 'instance-data.ec2.internal', 'instance-data'}

Cloud Metadata Access

High
Category
Server-Side Request Forgery
Confidence
90% confidence
Finding

Code accesses a cloud instance metadata endpoint (e.g. 169.254.169.254). A single request can return temporary IAM credentials, making this a high-value SSRF target for credential theft.

Content

Scanner excerpt · scripts/_network.py (reported line 22)May include surrounding context.

python
_PRIVATE = tuple(ipaddress.ip_network(x) for x in ('10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fc00::/7'))
_NAT64 = ipaddress.ip_network('64:ff9b::/96')
_METADATA = {ipaddress.ip_address(x) for x in ('169.254.169.254', '100.100.100.200', '168.63.129.16', 'fd00:ec2::254')}
_METADATA_HOSTS = {'metadata.google.internal', 'metadata.google', 'instance-data.ec2.internal', 'instance-data'}


def _check_ip(value, allow_remote):

Skill declares no tool scope ('permissions' or 'allowed-tools') but code capabilities were detected: env, file_read, file_write, network, shell.

Medium
Category
MCP Least Privilege
Confidence
70% confidence
Finding

Without declared permissions the skill's intent is opaque and cannot be validated.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · examples/onboarding/run_demo.py (reported line 21)May include surrounding context.

python
def run(script, *args):
    command = [sys.executable, str(SCRIPTS / script), *map(str, args)]
    result = subprocess.run(command, capture_output=True, text=True, encoding="utf-8",
                            env=minimal_env())
    if result.returncode:
        raise RuntimeError(f"{script}: {result.stdout}\n{result.stderr}")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
88% confidence
Finding

Although argument-array execution prevents shell injection, --domain is joined to HERE without enforcing containment, allowing absolute paths or traversal to select an external build_db.py. If an attacker can influence that domain selection and supply the external directory, the runner executes their Python code and can also delete an existing domain.db outside the intended mock tree.

Content

Scanner excerpt · mocks/run_mock.py (reported line 41)May include surrounding context.

python
def run_step(name, cmd, cwd):
    p = subprocess.run([sys.executable] + cmd, capture_output=True, text=True,
                       encoding="utf-8", errors="replace", cwd=cwd, env=minimal_env())
    ok = p.returncode == 0
    print(f"[{'PASS' if ok else 'FAIL'}] {name}")

The live-evaluation step lacks a warning that evaluation questions are transmitted to the configured engine.

Medium
Category
Output Handling
Confidence
86% confidence
Finding

The Stage 6 workflow runs live evaluation against $ENGINE and requires the formal LLM chain. It does not warn that case questions may contain sensitive business information or require confirming that the destination and downstream processing are authorized before transmission.

Content

No source excerpt is available for this finding.

Predicate translation can silently change metric definitions while marking drafts ready to merge.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

The translator extracts recognized comparisons without checking that it consumed the entire predicate, then joins every extracted comparison with AND. Consequently, OR expressions, unsupported filters, or grouping can be silently changed or omitted while the resulting COUNT draft is marked ready to merge, undermining metric integrity in this semantic-delivery workflow.

Content

No source excerpt is available for this finding.

Missing-field metrics are emitted as mergeable review operations despite the documented checklist-only boundary.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

Missing predicate fields produce issues and are skipped, but COUNT metrics with those issues still become review operations containing the remaining, potentially broadened predicate. The generated operations omit the blocking issues themselves, so applying ops_review.yaml can introduce incomplete metrics despite the documented checklist-only boundary; manual review reduces but does not eliminate this risk.

Content

No source excerpt is available for this finding.

Gold promotion accepts missing expected results despite documenting that undefined expectations must be rejected.

Medium
Category
Excessive Agency
Confidence
98% confidence
Finding

Only expect.type is validated, while missing value or rows fields are converted to None and written into the gold set. An incomplete card can therefore create or replace a regression expectation with an undefined result, weakening the evidence used by subsequent evaluation and release decisions.

Content

No source excerpt is available for this finding.

The skill includes a general project build and service-replacement capability beyond semantic-asset delivery.

Medium
Category
Excessive Agency
Confidence
85% confidence
Finding

The manifest supports a local semantic workbench, but this tool accepts caller-selected project directories, build commands, artifacts and foreground service commands rather than managing a specific workbench component. L194 executes the supplied build, L203–L209 stop the previously recorded service, and L218 launches its replacement, providing a general application lifecycle capability not directly required for semantic modeling or evidence-based handoff. Ownership checks and shell-free execution reduce operational risks but do not establish a purpose-specific boundary.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/rebuild.py (reported line 194)May include surrounding context.

python
with log_path.open('ab') as output, build_log.open('ab') as build_output:
                if build is not None:
                    log('building; output remains in the build log')
                    completed = subprocess.run(build, cwd=project, env=env, shell=False,
                                               stdin=subprocess.DEVNULL, stdout=build_output,
                                               stderr=subprocess.STDOUT, timeout=args.build_timeout,
                                               **_launch_options())

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/rebuild.py (reported line 218)May include surrounding context.

python
raise ValueError('port remains occupied; no other listener will be stopped')
                proc, process, new_record = None, None, None
                try:
                    proc = subprocess.Popen(start, cwd=project, env=env, shell=False,
                                            stdin=subprocess.DEVNULL, stdout=output,
                                            stderr=subprocess.STDOUT, close_fds=True,
                                            **_launch_options())

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/release_gate.py (reported line 19)May include surrounding context.

python
def run_gate(name, command):
    result = subprocess.run([sys.executable, str(HERE / command[0]), *command[1:]],
                            capture_output=True, text=True, encoding="utf-8", errors="replace",
                            env=minimal_env())
    return {"gate": name, "status": "pass" if result.returncode == 0 else "fail",

Unverifiable Dependency: PyYAML has 8 known advisory(ies) (CVE-2019-20477 (Deserialization of Untrusted Data in PyYAML); CVE-2020-1747 (Improper Input Validation in PyYAML); CVE-2020-14343 (Improper Input Validation in PyYAML) +5 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

OSV returned advisories for this package, but its resolved version is unknown. A package-name lookup does not establish whether the installed release is affected by those advisories.

Content

No source excerpt is available for this finding.

The schema inspection can silently create a database file when the supplied path does not exist.

Low
Category
Output Handling
Confidence
98% confidence
Finding

sqlite3.connect opens the database in create-if-missing mode, so a purported inspection operation can create a file at the supplied path. This violates the read-only expectation and can leave misleading empty databases after path mistakes; with no expected tables, the check can also report zero errors.

Content

No source excerpt is available for this finding.