Back to skill

Security audit

Claimback Radar

Security checks for vulnerabilities and agentic risk

Overview

The skill is transparent and purpose-aligned, but users should treat generated billing links and action steps as unverified advice.

Install only if you are comfortable sending the analyzed email or bill text to OpenAI. Verify any cancellation or refund links independently before clicking, and do not let downstream automation execute the generated action receipts without user confirmation.

Vulnerability Patterns
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • 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
Findings (2)

T09 · Insecure Skill Coding Practices

Warning
Location
src/runner.py:24
Finding

Untrusted Model Output Can Produce Attacker-Controlled Links and Instructions

Content
View full analysis

Vulnerability Details

File Location: src/runner.py:24-46; related output instructions in prompts/system.txt:18-19 and prompts/system.txt:38-47
Vulnerability Type: Prompt injection and insufficient validation of security-sensitive model output
Risk Level: Medium

Complete Code Snippet

python
messages = [
    {"role": "system", "content": self.system_prompt},
    {"role": "user", "content": json.dumps(user_input, ensure_ascii=False)}
]

response = self.client.chat.completions.create(
    model=self.model,
    messages=messages,
    response_format={"type": "json_object"},
    temperature=0.2
)

raw = response.choices[0].message.content
try:
    result = json.loads(raw)
except json.JSONDecodeError as e:
    raise ValueError(f"Model returned invalid JSON: {e}\nRaw: {raw}")

# Minimal validation: ensure required keys exist
if "confirmation_card" not in result or "action_receipts" not in result:
    raise ValueError(f"Missing required keys in output. Got: {list(result.keys())}")

return result

The model is instructed to produce security-sensitive links and procedural instructions:

text
- cancellation_method: How to cancel (URL, phone, email, in-app)
- cancellation_link: Direct URL if available

For each risk, generate an action_receipt:
- action_id: unique ID
- action_type: cancel_subscription, claim_refund, negotiate_discount, extend_warranty, review_usage, ignore
- title: Human-readable action title
- deadline: YYYY-MM-DD or null
- priority: critical, high, medium, low
- reason: Why this action is recommended
- estimated_savings: e.g., "$15.49/month" or "$200 total"
- cta_link: Direct link if available
- steps: Concrete steps to complete the action

Technical Analysis

Email, bill, PDF, OCR, and raw-text content are untrusted data. The implementation serializes the entire supplied object into a normal user-role message without clearly iso ...[truncated 2056 chars]

Remediation
View remediation

Remediation Suggestions

  1. Clearly delimit source-document content and state in the system prompt that all instructions found inside it are untrusted data that must never alter system instructions.
  2. Separate trusted contextual fields from untrusted document text rather than sending the entire input object as an undifferentiated message.
  3. Validate every response against schema/output.json with a real JSON Schema validator or strict Pydantic models. Reject unknown fields, incorrect nested types, missing required fields, and invalid enum values.
  4. Permit only https URLs. Reject credentials in URLs, non-web schemes, redirects to untrusted destinations, and malformed hostnames.
  5. Verify cancellation and CTA domains against a trusted provider-domain registry. When verification is unavailable, omit the link or visibly mark it as unverified.
  6. Treat generated links and steps as recommendations requiring user confirmation. Do not allow downstream systems to execute them automatically.
  7. Add adversarial tests containing embedded instructions, deceptive domains, alternate URL schemes, and malformed nested output.

T08 · Insecure Dependencies

Note
Location
requirements.txt:1
Finding

Unbounded Third-Party Dependency Versions Create Reproducibility and Supply-Chain Risk

Content
View full analysis

Vulnerability Details

File Location: requirements.txt:1-3; duplicated constraints in pyproject.toml:13-15
Vulnerability Type: Unpinned dependencies installed without integrity hashes
Risk Level: Low

Complete Code Snippet

text
openai>=1.12.0
python-dotenv>=1.0.0
pydantic>=2.5.0

Equivalent project dependency declarations are:

toml
dependencies = [
    "openai>=1.12.0",
    "python-dotenv>=1.0.0",
    "pydantic>=2.5.0",
]

The documented installation path is:

bash
pip install -r requirements.txt

Technical Analysis

All runtime dependencies use lower bounds without exact versions, upper bounds, a lock file, or package hashes. Separate installations can therefore resolve to materially different dependency versions over time.

This is not evidence that the currently named packages are malicious. The weakness is that installation implicitly trusts any future release satisfying the broad constraint. A compromised, malicious, or incompatible future release could be selected without a corresponding reviewed change to this project.

Python packages may run build-backend or installation-related code and subsequently execute with the privileges of the user running the application. Missing hashes also prevents pip from verifying that an artifact matches a project-reviewed artifact.

Attack Path

  1. A dependency publisher account, package release process, or distribution artifact is compromised, or a future release introduces a security defect.
  2. The affected release still satisfies one of the broad minimum-version constraints.
  3. A user follows the documented pip install -r requirements.txt command.
  4. Pip resolves and installs the newer affected release because no lock file, exact version, or approved hash prevents it.
  5. Malicious installation or runtime code executes in the user environment when the package is installed or imported.

...[truncated 418 chars]

Remediation
View remediation

Remediation Suggestions

  1. Generate and commit a reviewed lock file containing exact transitive dependency versions.
  2. Use integrity hashes for production installation, such as a hash-locked requirements file installed with pip --require-hashes.
  3. Keep broad compatibility declarations in pyproject.toml only when needed for library consumers, while deploying from a separately locked and tested dependency set.
  4. Update dependencies through controlled pull requests with automated vulnerability, license, and provenance checks.
  5. Test locked updates in an isolated environment before release.
  6. Prefer isolated virtual environments and avoid installing the project with administrative privileges.
Vulnerability Patterns
  • 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
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
Findings (19)

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 · main.py (reported line 18)May include surrounding context.

python
sys.exit(1)

    # Explicit env loading with warning
    env_path = Path(".env")
    if env_path.exists():
        print("⚠️  Loading .env file from current directory...")
        print("⚠️  Ensure no unrelated secrets are stored in this .env file.")

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 · README.md (reported line 23)May include surrounding context.

md
# Explicit env loading with warning
    env_path = Path(".env")
    if env_path.exists():
        print("⚠️  Loading .env file from current directory...")
        print("⚠️  Ensure no unrelated secrets are stored in this .env file.")
        load_dotenv(dotenv_path=env_path, override=False)

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 · main.py (reported line 20)May include surrounding context.

python
# Explicit env loading with warning
    env_path = Path(".env")
    if env_path.exists():
        print("⚠️  Loading .env file from current directory...")
        print("⚠️  Ensure no unrelated secrets are stored in this .env file.")
        load_dotenv(dotenv_path=env_path, override=False)

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 · main.py (reported line 27)May include surrounding context.

python
# Explicit env loading with warning
    env_path = Path(".env")
    if env_path.exists():
        print("⚠️  Loading .env file from current directory...")
        print("⚠️  Ensure no unrelated secrets are stored in this .env file.")
        load_dotenv(dotenv_path=env_path, override=False)

Credential Access

High
Category
Privilege Escalation
Confidence
72% confidence
Finding

Implicitly loading a .env file from the current working directory can cause the program to consume attacker-controlled configuration when executed in an untrusted folder. While this snippet only reads OPENAI_API_KEY, trusting ambient local files for credentials/config can enable confused-deputy behavior, unintended account usage, or downstream abuse if the runner makes network calls using that key.

Content

Scanner excerpt · main.py (reported line 21)May include surrounding context.

python
env_path = Path(".env")
    if env_path.exists():
        print("⚠️  Loading .env file from current directory...")
        print("⚠️  Ensure no unrelated secrets are stored in this .env file.")
        load_dotenv(dotenv_path=env_path, override=False)

    api_key = os.getenv("OPENAI_API_KEY")

Direct Prompt Extraction

High
Category
System Prompt Leakage
Confidence
85% confidence
Finding

Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Content

Scanner excerpt · src/runner.py (reported line 17)May include surrounding context.

python
def _load_prompt(self) -> str:
        prompt_path = Path(__file__).parent.parent / "prompts" / "system.txt"
        return prompt_path.read_text(encoding="utf-8")

    def run(self, user_input: Dict[str, Any]) -> Dict[str, Any]:
        """

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

No manifest is available, so there is no declared purpose or scope that would justify loading a local .env file and reading an OPENAI_API_KEY from the environment. This gives the skill a credential-access capability that is not supported by any stated intent in the provided context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The code sends the entire user_input payload to OpenAI's external API via chat.completions.create, and there is no indication in this file of notice, consent, minimization, or redaction before transmission. If user_input contains personal, financial, or otherwise sensitive claimback data, this creates a real privacy and compliance risk through third-party disclosure.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: setuptools has 10 known advisory(ies) (CVE-2013-1633 (Setuptools vulnerable to Man-in-the-middle attacks); CVE-2025-47273 (setuptools has a path traversal vulnerability in PackageIndex.download that lead); CVE-2024-6345 (setuptools vulnerable to Command Injection via package URL) +7 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

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: wheel has 4 known advisory(ies) (CVE-2026-24049 (Wheel Affected by Arbitrary File Permission Modification via Path Traversal in w); CVE-2022-40898 (pypa/wheel vulnerable to Regular Expression denial of service (ReDoS)); CVE-2022-40898 (An issue discovered in Python Packaging Authority (PyPA) Wheel 0.37.1 and earlie) +1 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

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Vague Triggers

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

This is a manifest file, so vague-trigger review applies. The description says the skill is an "AI-powered inbox scanner" for broad outcomes like refunds and savings opportunities, but it does not define specific activation phrases, limits, or exclusion conditions, which could contribute to overly broad invocation matching in systems that use manifest descriptions for routing.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), 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

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: pydantic has 4 known advisory(ies) (CVE-2021-29510 (Use of "infinity" as an input to datetime and date fields causes infinite loop i); CVE-2024-3772 (Pydantic regular expression denial of service); CVE-2021-29510 (Pydantic is a data validation and settings management using Python type hinting.) +1 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

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unverifiable Dependency: pytest has 2 known advisory(ies) (CVE-2025-71176 (pytest has vulnerable tmpdir handling); CVE-2025-71176 (pytest has vulnerable tmpdir handling)), 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

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
95% confidence
Finding

The dependency is specified with a lower bound only (openai>=1.12.0), which allows future installs to resolve to different versions over time. This weakens reproducibility and can inadvertently introduce vulnerable or breaking releases via normal dependency resolution or supply-chain compromise.

Content

Scanner excerpt · requirements.txt (reported line 1)May include surrounding context.

text
openai>=1.12.0
python-dotenv>=1.0.0
pydantic>=2.5.0

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

python-dotenv>=1.0.0 is unpinned, so installations are not reproducible and may pull newer releases with security defects or incompatible behavior. In a security context, this increases supply-chain risk because the exact code executed in different environments cannot be verified from the manifest alone.

Content

Scanner excerpt · requirements.txt (reported line 2)May include surrounding context.

text
openai>=1.12.0
python-dotenv>=1.0.0
pydantic>=2.5.0

Unverifiable Dependency: python-dotenv has 2 known advisory(ies) (CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
92% confidence
Finding

The manifest references python-dotenv without an exact version, and that package has known advisories in some releases. Because the installed version is unverifiable from this file, it is impossible to confirm whether deployments are affected, which creates avoidable uncertainty around a dependency with known security history.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
98% confidence
Finding

pydantic>=2.5.0 permits any later version, making builds non-deterministic and preventing reliable assessment of exposure to known vulnerabilities. This can lead to accidental adoption of affected releases or regressions that change validation/security behavior.

Content

Scanner excerpt · requirements.txt (reported line 3)May include surrounding context.

text
openai>=1.12.0
python-dotenv>=1.0.0
pydantic>=2.5.0

Unverifiable Dependency: pydantic has 4 known advisory(ies) (CVE-2021-29510 (Use of "infinity" as an input to datetime and date fields causes infinite loop i); CVE-2024-3772 (Pydantic regular expression denial of service); CVE-2021-29510 (Pydantic is a data validation and settings management using Python type hinting.) +1 more), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
93% confidence
Finding

pydantic has known advisories affecting certain versions, but this requirements file does not identify which version will actually be installed. That makes vulnerability status unverifiable and undermines security review, especially for a library central to input parsing and validation.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.