CLAUDE WATERMARK REMOVER · PRACTICAL TEST
Can deleting a marker change a URL path to its parent?
Yes. In our URL constructor test, deleting U+200B from a disguised two-dot segment changes /a/..%E2%80%8B/b into /b. Inspect the resolved pathname before using the edited URL.
Open the Claude text cleaner · Full measured data
Measured inputs and outputs
These are locally constructed test strings, not evidence that Claude inserts these characters. We executed the saved homepage script snapshot with a minimal DOM harness and compared exact strings. The invisible-checkbox state and dash mode appear in each row. The observations below test this page's specific question. Destination observations run independently on the exact input and cleaned strings in the recorded Node runtime. We make no detector-score or statistical-watermark removal claim.
| Fixture and mode | Input string and code points | Output and cleaner status | Observed before / after |
|---|---|---|---|
| Marked parent direct string / keep / invisible true | "https://example.com/a/../b"U+0068 U+0074 U+0074 U+0070 U+0073 U+003A U+002F U+002F U+0065 U+0078 U+0061 U+006D U+0070 U+006C U+0065 U+002E U+0063 U+006F U+00 … | "https://example.com/a/../b"Removed 1 invisible character | {"pathname":"/a/..%E2%80%8B/b","href":"https://example.com/a/..%E2%80%8B/b"}{"pathname":"/b","href":"https://example.com/b"} |
| Real parent direct string / keep / invisible true | "https://example.com/a/../b"U+0068 U+0074 U+0074 U+0070 U+0073 U+003A U+002F U+002F U+0065 U+0078 U+0061 U+006D U+0070 U+006C U+0065 U+002E U+0063 U+006F U+00 … | "https://example.com/a/../b"No selected invisible characters found | {"pathname":"/b","href":"https://example.com/b"}{"pathname":"/b","href":"https://example.com/b"} |
| Encoded parent direct string / keep / invisible true | "https://example.com/a/%2e%2e/b"U+0068 U+0074 U+0074 U+0070 U+0073 U+003A U+002F U+002F U+0065 U+0078 U+0061 U+006D U+0070 U+006C U+0065 U+002E U+0063 U+006F U+00 … | "https://example.com/a/%2e%2e/b"No selected invisible characters found | {"pathname":"/b","href":"https://example.com/b"}{"pathname":"/b","href":"https://example.com/b"} |
| Retained joiner direct string / keep / invisible true | "https://example.com/a/../b"U+0068 U+0074 U+0074 U+0070 U+0073 U+003A U+002F U+002F U+0065 U+0078 U+0061 U+006D U+0070 U+006C U+0065 U+002E U+0063 U+006F U+00 … | "https://example.com/a/../b"No selected invisible characters found | {"pathname":"/a/..%E2%80%8D/b","href":"https://example.com/a/..%E2%80%8D/b"}{"pathname":"/a/..%E2%80%8D/b","href":"https://example.com/a/..%E2%80%8D/b"} |
A deletion changes structural recognition
The first authored URL contains two dots followed by U+200B between path slashes. Before cleanup, the URL constructor treats that segment as path data and percent-encodes the marker. Once our actual cleaner deletes the marker, the segment is exactly two dots, so construction removes the preceding a segment and returns /b. The plain-parent and encoded-parent references already resolve to /b before any edit. The retained U+200D row remains a data segment. Recording the full serialized URL and pathname exposes the change that a shorter removal count would conceal.
This is construction, not a server routing test
The observer uses the standard URL constructor on complete example.com strings. It performs no request and follows no redirects. These results do not establish a server traversal vulnerability, a filesystem path, browser navigation history or access to a protected resource. The earlier encoded-path guide explains when a marker stays encoded; this matrix instead measures recognition of a structural parent segment. The cleaner has no URL-aware protection and does not compare intended destinations. WHATWG defines dot-segment handling, while the saved runtime and script hash identify the implementation actually measured here.
Review the destination after the edit
Preserve the original URL, then parse the original and edited strings using the destination application rules. Compare the entire path, not only a visible final filename. If a path is used for navigation, confirm the intended resource before accepting a changed parent relationship. Avoid interpreting fewer characters as a harmless cosmetic cleanup. Application authorization must be checked separately from string parsing. These four synthetic rows provide a reproducible example of a structural change; they do not recommend altering an unknown link or establish that all servers resolve encoded dots the same way.
Reproduce this test
Save reproduce.cjs and tested-app.js in the same folder. Run the command below with Node.js. The harness prints its runtime, script SHA-256 and every measured row. Compare those rows with the original record. Using a newer script or runtime creates a new experiment; retain the version information with your rerun.
node reproduce.cjsReference and next check
WHATWG URL Standard provides the relevant primary definition. The table and fixture analysis are original measurements. For broader inspection, use our Unicode inspector. Read the scope distinction before interpreting cleanup as a watermark result.