Back to skill

Security audit

TwitterShots

Security checks for vulnerabilities and agentic risk

Overview

This skill is a straightforward Twitter/X screenshot generator that uses the documented TwitterShots API, but users should understand that tweet identifiers and an API key are sent to that third-party service.

Install only if you are comfortable sending tweet IDs, rendering options, optional background image URLs, and your TwitterShots API key to TwitterShots. Prefer TWITTERSHOTS_API_KEY from a protected environment or secret manager instead of --api-key or shell history, and use the skill only when you explicitly want a screenshot generated.

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
scripts/screenshot_tweet.py:221
Finding

API Key Exposure Through Command-Line Arguments

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
SKILL.md:17
Finding

Unpinned Third-Party Python Dependency

Content
View full analysis
Remediation
View remediation
\ --hash=sha256: ``` 3. Pin and hash transitive dependencies where the packaging workflow permits. 4. Install dependencies in an isolated virtual environment rather than into the system Python environment. 5. Use a trusted package index and verify repository configuration before installation. 6. Add automated dependency vulnerability scanning and controlled update review. 7. Replace the unconstrained installation message with instructions that reference the project's locked dependency file, such as: ```bash python -m pip install --require-hashes -r requirements.txt ``` ]]>
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (20)

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

Critical
Category
Data Flow
Confidence
90% confidence
Finding

Credentials or environment variables flow to a network sink. This is a high-confidence indicator of credential exfiltration.

Content

Scanner excerpt · scripts/screenshot_tweet.py (reported line 111)May include surrounding context.

python
url = f"{API_BASE}/{tweet_id}"
    
    response = requests.get(
        url,
        headers={
            "X-API-KEY": api_key,

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The README describes generating screenshots through the TwitterShots API but does not clearly warn users that tweet URLs, tweet IDs, and related formatting choices are sent to an external service. This omission undermines informed consent and can expose user activity, targets of interest, or sensitive workflow context to a third party.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README states that the skill 'triggers automatically when you paste a tweet URL in the chat' without defining scope, confirmation behavior, or data-handling boundaries. In an agent environment, broad automatic triggers can cause unintended invocation and silent transmission of user-provided tweet URLs to the external TwitterShots service, increasing the risk of privacy leaks and prompt-trigger abuse.

Content

No source excerpt is available for this finding.

Skill Enumeration

Medium
Category
Agent Snooping
Confidence
85% confidence
Finding

Skill enumerates or reads other installed skills. Access to other skills' SKILL.md files or the skills directory reveals prompt instructions, capabilities, and secrets that should be invisible to peer skills.

Content

Scanner excerpt · README.md (reported line 34)May include surrounding context.

Claude Code (claude.ai / Claude desktop)

Skills live in ~/.claude/skills/. Clone this repo:

bash
git clone https://github.com/twittershots/skills.git ~/.claude/skills/twittershots

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The phrase 'invoke the skill when relevant' is too vague for a security-sensitive integration because it leaves invocation decisions to broad model interpretation. That ambiguity can lead to accidental execution in unrelated contexts and unintended disclosure of tweet URLs or IDs to an external service.

Content

No source excerpt is available for this finding.

Vague Triggers

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The usage section encourages natural-language triggering like 'Simply paste a tweet URL or ID' and 'automatically invoke this Skill' without clear constraints or consent steps. In practice, this can make the skill fire on incidental content and send user-supplied links or identifiers to a third-party API without sufficiently explicit intent.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
95% confidence
Finding

The skill performs network access to a third-party API and reads a secret from the environment, but it does not declare an explicit tool/permission scope. That omission weakens reviewability and policy enforcement because consumers cannot easily tell that the skill will transmit user-supplied tweet identifiers and an API credential to an external service.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · SKILL.md (reported line 9)May include surrounding context.

md
generate tweet image, convert tweet to PNG/SVG/HTML, create tweet screenshot
  for social media (Instagram, TikTok), or mentions "TwitterShots", "tweet screenshot",
  "capture tweet", "tweet image". Triggers on tweet URLs (twitter.com/*/status/* or x.com/*/status/*)
  or tweet IDs. Default to format=png and theme=light without asking follow-up questions;
  if the user explicitly provides format and/or theme, use the user-provided values.
homepage: https://github.com/twittershots/skills
source: https://github.com/twittershots/skills

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

This skill is explicitly designed to send tweet identifiers and rendering options to api.twittershots.com, along with an API key in a request header. External transmission is expected for the feature, but it still creates confidentiality and supply-chain risk because user content and metadata are sent to a third party.

Content

Scanner excerpt · SKILL.md (reported line 45)May include surrounding context.

API Request

Endpoint: GET https://api.twittershots.com/api/v1/screenshot/:statusId

Required Header:

text

External Transmission

Medium
Category
Data Exfiltration
Confidence
85% confidence
Finding

The skill allows a user-controlled backgroundImage HTTPS URL to be forwarded to the external rendering service. That can enable server-side fetching by the third-party service, creating SSRF-like or privacy risks against the remote service and causing user-supplied URLs to be transmitted without restriction.

Content

Scanner excerpt · SKILL.md (reported line 134)May include surrounding context.

bash
# Gradient background
curl -X GET "https://api.twittershots.com/api/v1/screenshot/1617979122625712128?format=png&containerBackground=linear-gradient(90deg,%23003f5b,%232b4b7d,%235f5195)" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "Accept: image/png" \
  -o tweet-gradient.png

External Transmission

Medium
Category
Data Exfiltration
Confidence
96% confidence
Finding

The Python example performs the actual outbound request and includes the API key header, confirming the skill sends data and credentials to a third-party service. This is expected functionality, but it remains security-relevant because compromise or misuse of the remote service could expose request contents or abuse the credential.

Content

Scanner excerpt · SKILL.md (reported line 178)May include surrounding context.

md
params["backgroundImage"] = background_image
    
    response = requests.get(
        f"https://api.twittershots.com/api/v1/screenshot/{tweet_id}",
        headers={
            "X-API-KEY": api_key,
            "Accept": f"image/{format}" if format != "html" else "text/html"

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 81)May include surrounding context.

md
sys.exit(1)


API_BASE = "https://api.twittershots.com/api/v1/screenshot"


def extract_tweet_id(input_str: str) -> str:

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 90)May include surrounding context.

md
sys.exit(1)


API_BASE = "https://api.twittershots.com/api/v1/screenshot"


def extract_tweet_id(input_str: str) -> str:

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 99)May include surrounding context.

md
sys.exit(1)


API_BASE = "https://api.twittershots.com/api/v1/screenshot"


def extract_tweet_id(input_str: str) -> str:

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 108)May include surrounding context.

md
sys.exit(1)


API_BASE = "https://api.twittershots.com/api/v1/screenshot"


def extract_tweet_id(input_str: str) -> str:

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · SKILL.md (reported line 124)May include surrounding context.

md
sys.exit(1)


API_BASE = "https://api.twittershots.com/api/v1/screenshot"


def extract_tweet_id(input_str: str) -> str:

External Transmission

Medium
Category
Data Exfiltration
Confidence
60% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · scripts/screenshot_tweet.py (reported line 33)May include surrounding context.

python
sys.exit(1)


API_BASE = "https://api.twittershots.com/api/v1/screenshot"


def extract_tweet_id(input_str: str) -> str:

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
88% confidence
Finding

This markdown file applies to SQP-2, and it explicitly tells the agent to "Save buffer to file" as part of the workflow. While file output is part of the skill's purpose, the documentation does not warn the user that using the skill may create local files or require choosing a safe path/filename, which is a missing disclosure for a data-affecting action.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This code makes an HTTP request to a third-party service and transmits the requested tweet ID plus user-supplied rendering options. Although the script's purpose implies API usage, there is no clear disclosure in the runtime messages or docstring that user input is sent to an external service.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

The code accesses the TWITTERSHOTS_API_KEY environment variable, which is a sensitive credential source. While required for functionality, the file does not include an explicit warning or comment noting that it reads credentials from the environment.

Content

No source excerpt is available for this finding.