Skip to content

Obfuscation: a [ or ] in a URL path or fragment makes obfuscate_url_string return ? #2523

Closed

Description

@webern

AI finding 2:

A [ or ] in the path or fragment now destroys the whole URL

Severity: blocking (over-redaction regression, whenever either option is on).

The pre-encode pass only escapes [ and ] when the path already contains a category-1 or non-ASCII character
(needs_full_path, libdd-trace-obfuscation/src/http.rs:23-30, :233-241). Otherwise the brackets reach
UriRef::parse, which rejects them (RFC 3986 forbids [/] outside an IP-literal host), so the parse-failure branch
at libdd-trace-obfuscation/src/http.rs:260-266 returns "?" whenever remove_query_string or
remove_paths_with_digits is on.

config     input                                    Agent                             this PR   pre-PR
qs=T dg=F  https://example.com/api/items[1]/detail  https://example.com/api/items[1]/detail  ?    https://example.com/api/items[1]/detail
qs=F dg=T  https://example.com/api/items[1]/detail  https://example.com/api/?/detail         ?    https://example.com/api/?/detail
qs=T dg=T  https://example.com/api/items[1]/detail  https://example.com/api/?/detail         ?    https://example.com/api/?/detail
qs=T dg=F  http://foo.com/x#a[b                     http://foo.com/x#a[b                     ?    http://foo.com/x#a[b

Go's url.Parse accepts brackets in a path and a fragment, and validEncoded explicitly allows them
("not specified in RFC 3986 but left alone by modern browsers"), so the Agent keeps the endpoint and redacts only the
digit segment. The pre-change ADP code did the same. This PR loses the endpoint for the whole class, which is the
exact failure mode #2404 was filed to remove ("a relative URL ... is replaced wholesale, so the endpoint is lost").
Bracketed path segments and bracketed SPA fragments are ordinary production URLs, so this is not a fuzz-only case.

Remediation: upstream, percent-encode every character UriRef rejects before parsing (brackets included) rather than
only the category-1/category-2 sets, then re-pin. A regression test on
https://example.com/api/items[1]/detail under all four option combinations would have caught it.

Originally posted by @webern in DataDog/saluki#2599 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    AI GeneratedPR largely written by AI tools

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions