Back to skill

Security audit

Niftyagents

Security checks for vulnerabilities and agentic risk

Overview

This skill matches its stated SVG signing purpose, but it needs Review because its ownership-conflict guidance, secret-key storage description, and optional verifier server controls can mislead or expose users.

Use this only for experiments or low-value provenance unless you add an authoritative registry, marketplace log, or consensus layer for transfer ordering. Do not rely on the longest chain or latest timestamp to resolve ownership conflicts. Treat all generated secret keys as real credentials, avoid the simulation vault pattern for production, bind the verifier to localhost unless intentionally exposed, add authentication and rate limits, and update or pin dependencies before deployment.

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

other

Error
Location
SKILL.md:88
Finding

Attacker-Controlled Fork Resolution Can Misassign Asset Ownership

Content
View full analysis
{ const audit = await verifySVG(svg); if (!audit.isValid) throw new Error('Cannot transfer invalid SVG'); if (audit.currentOwner !== fromIdentity.did) { throw new Error(`Signer ${fromIdentity.did} is not the current owner (${audit.currentOwner})`); } const manifest = audit.metadata; const timestamp = new Date().toISOString(); const transferPayload = `${manifest.hash}:${toDID}:${timestamp}`; const signature = nacl.sign.detached(decodeUTF8(transferPayload), fromIdentity.secretKey); manifest.transfers.push({ to: toDID, timestamp, signature: toBase64(signature) }); const newManifestBase64 = base64.fromByteArray(decodeUTF8(JSON.stringify(manifest))); return svg.replace(/nasp:(.*?)<\/metadata>/, `nasp:${newManifestBase64}`); } ``` ### Technical Analysis The signature chain proves that a particular sequence of transfers was authorized, but it cannot establish that the sequence is the unique or authoritative history. A current owner can preserve an old valid copy and create multiple independently valid transfers from that state. The documented resolution policy does not safely solve this problem: - Chain length is attacker-controlled because an owner can transfer an asset through identities they control. - Timestamps are generated from the signer's local system clock. - Verification does ...[truncated 1616 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
simulation/vault.ts:5
Finding

Secret Signing Keys Are Stored as Unencrypted Base64 Data

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
server.ts:5
Finding

Unauthenticated SVG Verification Endpoint Is Vulnerable to Resource Exhaustion

Content
View full analysis
{ try { const svg = req.body; if (!svg || svg.trim().length === 0) { return res.status(400).json({ error: 'Missing SVG body' }); } if (!svg.includes('[\s\S]*?<\/metadata>\s*/g, ''); const canonical = await canonicalizeSVG(cleanSVG); const hash = computeHash(canonical); // Verify Transfer Chain let currentOwner = manifest.creator; const chain = [manifest.creator]; for (const transfer of manifest.transfers) { const ownerPubKey = fromBase64(currentOwner.replace(DID_PREFIX, '')); const transferPayload = `${hash}:${transfer.to}:${transfer.timestamp}`; const isValidTransfer = nacl.sign.detached.verify( decodeUTF8(transferPayload), fromBase64(transfer.signature), ownerPubKey ); if (!isValidTransfer) { return { isValid: false, creator: manifest.creator, currentOwner, chain, metadata: manifest }; } currentOwner = transfer.to; chain.push(currentOwner); } `` ...[truncated 1734 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
index.ts:91
Finding

Caller-Controlled Metadata Can Override Cryptographic Manifest Fields

Content
View full analysis
{ // Remove existing metadata for hashing const cleanSVG = svg.replace(/\s*[\s\S]*?<\/metadata>\s*/g, ''); const canonical = await canonicalizeSVG(cleanSVG); const hash = computeHash(canonical); const signature = nacl.sign.detached(decodeUTF8(hash), identity.secretKey); const manifest = { version: "1.0", creator: identity.did, hash: hash, signature: toBase64(signature), transfers: [], ...extraMetadata }; const manifestBase64 = base64.fromByteArray(decodeUTF8(JSON.stringify(manifest))); ``` ### Technical Analysis JavaScript object-spread properties applied later overwrite earlier properties with the same name. Because `extraMetadata` is spread after the security-critical manifest fields, a caller can replace: - `version` - `creator` - `hash` - `signature` - `transfers` The API presents `extraMetadata` as optional custom metadata, but it is not isolated from protocol state and is typed as `any`. If a host application passes partially attacker-controlled metadata, the attacker can silently alter the signed artifact's security fields. Replacing these fields will generally cause verification failure, resulting in artifact corruption or denial of service. Supplying fabricated transfer structures can also create misleading output or trigger expensive processing and malformed-data exceptions. ### Attack Path 1. An application accepts custom asset metadata from a user. 2. The application passes that object directly to `signSVG()` as `extraMetadata`. 3. The attacker includes reserved keys such as `hash`, `creator`, `signature`, or `transfers`. 4. The object spread ...[truncated 664 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Note
Location
index.ts:43
Finding

Nonstandard did:key Encoding Breaks Identity Interoperability

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (29)

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

The documented purpose is a local cryptographic protocol, but the code reportedly exposes undeclared network service endpoints such as /verify and /health. Hidden or undocumented service behavior expands the attack surface, can cause the skill to accept remote input unexpectedly, and prevents operators from making informed trust and deployment decisions.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The documented purpose is a local cryptographic protocol, but the code reportedly exposes undeclared network service endpoints such as /verify and /health. Hidden or undocumented service behavior expands the attack surface, can cause the skill to accept remote input unexpectedly, and prevents operators from making informed trust and deployment decisions.

Content

No source excerpt is available for this finding.

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
files: ["index.ts", "server.ts", "package.json", "tsconfig.json"]

Known Vulnerable Dependency: path-to-regexp==8.3.0 — 2 advisory(ies): CVE-2026-4923 (path-to-regexp vulnerable to Regular Expression Denial of Service via multiple w); CVE-2026-4926 (path-to-regexp vulnerable to Denial of Service via sequential optional groups)

High
Category
Supply Chain
Confidence
90% confidence
Finding

path-to-regexp 8.3.0 is flagged for ReDoS/DoS issues, and it is used by the router/Express stack to process route patterns. If attacker-controlled paths can trigger pathological matching, a network-facing service can suffer CPU exhaustion and request denial, making this materially relevant in the apparent Express context.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: svgo==4.0.1 — 3 advisory(ies): CVE-2026-73650 (SVGO removeScripts plugin leaves some executable scripts intact); CVE-2026-84369 (SVGO: removeScripts incompletely sanitizes executable HTML in SVG foreignObject ); CVE-2026-84370 (SVGO: removeScripts allows executable links through namespace and control-charac)

High
Category
Supply Chain
Confidence
95% confidence
Finding

svgo 4.0.1 is flagged for incomplete SVG script sanitization, including cases involving foreignObject, namespaces, and executable links. In a skill specifically dedicated to minting, signing, verifying, and transferring SVG assets, this is especially dangerous because users are likely to trust processed SVG output; executable content could survive sanitization and lead to XSS or active content delivery downstream.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: svgo==4.0.1 — 3 advisory(ies): CVE-2026-73650 (SVGO removeScripts plugin leaves some executable scripts intact); CVE-2026-84369 (SVGO: removeScripts incompletely sanitizes executable HTML in SVG foreignObject ); CVE-2026-84370 (SVGO: removeScripts allows executable links through namespace and control-charac)

High
Category
Supply Chain
Confidence
98% confidence
Finding

The package explicitly depends on svgo 4.0.1, which is flagged with multiple advisories indicating incomplete removal of executable content from SVGs. In the context of a protocol centered on minting, signing, verifying, and transferring SVG digital assets, relying on a vulnerable SVG sanitizer is especially dangerous because malicious SVG payloads could survive sanitization and later execute in downstream viewers or web contexts, enabling XSS or script execution against users or integrators.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
82% confidence
Finding

The README instructs users to launch a server with npx tsx server.ts, which relies on resolving an executable at runtime and may execute an unexpected or attacker-influenced package version if the environment is not clean or dependencies are not pinned. Because this starts a long-running verification service intended for agent use, the supply-chain and execution-trust risk is more consequential than a one-off local test command.

Content

No source excerpt is available for this finding.

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 · README.md (reported line 75)May include surrounding context.

Server runs on port 3000

POST your SVG to the server

curl -X POST -H "Content-Type: image/svg+xml" --data-binary @genesis_artifact.svg http://localhost:3000/verify

text

## 🛡 Security & Hacks

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill advertises code-bearing files and detected capabilities involving environment and shell access, but it does not declare any explicit tool scope such as permissions or allowed-tools. This creates a transparency and containment gap: an agent host may grant broader execution than a reviewer expects, increasing the chance of unintended command execution or environment-variable exposure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This code generates a new Ed25519 identity and returns the private secretKey, but there is no user-facing warning, logging, or inline disclosure about handling highly sensitive key material. For code files, access to or creation of credential-like secrets should include some visible disclosure unless clearly covered elsewhere, and none is present in this file.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
77% confidence
Finding

The manifest describes a protocol-focused skill centered on cryptographic asset operations, but the top-level runtime dependency on Express suggests the implementation may also provide network service functionality. Hosting an HTTP API is not stated in the manifest description and is not an obvious requirement of the described protocol itself.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
79% confidence
Finding

Express is a full HTTP server framework, enabling request handling and remote access. For a skill described only as a blockchain-free cryptographic protocol for SVG assets, this network-serving capability is not explicitly justified by the manifest text.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
80% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · simulation/vault.ts (reported line 17)May include surrounding context.

ts
did: did
    };
    fs.writeFileSync(vaultPath, JSON.stringify(data, null, 2));
    // Simulate setting permissions: chmod 600
    fs.chmodSync(vaultPath, 0o600);
}

Known Vulnerable Dependency: body-parser==2.2.2 — 1 advisory(ies): CVE-2026-12590 (body-parser vulnerable to denial of service when invalid limit value silently di)

Low
Category
Supply Chain
Confidence
79% confidence
Finding

body-parser 2.2.2 is flagged for a denial-of-service condition involving invalid limit handling. In an Express-based application, malformed or attacker-controlled request parsing parameters can contribute to request processing failures or resource exhaustion, especially if body parsing is exposed on public endpoints.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: esbuild==0.27.4 — 1 advisory(ies): GHSA-g7r4-m6w7-qqqr (esbuild allows arbitrary file read when running the development server on Window)

Low
Category
Supply Chain
Confidence
60% 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.

Known Vulnerable Dependency: qs==6.15.0 — 3 advisory(ies): CVE-2026-82417 (qs: Denial of Service via Attacker Controlled isBuffer); CVE-2026-8723 (qs has a remotely triggerable DoS: qs.stringify crashes with TypeError on null/u); CVE-2026-82562 (qs array-limit bypass via bracket-key comma parsing)

Low
Category
Supply Chain
Confidence
76% confidence
Finding

qs 6.15.0 has multiple reported denial-of-service weaknesses, and qs is commonly used to parse attacker-supplied query strings or form bodies in Express applications. In a network-exposed service, malformed inputs may crash handlers or consume excessive resources, though the impact is generally availability rather than direct compromise.

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 · package.json (reported line 27)May include surrounding context.

json
"author": "",
  "license": "ISC",
  "dependencies": {
    "base64-js": "^1.5.1",
    "crypto-js": "^4.2.0",
    "express": "^5.2.1",
    "svgo": "^4.0.1",

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 · package.json (reported line 28)May include surrounding context.

json
"license": "ISC",
  "dependencies": {
    "base64-js": "^1.5.1",
    "crypto-js": "^4.2.0",
    "express": "^5.2.1",
    "svgo": "^4.0.1",
    "tweetnacl": "^1.0.3",

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 · package.json (reported line 29)May include surrounding context.

json
"dependencies": {
    "base64-js": "^1.5.1",
    "crypto-js": "^4.2.0",
    "express": "^5.2.1",
    "svgo": "^4.0.1",
    "tweetnacl": "^1.0.3",
    "tweetnacl-util": "^0.15.1"

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 · package.json (reported line 30)May include surrounding context.

json
"base64-js": "^1.5.1",
    "crypto-js": "^4.2.0",
    "express": "^5.2.1",
    "svgo": "^4.0.1",
    "tweetnacl": "^1.0.3",
    "tweetnacl-util": "^0.15.1"
  },

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 · package.json (reported line 31)May include surrounding context.

json
"crypto-js": "^4.2.0",
    "express": "^5.2.1",
    "svgo": "^4.0.1",
    "tweetnacl": "^1.0.3",
    "tweetnacl-util": "^0.15.1"
  },
  "devDependencies": {

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 · package.json (reported line 32)May include surrounding context.

json
"express": "^5.2.1",
    "svgo": "^4.0.1",
    "tweetnacl": "^1.0.3",
    "tweetnacl-util": "^0.15.1"
  },
  "devDependencies": {
    "@types/crypto-js": "^4.2.2",

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 · package.json (reported line 35)May include surrounding context.

json
"tweetnacl-util": "^0.15.1"
  },
  "devDependencies": {
    "@types/crypto-js": "^4.2.2",
    "@types/express": "^5.0.6",
    "@types/node": "^25.5.0",
    "ts-node": "^10.9.2",

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 · package.json (reported line 36)May include surrounding context.

json
},
  "devDependencies": {
    "@types/crypto-js": "^4.2.2",
    "@types/express": "^5.0.6",
    "@types/node": "^25.5.0",
    "ts-node": "^10.9.2",
    "tsx": "^4.19.3",