T09 · Insecure Skill Coding Practices
- Location
poq.js:7- Finding
Forgeable and Replayable Proof-of-Quality Result
- Content
View full analysis
10 && skillContent.includes('PoW') ? 98 : 80; return quality; } function powQuality(score, difficulty = 4) { let nonce = 0; while (true) { const hashInput = score + nonce; const hash = crypto.createHash('sha256').update(hashInput).digest('hex'); if (hash.startsWith('0'.repeat(difficulty))) return { hash, nonce, score }; nonce++; } } ``` ### Technical Analysis The benchmark does not execute a test suite or measure the claimed speed, accuracy, or security properties. It assigns a score of `98` solely when the input contains more than ten lines and includes the literal string `PoW`; all other inputs receive `80`. The generated proof hashes only the concatenated score and nonce: ```js const hashInput = score + nonce; ``` It does not bind the proof to the evaluated file contents, a cryptographic digest of the skill package, the benchmark evidence, the threshold, or the evaluator version. Therefore, all inputs receiving the same score share an identical proof search space. A previously generated proof can be reused for a different skill or after the evaluated skill has been modified. This behavior conflicts with the verification and security-benchmarking claims in `SKILL.md`, because the implementation neither performs the documented security evaluation nor supplies enough data to verify that a proof belongs to a specific artifact. ### Attack Path 1. An attacker creates an unsafe or low-quality skill containing more than ten lines. 2. The attacker inserts the literal text `PoW` anywhere in the input. 3. The attacker invokes `node poq.js 95`. 4. The superficial benchmark assigns the skill a score of `98`. 5. The script searc ...[truncated 962 chars]- Remediation
View remediation
