Back to skill

Security audit

Browser Session Manager

Security checks for vulnerabilities and agentic risk

Overview

This skill is a coherent Jimeng automation guide, but it handles raw login sessions and can submit account actions with weak scoping and safeguards.

Install only if you are comfortable storing and replaying Jimeng browser session data locally. Treat the JSON session file like a password, keep it out of shared /tmp paths and source control, run the browser in a contained environment, and review every generation request before allowing it to spend credits or upload private prompts/images.

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

T09 · Insecure Skill Coding Practices

Error
Location
scripts/browser-session-manager.js:94
Finding
Arbitrary-Origin Injection of Sensitive Browser Storage<![CDATA[ ## Vulnerability Details **File Location**: `scripts/browser-session-manager.js`, lines 94-123 and 194-205 **Vulnerability Type**: Sensitive authentication-state exposure through missing origin validation **Risk Level**: High ### Vulnerable Code ```javascript // Navigate to target URL console.log(`🔗 访问目标页面: ${url}`); await page.goto(url, { waitUntil: 'networkidle', timeout: 60000 }); // Apply localStorage if present if (sessionData.localStorage && Object.keys(sessionData.localStorage).length > 0) { console.log(`💾 设置 ${Object.keys(sessionData.localStorage).length} 个 localStorage 项...`); await page.evaluate((data) => { for (const [key, value] of Object.entries(data)) { try { localStorage.setItem(key, value); } catch (e) { console.error(`设置 localStorage[${key}] 失败:`, e); } } }, sessionData.localStorage); } // Apply sessionStorage if present if (sessionData.sessionStorage && Object.keys(sessionData.sessionStorage).length > 0) { console.log(`📦 设置 ${Object.keys(sessionData.sessionStorage).length} 个 sessionStorage 项...`); await page.evaluate((data) => { for (const [key, value] of Object.entries(data)) { try { sessionStorage.setItem(key, value); } catch (e) { console.error(`设置 sessionStorage[${key}] 失败:`, e); } } }, sessionData.sessionStorage); } ``` The target is taken directly from the command line: ```javascript const [url, sessionJsonPath, screenshotPath] = args; applySessionData(url, sessionJsonPath, { screenshotPath }) ``` ### Technical Analysis The session manager accepts an unrestricted target URL, navigates to that URL, and writes every supplied `localStorage` and `sessionStorage` value into the active origin. Web Storage is scoped to the currently loaded origin. Consequently, if the caller supplies an attacker-controlled URL, sensitive values from a Jimeng session export are not restored to Jimeng. Instead, they are inserted into the attacker' ...[truncated 1948 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Parse and validate the destination before launching the browser: - Require `https:`. - Allow only `jimeng.jianying.com`, or an explicitly documented set of trusted subdomains. - Reject embedded credentials, nonstandard schemes, and unexpected ports. 2. Compare the destination against trusted metadata from the session export: ```javascript const target = new URL(url); const exported = new URL(sessionData.url); if (target.protocol !== 'https:' || target.origin !== exported.origin) { throw new Error('Session data cannot be restored to a different origin'); } ``` 3. Treat cross-origin restoration as prohibited by default. If it is genuinely required, require a separate explicit option and interactive confirmation. 4. Use an allowlist for storage keys instead of restoring the entire exported object. 5. Avoid restoring authentication tokens unless they are essential to the requested operation. 6. Validate the final origin after navigation and redirects before writing storage: ```javascript await page.goto(url, options); if (new URL(page.url()).origin !== expectedOrigin) { throw new Error('Navigation redirected outside the trusted origin'); } ``` 7. Clear the browser context and abort immediately if an origin mismatch is detected. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/browser-session-manager.js:21
Finding
Chromium Sandbox Disabled While Processing Remote Web Content<![CDATA[ ## Vulnerability Details **File Location**: `scripts/browser-session-manager.js`, lines 21-25; `jimeng-final.js`, lines 7-11; `SKILL.md`, lines 107-111 **Vulnerability Type**: Unsafe browser security configuration **Risk Level**: Medium ### Vulnerable Code From `scripts/browser-session-manager.js`: ```javascript console.log('🌐 启动浏览器...'); const browser = await chromium.launch({ headless, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); ``` From `jimeng-final.js`: ```javascript console.log('🌐 启动浏览器...'); const browser = await chromium.launch({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }); ``` The documented implementation also recommends disabling the sandbox: ```javascript const browser = await chromium.launch({ headless: true, args: ['--no-sandbox'] }); ``` ### Technical Analysis The `--no-sandbox` and `--disable-setuid-sandbox` arguments disable important Chromium isolation boundaries. The scripts then process remote, dynamically controlled website content in an authenticated browser context. A browser sandbox is a defense-in-depth control designed to limit the host-level consequences of a renderer or browser-engine compromise. Disabling it does not by itself create arbitrary code execution, but it materially increases the impact of a malicious page or an exploitable Chromium vulnerability. This risk is amplified in the reusable manager because its target URL is supplied by the caller and is not restricted to a trusted origin. ### Attack Path 1. A user runs the automation against a compromised, malicious, or attacker-selected website. 2. The website serves content that exploits a vulnerability in the installed Chromium version. 3. The exploit gains code execution in a browser process. 4. Because Chromium sandbox protections were disabled, fewer isolation boundaries protect the host. 5. The attacker accesses resources available to the Node.js process, subject to the operating-system privileg ...[truncated 710 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Remove both sandbox-disabling arguments from the default launch configuration: ```javascript const browser = await chromium.launch({ headless }); ``` 2. If a specific deployment environment cannot support Chromium sandboxing: - Make sandbox disabling an explicit opt-in setting. - Display a clear security warning. - Run the process as a dedicated non-root user. - Use a locked-down container or virtual machine. - Mount only the files required for the operation. - Use a read-only root filesystem where practical. - Drop Linux capabilities and enable seccomp/AppArmor/SELinux controls. - Restrict outbound network access to approved Jimeng endpoints. 3. Keep Playwright and its bundled Chromium version patched. 4. Restrict the reusable session manager to trusted HTTPS origins. 5. Do not expose host secrets or broad filesystem mounts to the browser process. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
jimeng-final.js:5
Finding
Predictable Shared Temporary Paths Used for Session Data and Screenshots<![CDATA[ ## Vulnerability Details **File Location**: `jimeng-final.js`, line 5 and lines 69, 97, 134, 151, 179, and 185; `scripts/browser-session-manager.js`, lines 144-147; `examples/use-jimeng-session.js`, lines 23-28 **Vulnerability Type**: Unsafe temporary-file handling **Risk Level**: Low ### Vulnerable Code From `jimeng-final.js`: ```javascript const sessionData = JSON.parse(fs.readFileSync('/tmp/jimeng-session.json', 'utf8')); ``` The same script writes screenshots to predictable global names: ```javascript await page.screenshot({ path: '/tmp/jimeng_final_step0.png' }); await page.screenshot({ path: '/tmp/jimeng_final_step1.png' }); await page.screenshot({ path: '/tmp/jimeng_final_step3.png' }); await page.screenshot({ path: '/tmp/jimeng_final_step4.png' }); await page.screenshot({ path: '/tmp/jimeng_final_step6_submit.png', fullPage: true }); await page.screenshot({ path: '/tmp/jimeng_final_step6_after5s.png', fullPage: true }); ``` From `scripts/browser-session-manager.js`: ```javascript case 'screenshot': const ssPath = action.path || '/tmp/screenshot.png'; await page.screenshot({ path: ssPath, fullPage: action.fullPage || false }); console.log(`📸 截图已保存: ${ssPath}`); break; ``` From `examples/use-jimeng-session.js`: ```javascript sessionJsonPath: process.argv[2] || '/tmp/jimeng-session.json', options: { headless: true, screenshotPath: '/tmp/jimeng-result.png', ``` ### Technical Analysis The project uses fixed, globally predictable names under `/tmp` for authentication input and authenticated screenshots. It does not create a private per-run directory, validate file ownership, reject symbolic links, or explicitly enforce restrictive permissions. On a shared system, another local user or process may be able to prepare or replace predictable path entries before execution. Exact exploitability depends on operating-system protections, directory permissions, Playwright's file-opening behavior, and the privileges of the attacking pr ...[truncated 1330 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a private per-run temporary directory: ```javascript const os = require('os'); const path = require('path'); const fs = require('fs'); const runDir = fs.mkdtempSync(path.join(os.tmpdir(), 'jimeng-')); fs.chmodSync(runDir, 0o700); ``` 2. Store screenshots only inside that private directory and generate unique filenames. 3. Require the session path to be supplied explicitly instead of defaulting to a shared fixed name. 4. Before reading session data: - Use `lstat` to reject symbolic links. - Confirm the path is a regular file. - Validate ownership where supported. - Reject files accessible by other users. - Enforce a reasonable maximum size. 5. Create sensitive files with mode `0600`. 6. Delete session-derived artifacts when they are no longer required. 7. Avoid placing authentication exports in shared temporary storage. Prefer a private user configuration directory or a secrets-management facility. ]]>

T09 · Insecure Skill Coding Practices

Note
Location
jimeng-final.js:155
Finding
Ambiguous UI Targeting Can Trigger Unintended Credit-Consuming Actions<![CDATA[ ## Vulnerability Details **File Location**: `jimeng-final.js`, lines 155-174 **Vulnerability Type**: Unsafe browser-action targeting for a consequential operation **Risk Level**: Low ### Vulnerable Code ```javascript // 步骤 5: 点击正确的提交按钮(圆形黑色带箭头,旁边有60积分显示) console.log('📸 步骤 5: 点击提交按钮...'); try { // 查找圆形提交按钮 - 根据描述:黑色圆形,白色上箭头,旁边有"60" // 通常是 input 区域右侧的圆形按钮 // 方法1: 查找包含箭头的圆形按钮 const submitBtn = await page.locator('button[class*="submit"], button[class*="send"], [class*="circle"]:has(svg), button:has([class*="arrow"])').last(); await submitBtn.click({ timeout: 10000 }); console.log('✅ 已点击提交按钮'); } catch (e) { console.log('⚠️ 方法1失败,尝试坐标点击:', e.message); // 方法2: 坐标点击(根据截图,按钮在右下角,积分"60"旁边) try { // 先找到包含 "60" 的元素,然后点击它旁边的圆形按钮 const creditText = await page.getByText('60').first(); const box = await creditText.boundingBox(); if (box) { // 点击"60"右侧的圆形按钮(大约偏移50像素) await page.mouse.click(box.x + box.width + 30, box.y + box.height/2); console.log('✅ 已通过坐标点击提交按钮'); } ``` ### Technical Analysis The script submits a generation request that the surrounding comments identify as costing 60 credits. It locates the submission control using a broad union of class-fragment and structural selectors, chooses the last matching element, and falls back to clicking a coordinate relative to the first visible text value `60`. These targeting methods do not establish that the selected element is the intended generation button. Normal UI changes, localization, responsive layout changes, overlays, advertisements, or newly inserted matching elements can cause a different control to be activated. The code also does not verify the selected model, duration, prompt, expected credit cost, or destination state immediately before the consequential click. ### Attack Path 1. Jimeng changes its page layout, or a compromised page inserts another matching button or `60` text element. 2. The broad selector resolves to an unintended e ...[truncated 826 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Use a stable accessible role and exact accessible name, or a service-provided test identifier: ```javascript const submitBtn = page.getByRole('button', { name: 'Generate', exact: true }); ``` 2. Remove coordinate-based clicking for consequential operations. 3. Before submission, assert: - The current origin and page route. - The selected model. - The requested duration. - The presence and exact content of the prompt. - Uploaded image identities. - The displayed credit cost. - The button's visible and enabled state. 4. Require explicit user confirmation before spending credits, particularly when the cost differs from an expected value. 5. After clicking, verify a specific success state or request identifier rather than relying only on screenshots or elapsed time. 6. Fail closed when selectors do not resolve uniquely: ```javascript if (await submitBtn.count() !== 1) { throw new Error('Unable to identify the generation button uniquely'); } ``` 7. Add idempotency or duplicate-submission protection where the service workflow permits it. ]]>
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 (13)

Context-Inappropriate Capability

Medium
Confidence
94% confidence
Finding
The document explicitly instructs exporting and reusing authenticated cookies and localStorage, then injecting them into a Playwright browser context to assume an existing logged-in session. That enables account/session impersonation and bypasses normal authentication controls if the session file is mishandled, reused without consent, or applied to another user's credentials.

Missing User Warnings

Medium
Confidence
96% confidence
Finding
The skill tells users to export cookies and localStorage and save them to JSON, but does not warn that these artifacts are effectively credentials and may grant direct account access. This omission materially increases the chance of credential leakage, unsafe sharing, accidental commits, or reuse outside the intended environment.

Context-Inappropriate Capability

Medium
Confidence
98% confidence
Finding
The script reads cookies and localStorage from /tmp/jimeng-session.json and injects them into a Playwright browser context, allowing it to impersonate an authenticated user without any visible consent, validation, or scope restriction. In an unknown-purpose skill, this enables account misuse and unauthorized actions against the target service using stolen or preexisting session material.

Missing User Warnings

Medium
Confidence
99% confidence
Finding
Loading cookies and localStorage from disk and silently injecting them into the browser handles sensitive session credentials without notice, auditability, or access controls. This can expose or misuse authentication artifacts, especially in shared environments where /tmp data may be stale, cross-user, or attacker-controlled.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The automation navigates to an external site, populates content, changes model and duration settings, and attempts to press the submit button, causing remote actions on behalf of the logged-in user. Because the skill has no trustworthy stated business purpose or user confirmation step, it can spend credits, generate content, or trigger other account-linked operations without informed consent.

Missing User Warnings

Medium
Confidence
95% confidence
Finding
The script fills a prompt and submits it to a third-party website without any user-facing disclosure that the text will be transmitted externally. This creates a privacy and data-handling risk because users may unknowingly send sensitive or proprietary content to a remote service.

Context-Inappropriate Capability

Medium
Confidence
93% confidence
Finding
The document identifies specific authentication cookies and tokens and explains using exported browser session data to access authenticated Jimeng pages. This enables account/session reuse and lowers the barrier to unauthorized access if the session export is stolen, shared, or misused.

Context-Inappropriate Capability

Medium
Confidence
96% confidence
Finding
The troubleshooting guidance explicitly suggests using a different IP or proxy when rate limited, which can facilitate evasion of service anti-abuse controls. In a session-automation guide, this goes beyond benign debugging and provides operational advice for bypassing provider restrictions.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
This code contains multiple user-visible console messages and usage instructions exclusively in Chinese, including startup, progress, error, and help text. Because the skill does not provide any language selection or indicate that it is intentionally region-specific, it violates the language/locale policy for natural-language content.

Context-Inappropriate Capability

Low
Confidence
81% confidence
Finding
The guide's core purpose is browser-driven submission to an AI video site, but it also prescribes use of ImageMagick's `convert` command as part of the workflow. Spawning external tooling is a materially broader capability than interacting with the target website and is not inherently required for browser automation itself.

Missing User Warnings

Low
Confidence
84% confidence
Finding
The automation uploads local image files and submits prompt text to a third-party remote service without clearly warning users that local content will be transmitted off-host. In workflows involving private, regulated, or proprietary data, this can cause unintended data disclosure.

Natural-Language Policy Violations

Low
Confidence
6% confidence
Finding
After review, there is no clear natural-language policy violation because the file does not require a specific language or locale for user interaction. Mentions of Jimeng and Chinese domain names are contextual rather than mandatory language restrictions.

Intent-Code Divergence

Low
Confidence
97% confidence
Finding
The usage string says the command expects `<url> <session-json-path> [screenshot-path]`, but both example commands place `/session.json` inside the URL position instead of as the second argument. This is an active contradiction in the inline documentation because following the examples would not match how the code parses `const [url, sessionJsonPath, screenshotPath] = args`.

Static analysis

No suspicious patterns detected.