From 813f01070142af7e172ce4256f9910d1e13ddf6a Mon Sep 17 00:00:00 2001 From: Volodymyr Borysenko Date: Fri, 25 Sep 2026 21:44:23 -0700 Subject: [PATCH] Propagate the forUri deprecation to Encoders, tags and TLDs (#130) Encode.forUri(String) carried @Deprecated with no reason, and the same full-URI encoder was reachable with no signal through Encoders.URI, Encoders.forName("uri"), EncodedWriter and both ForUriTag classes. - Encode.forUri(String) gets an @deprecated tag with migration guidance: forUriComponent for each inserted value; for a whole untrusted URL, parse with java.net.URI, allow-list the scheme and encode for the enclosing context; never apply it to an already percent-encoded URI. It states that the method is retained in all 1.x releases and that 2.0 removal is under consideration (#142). The Writer overload points to it. - Encoders.URI and ForUriTag in jsp and jakarta are @Deprecated with the same guidance, and the Encoders.forName Javadoc says "uri" is still recognized for compatibility. - The forUriComponent note no longer introduces itself by contrast with forUri. - The forUri TLD descriptions (already "Deprecated: ...") also warn about double encoding. - The jsp, jakarta and esapi builds set showDeprecation, so the remaining call sites (ESAPIEncoder.encodeForURL) are named in the build log. - README gains a "Migrating from forUri" section and a News entry. Reflection tests pin the deprecation of Encoders.URI, both forUri overloads and ForUriTag, and that "uri" still resolves. --- README.md | 27 ++++++++++ .../main/java/org/owasp/encoder/Encode.java | 18 +++++-- .../main/java/org/owasp/encoder/Encoders.java | 13 ++++- .../java/org/owasp/encoder/EncodersTest.java | 14 ++++++ esapi/pom.xml | 4 ++ jakarta/pom.xml | 4 ++ .../java/org/owasp/encoder/tag/ForUriTag.java | 5 ++ .../META-INF/java-encoder-advanced.tld | 4 +- .../main/resources/META-INF/java-encoder.tld | 4 +- .../encoder/tag/ForUriTagDeprecationTest.java | 49 +++++++++++++++++++ jsp/pom.xml | 4 ++ .../java/org/owasp/encoder/tag/ForUriTag.java | 5 ++ .../META-INF/java-encoder-advanced.tld | 4 +- .../main/resources/META-INF/java-encoder.tld | 4 +- .../encoder/tag/ForUriTagDeprecationTest.java | 49 +++++++++++++++++++ 15 files changed, 195 insertions(+), 13 deletions(-) create mode 100644 jakarta/src/test/java/org/owasp/encoder/tag/ForUriTagDeprecationTest.java create mode 100644 jsp/src/test/java/org/owasp/encoder/tag/ForUriTagDeprecationTest.java diff --git a/README.md b/README.md index 58077ce..1ba24bb 100644 --- a/README.md +++ b/README.md @@ -142,6 +142,32 @@ TagLib | encoder-jakarta-jsp | <%@taglib prefix="e" uri="owasp.encoder.jakarta"%> | | encoder-jsp | <%@taglib prefix="e" uri="https://www.owasp.org/index.php/OWASP_Java_Encoder_Project"%> | +Migrating from forUri +--------------------- + +`Encode.forUri`, the `uri` context (`Encoders.URI`), `ForUriTag`, and the `forUri` +tag and EL function are deprecated. Percent-encoding a complete URI does not make an +untrusted URI safe: `forUri("javascript:alert(1)")` is returned unchanged. It also +always encodes `%`, so an already percent-encoded URI is double-encoded. + +- For an untrusted value inserted into a URL (a path segment, a query parameter name + or value, or a fragment), use `forUriComponent`: + + ```jsp + + ``` + +- For an entire untrusted URL, parse it with `java.net.URI`, allow-list its scheme + (for example `http` and `https`, rejecting a missing scheme unless relative URLs are + intended), and then encode the whole value for the enclosing context: + + ```jsp + + ``` + +`forUri` is retained for compatibility in all 1.x releases. Whether 2.0 removes it is +tracked in [#142](https://github.com/OWASP/owasp-java-encoder/issues/142). + Development ----------- @@ -167,6 +193,7 @@ Development builds use `1.5.0-SNAPSHOT`; this is not a published release. * feat: all four `forJavaScript*` methods encode dollar sign (`$`) as `\x24`, backtick as `\x60`, and opening brace (`{`) as `\x7b` [#129](https://github.com/OWASP/owasp-java-encoder/issues/129). Escaping `{` prevents input after a trusted `$` from completing `${...}`. Encoded output now supports literal text in ordinary (untagged) template literals as well as single- and double-quoted strings. This changes the encoded output while preserving its decoded JavaScript string value. Tagged templates (including `String.raw`), `${...}` expression bodies, JSON, and script URLs are unsupported; each method's HTML context restrictions still apply. * fix: all four `forJavaScript*` methods escape unpaired UTF-16 surrogates as `\uXXXX`, preserving their JavaScript string values through UTF-8 serialization [#135](https://github.com/OWASP/owasp-java-encoder/issues/135), and escape DEL/C1 controls (U+007F to U+009F) as `\xNN` [#163](https://github.com/OWASP/owasp-java-encoder/issues/163). Valid surrogate pairs and other non-ASCII text remain unescaped except U+2028/U+2029. These are output-fidelity changes; NEL was already ordinary JavaScript string data. * feat: add `Encode.forJson` String/Writer methods, the `json` encoder context, and `forJson` tags and EL functions in both JSP and Jakarta tag libraries [#145](https://github.com/OWASP/owasp-java-encoder/issues/145). The caller supplies double quotes. Output uses RFC 8259 string escapes and also escapes HTML script delimiters. Java `null` becomes the text `null` (the JSON string `"null"` when quoted); unpaired surrogates use Unicode escapes and may not interoperate with every JSON consumer. Prefer a serializer for complete JSON documents. The ESAPI adapter retains its existing JSON delegation and null behavior. +* deprecation: `Encoders.URI` and both `ForUriTag` classes are now deprecated like `Encode.forUri`, whose Javadoc now says what to use instead; the `forUri` TLD descriptions warn about double encoding, the adapter builds show deprecation call sites, and the README has a [forUri migration section](#migrating-from-foruri) [#130](https://github.com/OWASP/owasp-java-encoder/issues/130). * fix: `forHtmlUnquotedAttribute` now replaces U+0085 (NEL) with a hyphen like the other C1 control characters, instead of emitting `…`, which HTML5 parsers decode as U+2026 [#136](https://github.com/OWASP/owasp-java-encoder/issues/136). * fix: the XML 1.1 encoders (`forXml11`, `forXml11Content`, `forXml11Attribute`) now encode U+0085 (NEL) as `…` and U+2028 (line separator) as `
`, so they are not normalized to a line feed [#136](https://github.com/OWASP/owasp-java-encoder/issues/136). * maintenance: clarify output-context contracts and expand XML 1.1 tests, fix clean reactor compilation, and remove the obsolete benchmark profile. diff --git a/core/src/main/java/org/owasp/encoder/Encode.java b/core/src/main/java/org/owasp/encoder/Encode.java index 4fa3b1a..6d22484 100644 --- a/core/src/main/java/org/owasp/encoder/Encode.java +++ b/core/src/main/java/org/owasp/encoder/Encode.java @@ -690,6 +690,16 @@ public static void forCssUrl(Writer out, String input) * * @param input the input to encode * @return the encoded result + * @deprecated Encoding a complete URI does not make an untrusted URI + * safe. Encode each untrusted value inserted into a URL with + * {@link #forUriComponent(String)} instead. To use an entire untrusted + * URL, parse it with {@link java.net.URI}, allow-list its scheme (for + * example {@code http} and {@code https}), and then encode it for the + * enclosing output context, for example with + * {@link #forHtmlAttribute(String)}. This method always encodes + * {@code %}, so never apply it to a URI that is already percent-encoded. + * It is retained for compatibility in all 1.x releases; removal in 2.0 is + * under consideration. */ @Deprecated public static String forUri(String input) { return encode(Encoders.URI_ENCODER, input); @@ -704,7 +714,7 @@ public static void forCssUrl(Writer out, String input) * @throws NullPointerException if out is null * @throws IOException if thrown by writer * - * @deprecated There is never a need to encode a complete URI with this form of encoding. + * @deprecated See {@link #forUri(String)} for what to use instead. */ @Deprecated public static void forUri(Writer out, String input) throws IOException @@ -735,9 +745,9 @@ public static void forCssUrl(Writer out, String input) * Encoding Notes *