Back to skill

Security audit

Raccoon Data Analysis

Security checks for vulnerabilities and agentic risk

Overview

This is a coherent remote data-analysis skill, but it needs review because it can send files and credentials to an unvalidated host and mishandles downloaded artifacts.

Install only if you trust the Raccoon service and can set RACCOON_API_HOST to a known HTTPS endpoint. Do not use it for sensitive files without confirming the destination and retention expectations. Prefer running with --no-open, avoid sharing auth-check output, and treat downloaded artifacts as untrusted until the host, download URL, and filename handling are fixed.

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 (5)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.py:42
Finding

Bearer Credentials and User Files Can Be Transmitted to an Unvalidated Endpoint

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.py:233
Finding

Server-Controlled Artifact URLs Enable Client-Side SSRF

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/main.py:234
Finding

Server-Controlled Artifact Filenames Permit Path Traversal and File Overwrite

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:466
Finding

Authentication Check Discloses a Significant Portion of the Bearer Token

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/main.py:405
Finding

Untrusted Remote Artifacts Are Automatically Opened with Local Applications

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • 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 (33)

Tainted flow: 'headers' from os.environ.get (line 534, 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/main.py (reported line 460)May include surrounding context.

python
url = f"{host}/api/open/office/v2/sessions"
    try:
        resp = requests.get(url, headers=headers, params={"paging.limit": 1}, timeout=10)
        if resp.status_code == 200:
            data = resp.json()
            if data.get("code") == 0:

Tainted flow: 'h' from os.environ.get (line 491, credential/environment) → requests.post (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/main.py (reported line 492)May include surrounding context.

python
url = f"{host}{path}"
    if method == "POST" and files:
        h = {k: v for k, v in headers.items() if k != "Content-Type"}
        resp = requests.post(url, headers=h, files=files, stream=True, timeout=120)
    elif method == "POST":
        resp = requests.post(url, headers=headers, json=data, stream=True, timeout=120)
    else:

Tainted flow: 'headers' from os.environ.get (line 534, credential/environment) → requests.post (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/main.py (reported line 494)May include surrounding context.

python
h = {k: v for k, v in headers.items() if k != "Content-Type"}
        resp = requests.post(url, headers=h, files=files, stream=True, timeout=120)
    elif method == "POST":
        resp = requests.post(url, headers=headers, json=data, stream=True, timeout=120)
    else:
        resp = requests.get(url, headers=headers, params=data, timeout=30)
        return resp.json().get("data") if resp.status_code == 200 else None

Tainted flow: 'headers' from os.environ.get (line 534, 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/main.py (reported line 496)May include surrounding context.

python
elif method == "POST":
        resp = requests.post(url, headers=headers, json=data, stream=True, timeout=120)
    else:
        resp = requests.get(url, headers=headers, params=data, timeout=30)
        return resp.json().get("data") if resp.status_code == 200 else None

    if resp.status_code != 200:

Tainted flow: 'headers' from os.environ.get (line 534, credential/environment) → requests.post (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/main.py (reported line 540)May include surrounding context.

python
}

    print("\n[步骤1] 创建会话...")
    resp = requests.post(
        f"{host}/api/open/office/v2/sessions",
        headers=headers,
        json={"name": "Python示例会话"},

Tainted flow: 'upload_headers' from os.environ.get (line 556, credential/environment) → requests.post (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/main.py (reported line 557)May include surrounding context.

python
batch_id = str(uuid.uuid4())
    csv_content = "name,age,score\nAlice,25,88\nBob,30,92\nCarol,28,85\nDave,35,95\nEve,22,78"
    upload_headers = {k: v for k, v in headers.items() if k != "Content-Type"}
    resp = requests.post(
        f"{host}/api/open/office/v2/sessions/default_session/{batch_id}/files",
        headers=upload_headers,
        files={"file": ("sample_data.csv", csv_content.encode(), "text/csv")},

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
if [ -f "./SKILL.md" ] && [ -f "./scripts/main.py" ] && grep -q "raccoon-dataanalysis" "./SKILL.md"; then

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
if [ -f "./SKILL.md" ] && [ -f "./scripts/main.py" ] && grep -q "raccoon-dataanalysis" "./SKILL.md"; then

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
if [ -f "./SKILL.md" ] && [ -f "./scripts/main.py" ] && grep -q "raccoon-dataanalysis" "./SKILL.md"; then

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
if [ -f "./SKILL.md" ] && [ -f "./scripts/main.py" ] && grep -q "raccoon-dataanalysis" "./SKILL.md"; then

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
93% confidence
Finding

The skill explicitly instructs the agent to use shell, environment variables, local file access, and networked Python scripts to upload user files to a remote host, but it declares no explicit tool scope or allowed-tools boundary. This creates a real security control gap: a host platform or reviewer cannot enforce least privilege, and the skill may gain broader execution or data-access capability than users expect.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The manifest description and core instructions are written as mandatory Chinese-language operating guidance, and the skill name/examples all assume Chinese interaction. There is no statement that users may choose another language or that the Chinese-only behavior is required for a region-specific compliance reason.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
89% confidence
Finding

This markdown file documents behaviors that can transmit user content or files to external services, including enabling web search and uploading files, but it does not include any warning about privacy, sensitive data handling, or external data disclosure. Under the markdown-specific SQP-2 criteria, descriptions of behaviors affecting user data or privacy should warn users about those impacts.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
83% confidence
Finding

The module docstring and all CLI-facing text are presented exclusively in Chinese, and there is no indication that users may choose another language. Under the stated policy, forcing a specific language without opt-in can be a natural-language policy violation unless the locale restriction is explicitly documented and justified.

Content

No source excerpt is available for this finding.

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · scripts/main.py (reported line 64)May include surrounding context.

python
def _upload_headers(self):
        return {"Authorization": f"Bearer {self.token}"}

    def _request(self, method, path, json_data=None, params=None, timeout=None):
        url = f"{self.host}{path}"
        timeout = timeout or self.REQUEST_TIMEOUT
        resp = requests.request(

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill uploads local user-selected files to a remote API but does not present a clear user-facing warning or confirmation about off-device transmission. In the context of data analysis, users may upload sensitive spreadsheets or CSVs, so silent transfer can lead to unintended disclosure of confidential data.

Content

No source excerpt is available for this finding.

Tainted flow: 'url' from requests.post (line 141, network input) → requests.post (network output)

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

python
url = f"{self.host}/api/open/office/v2/sessions/default_session/{batch_id}/files"
        filename = os.path.basename(file_path)
        with open(file_path, "rb") as f:
            resp = requests.post(
                url, headers=self._upload_headers,
                files={"file": (filename, f)}, timeout=60,
            )

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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/main.py (reported line 142)May include surrounding context.

python
def _stream_chat(self, session_id, data):
        url = f"{self.host}/api/open/office/v2/sessions/{session_id}/chat/conversations"
        resp = requests.post(
            url, headers=self._headers, json=data,
            stream=True, timeout=self.STREAM_TIMEOUT,
        )

Tainted flow: 'url' from requests.post (line 141, network input) → requests.post (network output)

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

python
def _stream_chat(self, session_id, data):
        url = f"{self.host}/api/open/office/v2/sessions/{session_id}/chat/conversations"
        resp = requests.post(
            url, headers=self._headers, json=data,
            stream=True, timeout=self.STREAM_TIMEOUT,
        )

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill automatically opens downloaded artifacts with local OS handlers, causing local applications to process remote content without a fresh trust decision from the user. In a data-analysis tool that downloads model-generated files, this increases the attack surface for malicious files or unsafe file-handler behavior and is not strictly necessary for core functionality.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/main.py (reported line 344)May include surrounding context.

python
system = platform.system()
    try:
        if system == "Darwin":
            subprocess.run(["open", path], check=False)
        elif system == "Linux":
            subprocess.run(["xdg-open", path], check=False)
    except Exception:

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/main.py (reported line 346)May include surrounding context.

python
if system == "Darwin":
            subprocess.run(["open", path], check=False)
        elif system == "Linux":
            subprocess.run(["xdg-open", path], check=False)
    except Exception:
        pass

Tainted flow: 'url' from requests.post (line 141, network input) → requests.get (network output)

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

python
url = f"{host}/api/open/office/v2/sessions"
    try:
        resp = requests.get(url, headers=headers, params={"paging.limit": 1}, timeout=10)
        if resp.status_code == 200:
            data = resp.json()
            if data.get("code") == 0:

Tainted flow: 'url' from requests.post (line 141, network input) → requests.post (network output)

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

python
url = f"{host}{path}"
    if method == "POST" and files:
        h = {k: v for k, v in headers.items() if k != "Content-Type"}
        resp = requests.post(url, headers=h, files=files, stream=True, timeout=120)
    elif method == "POST":
        resp = requests.post(url, headers=headers, json=data, stream=True, timeout=120)
    else:

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% 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/main.py (reported line 494)May include surrounding context.

python
h = {k: v for k, v in headers.items() if k != "Content-Type"}
        resp = requests.post(url, headers=h, files=files, stream=True, timeout=120)
    elif method == "POST":
        resp = requests.post(url, headers=headers, json=data, stream=True, timeout=120)
    else:
        resp = requests.get(url, headers=headers, params=data, timeout=30)
        return resp.json().get("data") if resp.status_code == 200 else None

Static analysis

No suspicious patterns detected.