Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

RestApiTool path parameters with '.' / '..' still reach the wire after quote(safe="")

クローズ
#7,065 コメント 4 件 リアクション 0 件 担当者 1 名 GitHub で見る

メンテナーはふだん 5 日以内に返信

@sanketpatil06 がすでに取り組んでいます。

2026年9月9日 から。

評価

この issue はまだ評価されていません。

説明

tools

🔴 Required Information

Describe the Bug:
RestApiTool (google.adk.tools.openapi_tool) percent-encodes path parameter values with urllib.parse.quote(value, safe="") and documents that this prevents a model-supplied value from redirecting the request onto an undeclared path on the same host.

That guarantee does not hold for RFC 3986 dot-segments. quote() never encodes . (it is unreserved), so a value containing .. is sent with literal dot-dot segments joined by encoded slashes. Backends/gateways that decode %2F and then merge dot-segments can dispatch the request — with the tool's configured credentials — to a path the OpenAPI spec never declared.

>>> from urllib.parse import quote
>>> quote("../../admin/secret", safe="")
'..%2F..%2Fadmin%2Fsecret'

This is a hardening follow-up to the merged encoding fix (25f53bd). Google VRP issue 557701521 was closed as Infeasible (not tracked as a security bug) with a request to file this publicly.

Steps to Reproduce:

  1. Use an OpenAPI spec that declares only GET /files/{name} against a host that also serves an undeclared route such as GET /admin/secret.
  2. Call the generated tool with args={"name": "../../admin/secret"}.
  3. Observe the outgoing request line GET /files/..%2F..%2Fadmin%2Fsecret.
  4. On a backend that decodes %2F then merges dot-segments (e.g. a Go router over path.Clean(r.URL.Path), nginx as a gateway), the undeclared /admin/secret body is returned as the tool result.

Expected Behavior:
Path parameters whose /- or \-separated segments are . or .. are rejected before any HTTP request is sent. quote(safe="") continues to encode /, ?, and #. Slash-containing IDs such as foo/bar remain encoded as foo%2Fbar.

Observed Behavior:
The client emits GET /files/..%2F..%2Fadmin%2Fsecret. httpx correctly treats %2F as data, so the dot-dot sequences reach the backend unchanged.

Environment Details:

  • ADK Library Version (pip show google-adk): 2.8.0 (a119dd7751082dbbd9a65f71e359abdc2be659cc)
  • Desktop OS: macOS
  • Python Version (python -V): 3.12 / 3.13

Model Information:

  • Are you using LiteLLM: N/A (library-level RestApiTool)
  • Which model is being used: N/A

🟡 Optional Information

Regression:
Present in any release that contains the quote(safe="") path-param encoding fix.

Minimal Reproduction Code:

from urllib.parse import quote
print(quote("../../admin/secret", safe=""))  # '..%2F..%2Fadmin%2Fsecret'

Additional Context:

Backend behavior for GET /files/..%2F..%2Fadmin%2Fsecret:

  • Hand-rolled Go routers that clean the decoded path (path.Clean(r.URL.Path)): request is dispatched to /admin/secret.
  • Legacy Go ServeMux (pre-1.22 / GODEBUG=httpmuxgo121=1): 301 to /admin/secret. ADK does not follow redirects; a following intermediary would complete the access.
  • Modern Go ServeMux (>= 1.22), FastAPI/Starlette direct, Envoy defaults: not affected (%2F stays one segment).
  • nginx as gateway: decode-and-merge by documented analysis.

Same host/port only (origin is fixed by the spec). Suggested client-side fix: reject . / .. as path segments, then keep quote(safe="").

主要言語
Python
スター
21.6k
フォーク
4k
平均マージ
12時間 6分
マージ済み PR(30日)
4

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

google/adk-python のほかの issue

google/adk-python の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。