Back to skill

Security audit

Airnode Hub

Security checks for vulnerabilities and agentic risk

Overview

This skill is a scoped Airnode Hub API discovery and attestation-verification helper with disclosed network use and payment safeguards.

Before installing, expect the skill to contact Airnode Hub and catalogue-listed provider APIs for discovery and verification. Do not provide private keys or payment secrets; paid operations should only proceed through a separate authorized payer with explicit spend limits.

Vulnerability Patterns
  • 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
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
Findings (4)

Unbounded Resource Access

Medium
Category
Excessive Agency
Confidence
75% confidence
Finding

Skill allows unbounded resource consumption (API calls, storage, compute). Without rate limits or quotas, a compromised or misbehaving agent can cause denial-of-service or cost overruns.

Content

Scanner excerpt · references/http-contract.md (reported line 27)May include surrounding context.

md
POST to the same URL with {"operation":"<live operation ID>","parameters":{}} and optional responseProjection. Success contains airnode, requestHash, timestamp, data, signature. Preserve the entire body.

Common failures: 400 invalid parameters; 404 unknown operation; 402 payment required; 429 rate limit; 502 upstream failure; 503 unavailable. Do not interpret failures as empty data or retry indefinitely. A signed provider error remains an error.

## Independent verification
The helper recomputes requestHash from JSON.stringify([operation, canonical(parameters)]) or, with projection, JSON.stringify([operation, canonical(parameters), canonical(responseProjection)]). Canonicalization recursively turns objects into key-sorted entry arrays while preserving array order.

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · scripts/airnodehub.test.mjs (reported line 68)May include surrounding context.

js
for(const ip of ['1.1.1.1','8.8.8.8','2606:4700:4700::1111']) assert.equal(isPublicAddress(ip),true,ip);
});
test('literal loopback and localhost DNS blocked at network layer',async()=>{
 await assert.rejects(safeFetch('https://127.0.0.1/'),/non-public/);
 await assert.rejects(safeFetch('https://localhost/'),/non-public/);
});
test('canonical object ordering stable; arrays preserve order',()=>{

Internal Network Request

Medium
Category
Server-Side Request Forgery
Confidence
70% confidence
Finding

Code issues a request to a loopback, link-local, or private-range host. This can reach internal services not meant to be exposed and is a common SSRF pivot.

Content

Scanner excerpt · scripts/airnodehub.test.mjs (reported line 69)May include surrounding context.

js
});
test('literal loopback and localhost DNS blocked at network layer',async()=>{
 await assert.rejects(safeFetch('https://127.0.0.1/'),/non-public/);
 await assert.rejects(safeFetch('https://localhost/'),/non-public/);
});
test('canonical object ordering stable; arrays preserve order',()=>{
 assert.equal(deriveRequestHash('x',{b:2,a:1}),deriveRequestHash('x',{a:1,b:2}));

Unpinned Dependencies

Low
Category
Supply Chain
Confidence
94% confidence
Finding

The dependency uses a caret range (^2.52.2), which allows installation of newer compatible versions rather than one exact audited version. This creates supply-chain risk because builds may resolve differently over time and could unintentionally pull in a compromised or breaking release of the viem package or one of its transitive dependencies.

Content

Scanner excerpt · scripts/package.json (reported line 6)May include surrounding context.

json
"private": true,
  "type": "module",
  "dependencies": {
    "viem": "^2.52.2"
  }
}