Back to skill

Security audit

interpretable-attribution

Security checks for vulnerabilities and agentic risk

Overview

The skill performs attribution as advertised, but it runs user-supplied Python and includes a broad persistent learner module without enough scoping or warning.

Install only if you are comfortable reviewing and running local Python code. Treat any --predict file as fully trusted executable code, not as a passive model definition, and avoid using learner.py unless you intentionally want persistent notes/preferences written to the selected skill directory.

Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
Findings (11)

Dangerous chain: exec() wrapping compile

Critical
Category
Dangerous Code Execution
Content
return selftest()
    if not (a.data and a.predict and a.instance):
        print("用法: attributor.py --data d.json --predict p.py --instance i.json [--label label]"); sys.exit(2)
    ns = {}; exec(compile(open(a.predict, encoding="utf-8").read(), a.predict, "exec"), ns)
    predict = ns["predict"]
    rows = json.load(open(a.data, encoding="utf-8"))
    inst = json.load(open(a.instance, encoding="utf-8"))
Confidence
99% confidence
Finding
The script reads a user-supplied Python file from --predict and executes it with exec(compile(...)). This gives arbitrary code execution with the privileges of the process, not merely evaluation of a prediction function, so a crafted model file can run OS commands, exfiltrate data, or alter the environment.

exec() call detected

High
Category
Dangerous Code Execution
Content
return selftest()
    if not (a.data and a.predict and a.instance):
        print("用法: attributor.py --data d.json --predict p.py --instance i.json [--label label]"); sys.exit(2)
    ns = {}; exec(compile(open(a.predict, encoding="utf-8").read(), a.predict, "exec"), ns)
    predict = ns["predict"]
    rows = json.load(open(a.data, encoding="utf-8"))
    inst = json.load(open(a.instance, encoding="utf-8"))
Confidence
99% confidence
Finding
The exec() call is directly reachable from command-line input because the path supplied in --predict is opened and executed. In this skill's context, users may reasonably expect attribution analysis, not arbitrary code execution, making the behavior unexpectedly dangerous.

compile() call detected

Medium
Category
Dangerous Code Execution
Content
return selftest()
    if not (a.data and a.predict and a.instance):
        print("用法: attributor.py --data d.json --predict p.py --instance i.json [--label label]"); sys.exit(2)
    ns = {}; exec(compile(open(a.predict, encoding="utf-8").read(), a.predict, "exec"), ns)
    predict = ns["predict"]
    rows = json.load(open(a.data, encoding="utf-8"))
    inst = json.load(open(a.instance, encoding="utf-8"))
Confidence
92% confidence
Finding
compile() alone is not always dangerous, but here it is part of an execution chain that turns file contents into runnable code. Because it compiles untrusted input for immediate exec, it materially contributes to arbitrary code execution.

Direct flow: open (file read) → exec (code execution)

High
Category
Data Flow
Content
return selftest()
    if not (a.data and a.predict and a.instance):
        print("用法: attributor.py --data d.json --predict p.py --instance i.json [--label label]"); sys.exit(2)
    ns = {}; exec(compile(open(a.predict, encoding="utf-8").read(), a.predict, "exec"), ns)
    predict = ns["predict"]
    rows = json.load(open(a.data, encoding="utf-8"))
    inst = json.load(open(a.instance, encoding="utf-8"))
Confidence
100% confidence
Finding
This is a classic unsafe data-to-code flow: file contents from open(...).read() are passed into compile and then exec. Any attacker-controlled or accidentally unsafe file can execute arbitrary Python statements during analysis, enabling full compromise of the runtime environment.

Lp3

Medium
Category
MCP Least Privilege
Confidence
78% confidence
Finding
The skill instructs users to run a Python script that performs attribution and self-testing, and the static analyzer detected file-write capability despite no declared permissions. Undeclared write behavior is a security and governance problem because consumers cannot accurately assess what the skill may modify, and write access could be abused to overwrite local files, emit artifacts in unsafe locations, or persist data unexpectedly.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
The skill's stated purpose is interpretable attribution, but it broadens scope by executing any Python supplied as a predictor implementation. That mismatch increases risk because consumers may pass third-party predictor files assuming they are just model definitions, when they are actually arbitrary programs.

Description-Behavior Mismatch

High
Confidence
97% confidence
Finding
This file implements a generic cross-skill telemetry and self-learning subsystem, which is materially broader than the manifest's stated interpretable-attribution purpose. Capability creep is dangerous here because it creates persistent data collection and modification behavior that users and reviewers would not expect from an attribution engine, increasing the chance of unauthorized profiling or tampering across skills.

Context-Inappropriate Capability

Medium
Confidence
95% confidence
Finding
The code persistently stores operational telemetry, free-form notes, and user preferences to disk without necessity being established by the skill's attribution function. Free-form notes may capture sensitive user inputs or internal workflow details, and persistent accumulation creates a privacy and compliance risk even if no exploit primitive is present.

Context-Inappropriate Capability

High
Confidence
99% confidence
Finding
resolve_skill_dir accepts either an arbitrary filesystem directory or a skill name resolved under ~/.workbuddy/skills, allowing this module to read from and write to learned_patterns.json for other skills. That cross-skill modification capability exceeds the declared purpose of this attribution skill and can be abused to tamper with other skills' state, collect their usage metadata, or create a foothold for broader profiling.

Missing User Warnings

Medium
Confidence
90% confidence
Finding
The tool executes a user-supplied Python file without an explicit warning, confirmation, or trust boundary disclosure. While the core issue is the arbitrary code execution itself, the lack of disclosure increases the chance of unsafe operator behavior and accidental execution of untrusted files.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The prefer path writes user preferences to disk, and the broader module also stores notes and recent operations, without any user-facing warning or consent flow. Silent persistence is risky because users may provide sensitive preferences or notes assuming they are ephemeral, creating privacy exposure and surprise data retention.

Static analysis

No suspicious patterns detected.