Back to skill

Security audit

Upstage Information Extraction

Security checks for vulnerabilities and agentic risk

Overview

The skill has a legitimate Upstage document-extraction purpose, but it uploads potentially sensitive documents and instructs agents to save extracted data to predictable local files by default.

Install only if you are comfortable sending the relevant documents to Upstage for processing. Treat extracted output as sensitive, prefer an explicit private destination with restricted permissions, avoid shared temp directories, and delete saved JSON files when no longer needed.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
SKILL.md:178
Finding

Predictable Output Filename in a Shared Temporary Directory

Content
View full analysis

Vulnerability Details

File Location: SKILL.md, lines 178-181
Vulnerability Type: Predictable and potentially unsafe temporary-file handling
Risk Level: Medium

Vulnerable Code Snippet

markdown
## Output Files

- **Default**: write extracted JSON to `<system-temp>/<input-stem>.extracted.json` (e.g., `/tmp/invoice.extracted.json`). Use `tempfile.gettempdir()` for cross-platform code.
- **Override**: if the user specifies an output path, use it.
- **Always print the resolved absolute path** in your response so the user can locate the file.

Technical Analysis

The skill instructs implementations to derive a deterministic filename from the input stem and place it directly in a shared system temporary directory. It does not require exclusive file creation, restrictive permissions, symlink checks, or an unpredictable filename.

On multi-user systems, an attacker who can write to the same temporary directory may predict the destination and create it before extraction begins. If the implementation follows symbolic links or opens the path with ordinary overwrite semantics, the attacker could redirect the write to another file accessible to the victim process. If permissions are permissive, another local user may also read extracted receipt or invoice data.

The instruction to print the resolved absolute path is not independently sufficient for exploitation, but it unnecessarily exposes storage-location details and may place sensitive path information into logs or conversation records.

Attack Path

  1. The attacker learns or predicts the source document stem, such as invoice.
  2. The attacker predicts the output as /tmp/invoice.extracted.json.
  3. Before extraction begins, the attacker creates that path as a symbolic link to another writable target or prepares it for later observation.
  4. The extraction implementation opens the predictable path without exclusive creation or symlink protection.
  5. Extracted document data is written t ...[truncated 710 chars]
Remediation
View remediation

Remediation Suggestions

  • Create temporary output using tempfile.NamedTemporaryFile(delete=False) or tempfile.mkstemp() rather than constructing a predictable path with tempfile.gettempdir().
  • Use an unpredictable suffix and exclusive atomic creation.
  • Apply owner-only permissions, such as mode 0600, because extracted documents may contain sensitive business or personal data.
  • Do not follow symbolic links when opening output files. Where supported, use O_NOFOLLOW together with O_CREAT | O_EXCL.
  • If a stable user-facing filename is required, create a private per-run directory with mode 0700, write securely inside it, and atomically rename the completed file after validating the destination.
  • Validate user-supplied output paths and require explicit confirmation before overwriting existing files.
  • Avoid printing absolute paths unless necessary. When paths must be reported, ensure they are not sent to unrelated logs or external services.
  • Document cleanup and retention behavior for extracted files.
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (14)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

The skill is designed to send user documents to a third-party API for processing, but it does not prominently warn that potentially sensitive receipts, invoices, and trade documents will leave the local environment. Because these documents often contain personal, financial, or commercial data, omission of a privacy/transmission warning can lead to uninformed disclosure.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 19)May include surrounding context.

md
client = OpenAI(
    api_key=os.environ["UPSTAGE_API_KEY"],
    base_url="https://api.upstage.ai/v1/information-extraction"
)

response = client.chat.completions.create(

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 54)May include surrounding context.

md
client = OpenAI(
    api_key=os.environ["UPSTAGE_API_KEY"],
    base_url="https://api.upstage.ai/v1/information-extraction"
)

response = client.chat.completions.create(

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 55)May include surrounding context.

md
client = OpenAI(
    api_key=os.environ["UPSTAGE_API_KEY"],
    base_url="https://api.upstage.ai/v1/information-extraction"
)

response = client.chat.completions.create(

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 56)May include surrounding context.

md
client = OpenAI(
    api_key=os.environ["UPSTAGE_API_KEY"],
    base_url="https://api.upstage.ai/v1/information-extraction"
)

response = client.chat.completions.create(

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 58)May include surrounding context.

md
client = OpenAI(
    api_key=os.environ["UPSTAGE_API_KEY"],
    base_url="https://api.upstage.ai/v1/information-extraction"
)

response = client.chat.completions.create(

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 126)May include surrounding context.

md
client = OpenAI(
    api_key=os.environ["UPSTAGE_API_KEY"],
    base_url="https://api.upstage.ai/v1/information-extraction"
)

response = client.chat.completions.create(

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 155)May include surrounding context.

md
client = OpenAI(
    api_key=os.environ["UPSTAGE_API_KEY"],
    base_url="https://api.upstage.ai/v1/information-extraction"
)

response = client.chat.completions.create(

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% 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 168)May include surrounding context.

md
client = OpenAI(
    api_key=os.environ["UPSTAGE_API_KEY"],
    base_url="https://api.upstage.ai/v1/information-extraction"
)

response = client.chat.completions.create(

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 154)May include surrounding context.

md
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}

# 1. Submit async job
response = requests.post(
    "https://api.upstage.ai/v1/information-extraction/async",
    headers=headers,
    json={

External Transmission

Medium
Category
Data Exfiltration
Confidence
70% 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 154)May include surrounding context.

md
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}

# 1. Submit async job
response = requests.post(
    "https://api.upstage.ai/v1/information-extraction/async",
    headers=headers,
    json={

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill manifest describes API-based information extraction, but the documentation adds default local file-writing behavior that materially expands what the skill does. This can cause unintended persistence of potentially sensitive extracted data on disk, creating confidentiality and lifecycle risks that users would not reasonably expect from the manifest alone.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The instruction to write extracted JSON to a local path by default, and to honor arbitrary user-specified output paths, introduces filesystem side effects unrelated to the core extraction purpose. That creates risk of overwriting files, placing sensitive output in insecure locations, or enabling path abuse in environments where the agent has broad filesystem access.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The documentation instructs the skill to create local output files by default without a clear warning to the user that a file will be created and where it will be stored. Even when the path is temporary, this can leave sensitive extracted data on disk unexpectedly and increase the chance of accidental exposure.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.