Test: pin both halves of the zip-slip entry-name contract - #762
Open
AmaadMartin wants to merge 1 commit into
Open
Test: pin both halves of the zip-slip entry-name contract#762AmaadMartin wants to merge 1 commit into
AmaadMartin wants to merge 1 commit into
Conversation
The suite only asserted rejection. A change that swapped the exact-segment
test for a substring test stayed green while it broke every archive with a
benign dot-prefixed member such as references/..hidden.txt.
Add three cases that assert such a member still loads, and add the two bare
dangerous shapes ('..' and a leading Windows traversal) that the committed
list only covered in prefixed form.
Correct the docstring: adk-js no longer mirrors adk-python's
_load_skill_from_zip_bytes, it is deliberately stricter.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
Follow-up to google#621 (the zip-slip fix this pins). Original port: google#584.
Problem: The
isDangerousZipEntryNamesuite asserts only rejection. Nothing asserts that a member name which merely contains..inside a segment is still accepted, so an over-broad change stays green while it breaks archives with a benign dot-prefixed member. The docstring also still says the function mirrors adk-python's_load_skill_from_zip_bytes, which stopped being true at #621.Solution: I pinned the accepted half of the contract with three new cases, and added the two bare dangerous shapes the committed list only covered in prefixed form. I rewrote the docstring to name the divergence and its reason, in the house style of the neighbouring
isBareSkillNamecomment. No runtime behaviour changes: the source diff is comment lines only.Notes for the reviewer:
..cases were appended to the existingit.eacharray. The assertion body, the test name and all five existing entries are unchanged, so no regression signal is lost.a/../../evil.txt. The committedreferences/../../esc.txtis the same shape and exercises no new branch.isDangerousZipEntryNamestays module-private. The new tests drive it throughloadSkillFromZipBuffer, as the existing cases do.mainwas 13 commits behindgoogle/adk-jsmainand did not contain Fix: reject a non-object Reasoning Engine raw body instead of crashing the dev server #621, so the new cases could not pass. I fast-forwarded the fork'smainto upstream and rebased. The PR diff is two files.gh pr list --repo AmaadMartin/adk-js --state open --limit 100plusgh pr diff --name-onlyon every skills, zip and loader PR. Only Fix: key directory-loaded skill resources by POSIX relative paths #728 touches these two files. It rewrites resource keys inloadDirand adds tests in theloadSkillFromDirblock; this PR touchesisDangerousZipEntryNameand theloadSkillFromZipBufferblock. There is no dependency between them, and Fix: key directory-loaded skill resources by POSIX relative paths #728 is based on amainthat predates Fix: reject a non-object Reasoning Engine raw body instead of crashing the dev server #621, so I did not stack on it.Testing Plan
Unit Tests:
npx vitest run --project unit:core core/test/skills/loader_test.ts— 52 passed, up from 47 onmain.Mutation proof. I ran each mutation against
core/src/skills/loader.tsand confirmed the expected tests turn red.segment === '..'->segment.includes('..')Error: Dangerous zip entry ignored: references/..hidden.txt,... assets/v1..2.bin,... scripts/a..b.sh.split(/[/\\]/)->split('/')'..\evil.txt'and existing'scripts\..\..\pwned.txt', bothAssertionError: expected [Function] to throw an error.some((segment) => segment === '..')->startsWith('../')'..', allAssertionError: expected [Function] to throw an error.Mutation 1 is the regression the new negative test exists to catch. It is green against
maintoday.Manual End-to-End (E2E) Tests:
No E2E surface. The change is a comment plus unit cases against an in-memory archive.
Other local checks on the pushed commit:
npm run build— passes.npm run lint— clean.npm run format:check— clean.git diff main -- core/src/skills/loader.ts— every added and removed line is a comment line.Checklist