Google publishes the Agent Development Kit. The local
adk web server can create, read, and delete
agent test JSON files. Create already strips directories
from the name. Get, delete, and rebuild did not. A
percent-encoded ../ can leave the
tests/ folder. The patch is in
PR 7034.
| Document | HB-AR-2026.5 / public source review, adk web test files |
|---|---|
| What this is | A research note and an opinion. Google did not hire Hackerbane for this. |
| System | google-adk / adk-python, Google's Agent Development Kit |
| Scope |
create_test, get_test_content,
delete_test, and rebuild_app_tests
in the local adk web server
|
| Review commit | main @ b018062 |
| Upstream | PR 7034 (open) · #7033 |
| Date | 7 September 2026 |
| Author | Barney Chambers, Hackerbane |
If you have not used ADK: it is Google's library for building
agents. adk web is a local FastAPI app for
development. One set of routes writes test JSON under
<agent>/tests/. The file that creates a
test already refuses a path with directories in the name.
The files that read, delete, and rebuild a named test did
not.
On main at commit b018062:
test_name = os.path.basename(test_name) # create_test only # get / delete / rebuild: test_file_path = os.path.join(tests_dir, test_name)
FastAPI decodes a path segment.
%2e%2e%2foutside.json becomes
../outside.json. Join follows it. I opened a
patch that shares one helper with create. It is
PR 7034.
Google did not hire this review. The name on the cover
names the project I read.
The server is unauthenticated on purpose. The module says not to expose it. Default bind is loopback. I still scored this because the create handler already treated the name as untrusted, and the other three did not.
| # | ID | Action | Status on 7 Sep 2026 |
|---|---|---|---|
| 1 | MED-01 | Use the same basename rule on get, delete, and rebuild that create already uses. | Patch open. PR 7034. Issue #7033. |
This is not a full audit of ADK. I split the tree and read
code executors, auth, tools, CLI, artifacts, A2A, and
agent config. The finding I can prove with a unit test on
current main is the test-file name. I did not
treat documented local-dev trust as a product bug.
| In scope |
src/google/adk/cli/dev_server.py:
create_test, get_test_content,
delete_test, rebuild_app_tests.
Tests in
tests/unittests/cli/test_adk_web_server_tests.py.
|
|---|---|
| Out of scope |
Hosted Vertex Agent Engine. The production
api_server path. Code executors that are
documented as unsafe or remote. OAuth client-secret
storage choices I did not patch in this note.
|
| Method |
Read the four handlers. Compare create with get and
delete. Add TestClient cases that fail on
b018062 and pass with the patch.
|
| Retest |
pytest tests/unittests/cli/test_adk_web_server_tests.py::test_delete_test_rejects_path_traversal tests/unittests/cli/test_adk_web_server_tests.py::test_rebuild_single_test_rejects_path_traversal tests/unittests/cli/test_adk_web_server_tests.py::test_delete_test tests/unittests/cli/test_adk_web_server_tests.py::test_get_test_content tests/unittests/cli/test_adk_web_server_tests.py::test_create_test tests/unittests/cli/test_adk_web_server_tests.py::test_rebuild_single_test -q
|
| ID | Severity | Title | Status |
|---|---|---|---|
| MED-01 | Medium | GET/DELETE/rebuild skip the create_test path sanitiser |
Patch open (PR 7034) |
I called this Medium, not High, because the server is a local dev tool and the docs already say not to expose it. The miss is still real: one handler sanitises, three do not.
src/google/adk/cli/dev_server.py · create_test · delete_test · get_test_content · rebuild_app_tests
Create comments that it sanitises to prevent directory
traversal, then calls os.path.basename.
Delete, get, and rebuild join the raw name. A TestClient
DELETE of
/dev/apps/test_app/tests/%2e%2e%2foutside.json
removes <agent>/outside.json on
b018062. After the patch it 404s and the
file stays.
Rebuild with
test_name=../outside.json used to pass that
path into rebuild_tests. After the patch
the basename is outside.json under
tests/.
| When | What |
|---|---|
| 7 Sep 2026 |
Review commit b018062. MED-01 confirmed.
Tests fail on that commit and pass with the patch.
|
| 7 Sep 2026 | Opened #7033 and PR 7034. Still open when this note was written. |
To retest MED-01, run the command in section 2. A normal
my_test.json create/get/delete must still
work.
Read this before you treat anything above as advice.
This file is a public research note. Google did not hire Hackerbane. There is no services agreement, statement of work, or client relationship behind it. The Google name on the cover names the project I read. It is not a partnership badge.
What you have is an opinion about the files and commits named in section 2. It is not a certificate. It is not an endorsement of Google, of ADK, or of the patch. It is not a claim that the rest of ADK is safe, or that it is broken.
I am not telling you to merge, deploy, buy, or sell
anything. This is not investment advice, legal advice, or
a security guarantee. If you ship software, you own that
risk. If you run adk web, you own that risk.
Hackerbane and I accept no liability for how anyone uses this note, for bugs it does not name, or for loss that follows from relying on it. Findings can be wrong, incomplete, or already stale the day after the review commit. Code added after that commit was not reviewed. A retest covers only the checks it names.
You may share this file. Sharing it does not create a contract and does not make the reader a client.
This note is provided as-is, as available, with all faults. To the maximum extent the law allows, Hackerbane disclaims every warranty, express or implied, including merchantability, fitness for a particular purpose, title, and non-infringement. No promise that this text is accurate, complete, or free of error, or that any error will be fixed.
Nobody may rely on this note as a professional engagement. It is not financial, tax, legal, or regulatory advice. No third party is a beneficiary of it.
| Critical | Someone could steal funds or hurt people with what I looked at. |
|---|---|
| High | The check you think you have does not work in the common case. |
| Medium | A real miss, less common in the output I care about here. |
| Low | Real, but limited, or it needs an unlikely setup. |
| Informational | On the record. Not scored as a bug. |
The coloured bars are labels. The word High or Medium is what counts.