RestApiTool path parameters with '.' / '..' still reach the wire after quote(safe="")
Los mantenedores suelen responder en 5 días
@sanketpatil06 ya está trabajando en esto.
Desde el 9/9/2026.
Evaluación
Este issue todavía no se ha evaluado.
Descripción
🔴 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:
- Use an OpenAPI spec that declares only
GET /files/{name}against a host that also serves an undeclared route such asGET /admin/secret. - Call the generated tool with
args={"name": "../../admin/secret"}. - Observe the outgoing request line
GET /files/..%2F..%2Fadmin%2Fsecret. - On a backend that decodes
%2Fthen merges dot-segments (e.g. a Go router overpath.Clean(r.URL.Path), nginx as a gateway), the undeclared/admin/secretbody 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 (
%2Fstays 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="").
- Lenguaje dominante
- Python
- Estrellas
- 21.6k
- Forks
- 4k
- Merge medio
- 12 h 6 min
- PR fusionados (30 d)
- 4
Preparar el entorno
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de google/adk-python
-
[A2A] RemoteA2aAgent(use_legacy=False): extension header written to state['http_kwargs'], ignored by a2a-sdk 1.x transportsPosiblemente ocupada @surajksharma07 la tomó hace 3 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
google/adk-python#7334 · 2 comentarios · 1 asignado ·
Los mantenedores suelen responder en 5 días
-
GoogleOidcVerifier treats string "false" as a verified email claimPosiblemente ocupada @surajksharma07 la tomó hace 4 días. Abiertocore
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
google/adk-python#7289 · 5 comentarios · 1 asignado ·
Los mantenedores suelen responder en 5 días
-
RestApiTool raises uncaught KeyError when a required path param is omittedPosiblemente ocupada @llalitkumarrr la tomó hace 4 días. Abiertorequest clarification tools
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
google/adk-python#7282 · 5 comentarios · 1 asignado ·
Los mantenedores suelen responder en 5 días
-
CredentialsManager should also extract scopes when populating auth schemesPosiblemente ocupada @sanketpatil06 la tomó hace 7 días. Abiertocore needs review
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
google/adk-python#7266 · 2 comentarios · 1 asignado ·
Los mantenedores suelen responder en 5 días
-
OAuth2 Discovery method fails because FastMCP with GoogleProvider (OAuth) returns issuerUrl with trailing slashPosiblemente ocupada @sanketpatil06 la tomó hace 7 días. Abiertomcp
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
google/adk-python#7265 · 4 comentarios · 1 asignado ·
Los mantenedores suelen responder en 5 días
Todos los issues de google/adk-python
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
BasedHardware/omi#20271 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 92/100
openai/openai-cookbook#3153 ·
Los mantenedores suelen responder en 1 día
-
cvss-severity:high devguard l3montree-cybersecurity/devguard/devguard pkg:golang/github.com/l3montree-dev/devguard risk:low state:open
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
l3montree-dev/devguard#3146 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
-
bug confirmed issue
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
open-webui/open-webui#31849 · 2 comentarios ·
Los mantenedores suelen responder en 1 día