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<![CDATA[ ## Vulnerability Details **File Location**: `assets/backend/app.py:23-25, 159-175` **Vulnerability Type**: Unvalidated outbound API destination and sensitive-data disclosure **Risk Level**: High ### Vulnerable Code ```python 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" ``` ```python # Call StepFun API image_b64 = image_to_base64(upload_path) headers = { "Authorization": f"Bearer {STEPFUN_API_KEY}", "Content-Type": "application/json", } payload = { "model": "step-image-edit-2", "image": image_b64, "prompt": prompt, "response_format": "b64_json", } try: resp = requests.post(STEPFUN_EDIT_URL, json=payload, headers=headers, timeout=120) ``` ### Technical Analysis The backend obtains the outbound API base URL directly from the process environment and does not validate its scheme, hostname, port, or resolved IP address. It then sends both the uploaded image and the `STEPFUN_API_KEY` bearer credential to that destination. The Skill only documents two legitimate StepFun endpoint prefixes. Allowing an arbitrary destination exceeds the minimum network privileges required for the declared image-editing functionality. Base64 encoding itself is necessary for the documented StepFun JSON API and is not covert exfiltration. The security issue is that the encoded image and API credential can be sent to an unrestricted destination. Depending on `requests` redirect behavior, a malicious or compromised endpoint may also redirect the request. Sensitive authorization headers are normally removed on cross-host redirects, but redirects should still be disabled or explicitly validated because the image payload remains sensitive. ### Attack Path 1. An attacker gains the ability to modify the generated application's `.env`, deployment configuration, container environment, or process environment. 2. The ...[truncated 918 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Allowlist the exact documented StepFun hosts and HTTPS scheme. - Reject URLs containing user information, unexpected ports, fragments, or unsupported paths. - Resolve the hostname and reject loopback, private, link-local, multicast, and metadata-service addresses. - Disable redirects with `allow_redirects=False`, or validate every redirect destination before following it. - Construct the API URL from a fixed application-controlled host wherever possible. - Store the API key in a managed secret store and rotate it immediately if endpoint redirection is suspected. - Fail startup if the API key is absent rather than sending an empty bearer credential. - Log destination validation failures without logging the API key or image payload. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
assets/backend/app.py:198
Finding
Uploaded and Generated Images Are Persistently Exposed Without Authentication<![CDATA[ ## Vulnerability Details **File Location**: `assets/backend/app.py:18-21, 140-153, 184-205` **Vulnerability Type**: Insecure sensitive-file storage and unauthenticated access **Risk Level**: Medium ### Vulnerable Code ```python UPLOAD_DIR = os.path.join(os.path.dirname(__file__), "uploads") RESULT_DIR = os.path.join(os.path.dirname(__file__), "results") os.makedirs(UPLOAD_DIR, exist_ok=True) os.makedirs(RESULT_DIR, exist_ok=True) ``` ```python # Save uploaded image ext = os.path.splitext(image_file.filename)[1] or ".png" upload_filename = f"upload_{uuid.uuid4().hex[:8]}{ext}" upload_path = os.path.join(UPLOAD_DIR, upload_filename) image_file.save(upload_path) # Compress large images img = Image.open(upload_path) if img.mode in ("RGBA", "P"): img = img.convert("RGB") max_size = 2048 if max(img.size) > 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/<filename>") def serve_upload(filename): return send_from_directory(UPLOAD_DIR, filename) @app.route("/results/<filename>") 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
<![CDATA[ ## Remediation Suggestions - Require authentication and verify file ownership before serving either original or result images. - Use full cryptographically random identifiers rather than truncated UUID values. - Store images outside directly served directories. - Provide short-lived, signed download tokens tied to a specific file and user. - Delete original images as soon as processing no longer requires them. - Apply a documented, short retention period to generated results and enforce it with cleanup jobs. - Add restrictive `Cache-Control` headers appropriate for sensitive content. - Prevent sensitive URLs from entering application and reverse-proxy logs. - Use encrypted storage where retained images require persistence. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
assets/backend/app.py:127
Finding
Unbounded Image Upload and Processing Permit Resource-Exhaustion Attacks<![CDATA[ ## Vulnerability Details **File Location**: `assets/backend/app.py:127-153, 174-184` **Vulnerability Type**: Unrestricted upload size, decompression-bomb exposure, and unbounded response decoding **Risk Level**: Medium ### Vulnerable Code ```python @app.route("/api/edit", methods=["POST"]) def edit_image(): """图片编辑接口""" if "image" not in request.files: return jsonify({"error": "请上传图片"}), 400 image_file = request.files["image"] feature = request.form.get("feature", "restore") style = request.form.get("style", "oil") if feature not in FEATURE_PROMPTS: return jsonify({"error": f"不支持的功能: {feature}"}), 400 # Save uploaded image ext = os.path.splitext(image_file.filename)[1] or ".png" upload_filename = f"upload_{uuid.uuid4().hex[:8]}{ext}" upload_path = os.path.join(UPLOAD_DIR, upload_filename) image_file.save(upload_path) # Compress large images img = Image.open(upload_path) if img.mode in ("RGBA", "P"): img = img.convert("RGB") max_size = 2048 if max(img.size) > 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
<![CDATA[ ## Remediation Suggestions - Configure a strict Flask `MAX_CONTENT_LENGTH`. - Enforce limits at the reverse proxy and application layers. - Validate image signatures and allowlist required formats after upload. - Reject excessive dimensions and pixel counts before full processing where practical. - Treat Pillow decompression-bomb warnings as errors and set an appropriate `Image.MAX_IMAGE_PIXELS`. - Call `img.verify()` and then reopen the file before transformation. - Limit concurrent edits per user and IP and add request-rate controls. - Use bounded temporary storage and guaranteed cleanup through `try`/`finally`. - Apply upstream response-size limits before reading or decoding the response body. - Validate Base64 length and decoded image format before writing it. - Run image processing in isolated workers with CPU, memory, file-size, and execution-time limits. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
assets/backend/app.py:208
Finding
Flask Interactive Debug Mode Is Enabled by Default<![CDATA[ ## Vulnerability Details **File Location**: `assets/backend/app.py:208-209` **Vulnerability Type**: Unsafe development configuration **Risk Level**: Medium ### Vulnerable Code ```python if __name__ == "__main__": app.run(debug=True, port=5050) ``` ### Technical Analysis The generated application always enables Flask debug mode when started according to the Skill instructions. Debug mode exposes detailed exception pages containing source context, stack traces, local file paths, and application internals. Under unsafe network exposure conditions, access to the Werkzeug interactive debugger can have more severe consequences, potentially including arbitrary Python execution if its protection is bypassed or its debugger PIN becomes available. The current call does not explicitly bind to all interfaces, which reduces default exposure, but the accompanying Skill also describes frontend use with externally bound Vite, and generated applications are commonly placed behind proxies or modified for deployment. Debug mode should therefore never be the template default. Malformed image files can cause uncaught Pillow exceptions, making debug pages practically reachable. ### Attack Path 1. The generated Flask service is started with the provided command. 2. The service becomes network-accessible directly, through a proxy, container port publication, or a later host-binding change. 3. An attacker submits malformed image data that triggers an uncaught exception. 4. Flask returns a detailed debug exception page. 5. The attacker obtains internal implementation and path information. 6. If interactive debugger access is available or its protections are defeated, the attacker may execute Python in the application process. ### Impact Assessment At minimum, exploitation can disclose source details, internal paths, package versions, and runtime information. Under an exposed interactive-debugger scenario, impact can escalate to arbitrary code execution with the ...[truncated 139 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Change the default to `debug=False`. - Use an explicit development-only environment setting if debugging is required locally. - Ensure development mode is permitted only on loopback interfaces. - Deploy production instances through a production WSGI server such as Gunicorn or Waitress. - Add controlled exception handling for Pillow decoding, JSON parsing, response validation, and Base64 decoding. - Return generic errors to clients and send detailed diagnostics only to protected server logs. - Run the application as a dedicated, unprivileged operating-system account. ]]>

T08 · Insecure Dependencies

Note
Location
assets/frontend/package.json:11
Finding
Frontend Dependencies Are Not Reproducibly Locked<![CDATA[ ## Vulnerability Details **File Location**: `assets/frontend/package.json:11-19`; installation instruction at `SKILL.md:57-60` **Vulnerability Type**: Non-reproducible dependency resolution and supply-chain exposure **Risk Level**: Low ### Vulnerable Code ```json "dependencies": { "react": "^18.3.1", "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" } ``` The Skill instructs installation without a lockfile: ```bash cd backend && pip install -r requirements.txt cd frontend && npm install ``` ### Technical Analysis The project does not include an npm lockfile, while package versions use caret ranges. Consequently, two installations can resolve different direct or transitive dependency versions. This prevents deterministic review and allows newly published versions within the permitted ranges to enter the build without a corresponding source change. No malicious package, typosquatting package, or known vulnerable resolved version was identified from the reviewed files. The finding is an insecure supply-chain practice rather than evidence that the listed packages are malicious. ### Attack Path 1. A permitted direct or transitive package version is compromised or publishes a harmful release. 2. A user later follows the Skill instructions and runs `npm install`. 3. npm resolves the newly available version because no reviewed lockfile fixes the dependency graph. 4. Package lifecycle or build-time code executes with the installing user's privileges. 5. The compromised dependency can access source files, environment variables, build output, and other files available to that user. ### Impact Assessment A compromised dependency could execute code with the privileges of the user running `npm install` or the CI build account. The practical scope may include project files, build credentials, CI secrets, and deployable frontend artifacts ...[truncated 158 chars]
Remediation
<![CDATA[ ## Remediation Suggestions - Generate and commit a reviewed `package-lock.json`. - Use `npm ci` rather than `npm install` in documented and automated builds. - Pin dependency versions or adopt a controlled update policy. - Review lockfile changes before merging dependency updates. - Run dependency vulnerability and provenance checks in CI. - Use a trusted npm registry and enforce registry configuration in CI. - Minimize lifecycle-script execution where operationally feasible. - Rebuild lockfiles only in a controlled environment and periodically update dependencies after security review. ]]>
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
Content
}

    try:
        resp = requests.post(STEPFUN_EDIT_URL, json=payload, headers=headers, timeout=120)
        resp.raise_for_status()
        data = resp.json()
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.

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.

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.

Lp3

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.

Missing User Warnings

Medium
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.

External Transmission

Medium
Category
Data Exfiltration
Content
```
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.
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.

External Transmission

Medium
Category
Data Exfiltration
Content
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.

### 3. Install Dependencies
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.

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.

External Transmission

Medium
Category
Data Exfiltration
Content
### Endpoint

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

### Request Format
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.

External Transmission

Medium
Category
Data Exfiltration
Content
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 = {
Confidence
60% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Missing User Warnings

Medium
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.

External Transmission

Medium
Category
Data Exfiltration
Content
}

    try:
        resp = requests.post(STEPFUN_EDIT_URL, json=payload, headers=headers, timeout=120)
        resp.raise_for_status()
        data = resp.json()
Confidence
80% confidence
Finding
Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

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.

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.

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.

Natural-Language Policy Violations

Medium
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.

Missing User Warnings

Medium
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.

Natural-Language Policy Violations

Low
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.

Natural-Language Policy Violations

Low
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.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"preview": "vite preview"
  },
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

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.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  },
  "devDependencies": {
    "@types/react": "^18.3.12",
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

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.

Unpinned Dependencies

Low
Category
Supply Chain
Content
"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"
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Unpinned Dependencies

Low
Category
Supply Chain
Content
},
  "devDependencies": {
    "@types/react": "^18.3.12",
    "@types/react-dom": "^18.3.1",
    "@vitejs/plugin-react": "^4.3.4",
    "vite": "^6.0.0"
  }
Confidence
40% confidence
Finding
Dependencies lack version pinning, allowing potential malicious package updates. Consider pinning versions.

Static analysis

No suspicious patterns detected.