Back to skill

Security audit

ImageCraft Editor

Security checks for vulnerabilities and agentic risk

Overview

The skill matches an AI image editor, but its template can expose private photos and API keys unless reviewed and hardened.

Install only after review or hardening. At minimum, allowlist the StepFun API hosts, keep the API key server-side, disable Flask debug mode, add upload size and rate limits, authenticate or expire image URLs, delete originals when no longer needed, disclose third-party image processing to users, and update or lock dependencies.

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

T09 · Insecure Skill Coding Practices

Error
Location
assets/backend/app.py:23
Finding

Unrestricted API Destination Can Disclose Uploaded Images and API Credentials

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
assets/backend/app.py:198
Finding

Uploaded and Generated Images Are Persistently Exposed Without Authentication

Content
View full analysis
max_size: img.thumbnail((max_size, max_size), Image.LANCZOS) img.save(upload_path, "PNG") ``` ```python result_filename = save_base64_image(result_b64, RESULT_DIR) return jsonify({ "success": True, "original": f"/uploads/{upload_filename}", "result": f"/results/{result_filename}", "feature": feature, "prompt": prompt, }) ``` ```python @app.route("/uploads/") def serve_upload(filename): return send_from_directory(UPLOAD_DIR, filename) @app.route("/results/") def serve_result(filename): return send_from_directory(RESULT_DIR, filename) ``` ### Technical Analysis Original and generated images are written to persistent directories and served through routes that require no authentication or authorization. The application does not associate files with a user, impose expiration, remove files after download, or define a retention policy. Filenames contain only the first eight hexadecimal characters of a UUID. Although opportunistic guessing is not trivial, this is substantially weaker than using the complete random identifier. URLs can also be exposed through browser history, logs, referrer data, ...[truncated 1198 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
assets/backend/app.py:127
Finding

Unbounded Image Upload and Processing Permit Resource-Exhaustion Attacks

Content
View full analysis
max_size: img.thumbnail((max_size, max_size), Image.LANCZOS) img.save(upload_path, "PNG") ``` ```python try: resp = requests.post(STEPFUN_EDIT_URL, json=payload, headers=headers, timeout=120) resp.raise_for_status() data = resp.json() # Save result result_b64 = data.get("data", [{}])[0].get("b64_json", "") if not result_b64: return jsonify({"error": "API 返回数据异常", "raw": data}), 500 result_filename = save_base64_image(result_b64, RESULT_DIR) ``` ```python def save_base64_image(b64_data, output_dir, prefix="result"): img_data = base64.b64decode(b64_data) filename = f"{prefix}_{uuid.uuid4().hex[:8]}.png" filepath = os.path.join(output_dir, filename) with open(filepath, "wb") as f: f.write(img_data) return filename ``` ### Technical Analysis The Flask application defines no `MAX_CONTENT_LENGTH`, server-side file-size limit, rat ...[truncated 1669 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
assets/backend/app.py:208
Finding

Flask Interactive Debug Mode Is Enabled by Default

Content
View full analysis
Remediation
View remediation

T08 · Insecure Dependencies

Note
Location
assets/frontend/package.json:11
Finding

Frontend Dependencies Are Not Reproducibly Locked

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (29)

Tainted flow: 'STEPFUN_EDIT_URL' from os.getenv (line 25, credential/environment) → requests.post (network output)

Critical
Category
Data Flow
Confidence
94% confidence
Finding

The endpoint used for the outbound request is derived from an environment variable without validation or allowlisting. If an attacker can influence deployment configuration, they can redirect uploaded images and the bearer token to an arbitrary host, creating a server-side exfiltration/SSRF-style risk beyond the intended StepFun service.

Content

Scanner excerpt · assets/backend/app.py (reported line 175)May include surrounding context.

python
}

    try:
        resp = requests.post(STEPFUN_EDIT_URL, json=payload, headers=headers, timeout=120)
        resp.raise_for_status()
        data = resp.json()

Known Vulnerable Dependency: flask-cors==5.0.1 — 6 advisory(ies): CVE-2024-6866 (Flask-CORS vulnerable to Improper Handling of Case Sensitivity); CVE-2024-6839 (Flask-CORS improper regex path matching vulnerability); CVE-2024-6844 (Flask-CORS allows for inconsistent CORS matching) +3 more

High
Category
Supply Chain
Confidence
98% confidence
Finding

Flask-CORS is pinned to a version with multiple known CORS-handling flaws, including case-sensitivity, regex path matching, and inconsistent origin matching issues. For a React frontend talking to a Flask backend, CORS policy is security-critical; bypasses or inconsistent matching can let unintended origins access authenticated API responses or perform cross-origin interactions.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: pillow==11.1.0 — 16 advisory(ies): CVE-2026-55379 (Pillow `BdfFontFile`: `Image.new()` called without `_decompression_bomb_check()`); CVE-2026-55798 (Pillow: WindowsViewer.get_command() OS command injection via unescaped shell pat); CVE-2026-54060 (Pillow: `FontFile.compile()`: `Image.new()` called without `_decompression_bomb_) +13 more

High
Category
Supply Chain
Confidence
98% confidence
Finding

Pillow is pinned to a version with numerous advisories affecting image parsing and related functionality. Because this skill is specifically for AI-powered image editing and will likely process untrusted user-uploaded images, any image library vulnerability is especially dangerous and could lead to denial of service, memory issues, or worse depending on the specific code paths reached.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
94% confidence
Finding

The skill describes capabilities that require environment-variable access and outbound network access, but it does not declare any tool scope or permissions boundaries. This creates a governance gap where an agent may use broader capabilities than the user expects, increasing the chance of unauthorized secret access or unintended external requests during skill execution.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The skill instructs users to upload images for AI editing but does not clearly warn that those images are transmitted to StepFun, a third-party external API, for processing. This can expose sensitive personal or confidential images without informed consent, especially in a photo-editing context where portraits and private media are common.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

This section directs configuration of an external API endpoint and API key, confirming that image data and credentials will be used for outbound transmission to a third party. In this skill context, external transmission is expected, but it remains security-relevant because sensitive user images may leave the local environment and API keys must be protected.

Content

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

text
STEPFUN_API_KEY=<user's actual api key>
STEPFUN_BASE_URL=https://api.stepfun.com/v1

If using Step Plan subscription, change base URL to https://api.stepfun.com/step_plan/v1 instead.

External Transmission

Medium
Category
Data Exfiltration
Confidence
90% confidence
Finding

The alternate Step Plan base URL is another explicit instruction to send requests to an external service, so the same data-exposure and third-party trust risks apply. Although this is part of the intended architecture, users still need clear notice and controls because uploaded content may contain sensitive imagery.

Content

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

STEPFUN_BASE_URL=https://api.stepfun.com/v1

text

If using Step Plan subscription, change base URL to `https://api.stepfun.com/step_plan/v1` instead.

### 3. Install Dependencies

Rp1

Medium
Category
MCP Rug Pull
Confidence
82% confidence
Finding

Using npx vite without pinning a version allows resolution of whatever package version is current at execution time, which weakens supply-chain integrity and reproducibility. If a malicious or compromised upstream package version is served, the developer could install and execute untrusted code.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
97% confidence
Finding

The documented POST https://api.stepfun.com/v1/images/edit endpoint confirms direct external transmission of user-provided image content to a third-party processor. In an image-editing skill, this is functionally necessary, but it is still a real security/privacy concern because personal photos, metadata-bearing images, or confidential media could be exposed outside the user's system.

Content

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

Endpoint

text
POST https://api.stepfun.com/v1/images/edit

Request Format

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 · assets/backend/app.py (reported line 24)May include surrounding context.

python
os.makedirs(RESULT_DIR, exist_ok=True)

STEPFUN_API_KEY = os.getenv("STEPFUN_API_KEY", "")
STEPFUN_BASE_URL = os.getenv("STEPFUN_BASE_URL", "https://api.stepfun.com/v1")
STEPFUN_EDIT_URL = f"{STEPFUN_BASE_URL}/images/edit"

FEATURE_PROMPTS = {

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This code sends user-uploaded images to an external third-party API for processing, but there is no visible consent, disclosure, or privacy gating in the backend flow. For photo-editing applications, uploads often contain sensitive personal data, so undisclosed transmission can create privacy, compliance, and trust issues even if the transmission is functionally required.

Content

No source excerpt is available for this finding.

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 · assets/backend/app.py (reported line 175)May include surrounding context.

python
}

    try:
        resp = requests.post(STEPFUN_EDIT_URL, json=payload, headers=headers, timeout=120)
        resp.raise_for_status()
        data = resp.json()

Known Vulnerable Dependency: flask==3.1.0 — 4 advisory(ies): CVE-2025-47278 (Flask uses fallback key instead of current signing key); CVE-2026-27205 (Flask session does not add `Vary: Cookie` header when accessed in some ways); CVE-2025-47278 (Flask uses fallback key instead of current signing key) +1 more

Medium
Category
Supply Chain
Confidence
95% confidence
Finding

The requirements file pins Flask to a version identified by the scanner as having multiple known security advisories, including session/signing and caching-related issues. In a web application backend for an image editing service, Flask is directly exposed to user traffic, so shipping a known vulnerable framework version increases the chance of exploitable session or response-handling weaknesses.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: requests==2.32.3 — 4 advisory(ies): CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs); CVE-2026-25645 (Requests has Insecure Temp File Reuse in its extract_zipped_paths() utility func); CVE-2024-47081 (Requests vulnerable to .netrc credentials leak via malicious URLs) +1 more

Medium
Category
Supply Chain
Confidence
91% confidence
Finding

Requests is pinned to a version with known advisories, including a .netrc credential leak scenario and other unsafe behaviors in edge-case utilities. This skill integrates with external APIs and may fetch remote resources, so using a vulnerable HTTP client can expose credentials or create unsafe file/network handling paths if attacker-controlled URLs are processed.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: python-dotenv==1.0.1 — 2 advisory(ies): CVE-2026-28684 (python-dotenv: Symlink following in set_key allows arbitrary file overwrite via ); CVE-2026-28684 (python-dotenv reads key-value pairs from a .env file and can set them as environ)

Medium
Category
Supply Chain
Confidence
87% confidence
Finding

python-dotenv is pinned to a version with a known arbitrary file overwrite/symlink-following issue in set_key-related behavior. While .env handling is often limited to development or deployment workflows, if any administrative or automated runtime path modifies environment files, this dependency could be abused for filesystem impact.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The HTML document declares lang="zh-CN", which fixes the interface locale to Simplified Chinese. In this file there is no indication of user opt-in, locale selection, or a documented region-specific reason, so this appears to violate the language/locale policy requirement.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code sends the user-selected image via a POST request to /api/edit, which is a network operation involving user data. The UI shows upload and processing controls, but there is no visible notice, confirmation, or inline disclosure near the action indicating that the image will be sent to a backend service.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
89% confidence
Finding

This line states that all prompts must be in English for best results, which imposes a language constraint in the skill guidance. The file does not present this as an option, ask for user preference, or document a policy justification for forcing English.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
83% confidence
Finding

User-facing strings and descriptions in this file are presented in Chinese only, with no visible option to choose another language or locale. That can violate language/locale policy when a skill imposes a single language experience without explicit user choice or documented regional justification.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · assets/frontend/package.json (reported line 12)May include surrounding context.

json
"preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {

Unverifiable Dependency: react has 2 known advisory(ies) (CVE-2013-7035 (Cross-Site Scripting in react); GHSA-hg79-j56m-fxgv (Cross-Site Scripting in react)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · assets/frontend/package.json (reported line 13)May include surrounding context.

json
},
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@types/react": "^18.3.12",

Unverifiable Dependency: react-dom has 1 known advisory(ies) (CVE-2018-6341 (Cross-Site Scripting in react-dom)), but the manifest does not pin a version, so it is unknown whether the installed release is affected

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependency has known vulnerabilities (CVEs). Using packages with unpatched security flaws exposes the environment to known exploits.

Content

No source excerpt is available for this finding.

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · assets/frontend/package.json (reported line 16)May include surrounding context.

json
"react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@types/react": "^18.3.12",
    "@types/react-dom": "^18.3.1",
    "@vitejs/plugin-react": "^4.3.4",
    "vite": "^6.0.0"

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
40% confidence
Finding

Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Content

Scanner excerpt · assets/frontend/package.json (reported line 17)May include surrounding context.

json
},
  "devDependencies": {
    "@types/react": "^18.3.12",
    "@types/react-dom": "^18.3.1",
    "@vitejs/plugin-react": "^4.3.4",
    "vite": "^6.0.0"
  }