sdk/node: reject arrays for transform and transform.headers - #1469
sdk/node: reject arrays for transform and transform.headers#1469dwin-gharibi wants to merge 1 commit into
Conversation
Signed-off-by: Dwin Gharibi <dwin.gharibi@email.kntu.ac.ir>
|
|
||
| it("rejects an array transform", () => { | ||
| expect(() => | ||
| convertE2BPerHostRules({ "api.example.com": [["headers"]] } as never), |
There was a problem hiding this comment.
This test doesn't exercise the new Array.isArray(transform) guard. With input { "api.example.com": [["headers"]] }, entries is [["headers"]] and entry is the array ["headers"] — the entry object check (typeof entry !== "object" || entry === null) passes arrays through, so the code path taken is (entry as E2BTransformEntry).transform → undefined → the pre-existing "missing the 'transform' field" error thrown in convertE2BPerHostRules. convertE2BTransformToInject is never reached, and /transform/ happens to match both messages.
That's why the red/green run shows only the headers-array test going red — this test passes before and after the fix. To actually cover the new branch, pass a transform that is an array but still reaches convertE2BTransformToInject, e.g.:
it("rejects an array transform", () => {
expect(() =>
convertE2BPerHostRules({ "api.example.com": [{ transform: ["headers"] }] } as never),
).toThrow(/transform must be an object/);
});With the current as never/array-input approach, consider dropping the test or asserting the specific message. Note that even the corrected input only turns red when the regex is specific — a bare-array transform without a .headers property throws "requires a 'headers' field" in the unfixed code, so the guard's distinctive observable outcome is the message, not the throw.
Review — PR #1469: sdk/node: reject arrays for transform and transform.headersAI-generated review. No human approval claimed. OverviewFixes #1468. Verdict: approveThe fix is correct, minimal, and consistent with the sibling SDK. The core reported bug (headers array → index-key injects) is genuinely closed: tracing the input Finding (minor)
Nits (no change required)
Testing claimsThe stated checks (tsc clean, 192 passed / 1 skipped) are consistent with the diff and the surrounding suite. No test runs were executed in this review; claims were checked by code-path tracing against the base tree. |
Closes #1468.
Motivation
convertE2BTransformToInjectvalidated withtypeof headers !== "object". In JavaScripttypeof [] === "object", so an array passed the guard, andObject.entries(["a","b"])produced[["0","a"],["1","b"]]— injects whose header names are the array indices"0"and"1", carrying realcredentials.
The Python SDK rejects the same input via
isinstance(headers, dict), so this was also a cross-SDKdivergence. And the server does not catch it:
validate_policyrequires only a non-empty string headername, and
"0"satisfies that, so the malformed policy is accepted end to end.What this changes
sdk/node/src/policy.ts— two guards gain anArray.isArraycheck:Error messages are unchanged, so callers matching on them are unaffected. Strings and numbers were
already rejected; this closes the array case, and does the same for the outer
transformforconsistency.
No comment changes.
Testing
New:
sdk/node/test/policy-e2b-shapes.test.tstransformRed/green — with
policy.tsreverted:with the fix, and the whole SDK suite:
CI gates checked locally:
npx tsc --noEmit— clean.npx vitest run— 192 passed (sdk-test-check).