Back to skill

Security audit

Bitly URL Shortner and Manager

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent Bitly management CLI that uses local Bitly credentials for expected account and link operations, with some credential-handling cautions but no evidence of deception or unrelated behavior.

Use this only with a Bitly token you intend the agent to use. Prefer setting BITLY_ENV_FILE or shell environment variables explicitly, protect the token file, review or remove any legacy bitly-credentials.json file, and remember that shorten/create-custom commands can change your Bitly account while exports can write link data to local files.

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
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • 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
Findings (11)

Credential Access

High
Category
Privilege Escalation
Confidence
96% confidence
Finding

The skill is explicitly designed to load Bitly credentials from fixed plaintext locations under the user's profile, including a legacy JSON credential file. In an agent-skill context, credential discovery and use from predictable local paths is more sensitive because it enables silent access to existing tokens without interactive user confirmation, increasing the chance of unauthorized use if the skill is invoked unexpectedly or modified.

Content

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

python
API_BASE = "https://api-ssl.bitly.com/v4"
DEFAULT_ENV_FILE = Path(r"C:\Users\Big Dell\.openclaw\bitly.env")
LEGACY_JSON_FILE = Path(r"C:\Users\Big Dell\.openclaw\bitly-credentials.json")


class BitlyError(Exception):

Credential Access

High
Category
Privilege Escalation
Confidence
95% confidence
Finding

The code requires and automatically consumes a Bitly access token from environment variables or local files, then uses it for authenticated API actions. In the context of an agent skill, automatic token use is security-relevant because bearer tokens grant direct account access; if the skill is triggered without clear consent boundaries, it can perform account queries, link creation, and exports using the user's standing credentials.

Content

Scanner excerpt · scripts/bitly_manager.py (reported line 62)May include surrounding context.

python
merged["redirect_uri"] = merged["redirect_uri"] or data.get("redirect_uri")

    if not merged["access_token"]:
        raise BitlyError(f"No access token found. Set BITLY_ACCESS_TOKEN in {env_path}")
    return merged

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 · scripts/bitly_manager.py (reported line 373)May include surrounding context.

python
add_link_filters(export)
    export.set_defaults(func=cmd_export_links)

    env = sub.add_parser("env-template", help="Print or write a local .env template")
    env.add_argument("--output", default=None)
    env.set_defaults(func=cmd_env_template)
    return p

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
90% confidence
Finding

The skill invokes a local Python CLI that uses environment variables, reads and writes local files, and performs network operations against the Bitly API, but the manifest declares no explicit tool scope or permissions. This creates a governance gap: an agent or reviewer cannot easily determine the intended capabilities, increasing the risk of over-privileged execution, accidental secret exposure from env usage, or unsafe file/network access in downstream automation.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code loads sensitive Bitly credentials from environment variables and local files, including a legacy JSON credential file, but provides no confirmation prompt, log message, docstring, or comment disclosing that credential material will be accessed. For a code file, access to sensitive environment variables or credentials should have some visible disclosure unless otherwise documented.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The request helper sends authenticated HTTP requests containing bearer tokens and, depending on command, user-provided URLs, account metadata, or analytics queries to Bitly. There is no confirmation prompt, warning comment, or user-facing disclosure in this file that commands will contact a remote service and transmit this data.

Content

No source excerpt is available for this finding.

Dynamic import via __import__()

Medium
Category
Dangerous Code Execution
Confidence
75% confidence
Finding

Dynamic import() can load arbitrary modules at runtime, bypassing static analysis and potentially importing malicious code.

Content

Scanner excerpt · scripts/bitly_manager.py (reported line 107)May include surrounding context.

python
print("")
        return
    keys = sorted({k for row in rows if isinstance(row, dict) for k in row.keys()})
    writer = csv.DictWriter(__import__('sys').stdout, fieldnames=keys)
    writer.writeheader()
    for row in rows:
        if isinstance(row, dict):

Tainted flow: 'data' from pathlib.Path.read_text (line 55, file read) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/bitly_manager.py (reported line 119)May include surrounding context.

python
return
    out = Path(path)
    out.parent.mkdir(parents=True, exist_ok=True)
    out.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")


def pick_group_guid(token: str, explicit: str | None, creds: dict[str, Any]) -> str:

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This markdown file documents authentication via a bearer token and storing secrets in a local .env file, but it does not include any warning about protecting credentials or avoiding accidental disclosure. For markdown files, SQP-2 applies when behavior affecting privacy or sensitive data is described without user-facing warning.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The export-links command creates parent directories and writes potentially sensitive link data to a user-specified file path, but the code contains no warning, comment, or prompt indicating that local files will be created or overwritten. For code files, file writes should have at least some visible disclosure when not otherwise documented.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

When --output is provided, this command writes a .env-style template containing credential field names to disk, but there is no visible disclosure that a local file will be created for storing secrets. Although not destructive, it is still a file write related to sensitive configuration without a warning or explanatory comment.

Content

No source excerpt is available for this finding.