Background
PR #16 added ^[a-zA-Z0-9._:-]+$ character validation on agent_id at registration to block newline injection, path traversal, and other dangerous inputs.
Gap
DID:web shadow agents are created via resolveDIDWebAgent() in src/middleware/auth.js which calls storage.createAgent() directly, bypassing the register() method and its validation. This means a DID:web agent ID sourced from an untrusted HTTP header or DNS record could contain newlines or slashes and be stored unvalidated.
Impact
If a DID:web agent ID contains a newline character, it could inject headers into HTTP Signature signing strings constructed downstream — the exact attack vector PR #16 protects against for registered agents.
Suggested Fix
Add the same allowlist validation inside resolveDIDWebAgent() before calling storage.createAgent():
```js
if (!/^[a-zA-Z0-9._:-]+$/.test(shadowAgentId) || shadowAgentId.length > 255) {
throw new Error('DID:web shadow agent ID contains invalid characters');
}
```
Or extract the validation into a shared validateAgentId(id) utility used by both paths.
References
Background
PR #16 added
^[a-zA-Z0-9._:-]+$character validation onagent_idat registration to block newline injection, path traversal, and other dangerous inputs.Gap
DID:web shadow agents are created via
resolveDIDWebAgent()insrc/middleware/auth.jswhich callsstorage.createAgent()directly, bypassing theregister()method and its validation. This means a DID:web agent ID sourced from an untrusted HTTP header or DNS record could contain newlines or slashes and be stored unvalidated.Impact
If a DID:web agent ID contains a newline character, it could inject headers into HTTP Signature signing strings constructed downstream — the exact attack vector PR #16 protects against for registered agents.
Suggested Fix
Add the same allowlist validation inside
resolveDIDWebAgent()before callingstorage.createAgent():```js
if (!/^[a-zA-Z0-9._:-]+$/.test(shadowAgentId) || shadowAgentId.length > 255) {
throw new Error('DID:web shadow agent ID contains invalid characters');
}
```
Or extract the validation into a shared
validateAgentId(id)utility used by both paths.References
src/middleware/auth.js→resolveDIDWebAgent()