diff --git a/CHANGELOG.md b/CHANGELOG.md index fff7cca..23b1d23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ unchanged. [1.5.0 is available from Central](releases/1.5.0-central-publication. ## Unreleased +- Clarify JavaScript encoding modes, output growth, and insertion-boundary + requirements for #243; distinguish JSON whole-string HTML embedding from + JavaScript fragment protection. Correct internal HTML/XML comments and + strengthen parser tests to verify script text, not only absence of a marker. + Encoding behavior is unchanged. - Resume development at `1.5.1-SNAPSHOT`, with the immutable 1.5.0 public-API baseline and its matching support APIs. Minimum-consumer fixtures are unchanged. - Discover release tags independently of commit ancestry so squash merges cannot @@ -42,7 +47,7 @@ Signed artifact availability and independent verification are tracked in the * build/compatibility: update the published JSP provided API to 2.3.3 and the Jakarta test classpath to Servlet 6.1.0 and EL 6.0.1, while retaining independent JSP 2.2.1 and Java 8-compatible Jakarta minimum-consumer fixtures. Japicmp now resolves distinct old/new support classpaths so the 1.4.1 comparison remains complete. Dependabot scans the root Maven reactor once, rather than opening duplicate module proposals, and continues to scan the standalone compatibility-fixture project separately. * 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. -* fix: the HTML/block JavaScript encoders escape every ASCII character that can contribute to a case-insensitive `` script tokens, including the HTML end-tag delimiters, so any nonempty encoded substring cannot complete a delimiter supplied partly by adjacent trusted literal text. `forCDATA` represents every `]` and `>` with close/reopen sequences, preserving parsed text while breaking every nonempty encoded substring of `]]>`; its String facade grows with actual output instead of eagerly reserving the 13× maximum. `forXmlComment` replaces every hyphen with `~`. These are substantial compatibility-visible output changes; see the [migration record](docs/compatibility-decisions.md#15-parser-boundary-output-migration). +* fix: the HTML/block JavaScript encoders escape every ASCII character that can contribute to case-insensitive `` script tokens, including their delimiters, so the encoding of any nonempty value cannot complete a delimiter supplied partly by adjacent trusted literal text. `forCDATA` represents every `]` and `>` with close/reopen sequences, preserving parsed text while breaking every nonempty encoded substring of `]]>`; its String facade grows with actual output instead of eagerly reserving the 13× maximum. `forXmlComment` replaces every hyphen with `~`. These are substantial compatibility-visible output changes; see the [migration record](docs/compatibility-decisions.md#15-parser-boundary-output-migration). * fix: `EncodedWriter` now enforces Writer lifecycle semantics: write, append and flush operations fail after close; repeated close is harmless; the first close finalizes pending input and still attempts the delegate close, preserving simultaneous failures with suppressed exceptions. Array-slice writes now use overflow-safe bounds validation, including `Integer.MAX_VALUE`-shaped ranges. * build: compare all three 1.5.0 artifacts against the immutable 1.4.1 public-API baseline, and verify that every publishable effective POM inherits repository-root SCM connection, developer connection and URL values without module-name suffixes. * 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. diff --git a/core/src/main/java/org/owasp/encoder/Encode.java b/core/src/main/java/org/owasp/encoder/Encode.java index 9bde58a..7adcd7e 100644 --- a/core/src/main/java/org/owasp/encoder/Encode.java +++ b/core/src/main/java/org/owasp/encoder/Encode.java @@ -1103,14 +1103,47 @@ public static void forJava(Writer out, String input) * blocks, and JavaScript source. The caller MUST * provide surrounding single (') or double (") quotation marks, or backticks * (`) for an ordinary (untagged) template literal. - * Since this performs additional encoding so it can work in all - * of the JavaScript contexts listed, it may be slightly less - * efficient than using one of the methods targeted to a specific - * JavaScript context ({@link #forJavaScriptAttribute(String)}, - * {@link #forJavaScriptBlock}, {@link #forJavaScriptSource}). - * Unless you are interested in saving a few bytes of output or - * are writing a framework on top of this library, it is recommend - * that you use this method over the others.

+ * HTML event-attribute values must also be quoted at the HTML level. + * This general method applies the protections needed for all of these + * contexts. The resulting source can be substantially longer than the input; + * the evaluated JavaScript string value is preserved, not its source spelling. + * Choose {@link #forJavaScriptAttribute(String)}, + * {@link #forJavaScriptBlock(String)}, or {@link #forJavaScriptSource(String)} + * when the output context is known and satisfies that method's contract.

+ * + *

Insertion boundaries: insert the complete encoded result into + * literal string text, not into a JavaScript expression or where it can + * continue or extend an escape sequence. Trusted text immediately before the + * insertion must not leave an unmatched backslash or an incomplete hex or + * Unicode escape, or an extendable escape such as \0 before + * an input digit. In an HTML event attribute, it must not continue an HTML + * character reference begun by trusted text, such as an unencoded + * & followed by encoded #39;. Encode the + * complete string value, including trusted text, when possible. + * The surrounding template must keep the insertion in the + * intended JavaScript string and HTML context. Encoding cannot repair an + * already unsafe template, such as an HTML script end-tag name + * </script followed by whitespace or / + * before the insertion, with the closing > supplied later.

+ * + *

In HTML script blocks, a nonempty encoded fragment cannot complete the + * raw sequences </script or <script + * (case-insensitive), + * <!--, or --> with adjacent trusted text. + * For example, trusted </scr, an encoded i, and + * trusted pt> cannot form an HTML closing script tag. + * Preventing a split <script also avoids entering the HTML + * tokenizer's double-escaped state after a trusted <!--, + * which could otherwise cause the rest of the page to be consumed as script. + * Empty input produces empty output and cannot separate dangerous trusted + * fragments. These protections do not sanitize the surrounding template.

+ * + *

For example, forJavaScript("http://google.com") returns + * h\x74\x74\x70:\/\/google.\x63om, which evaluates to the + * original URL inside a supported JavaScript string literal. + * {@link #forJavaScriptSource(String)} and + * {@link #forJavaScriptAttribute(String)} leave this URL unchanged, but + * must only be used in their respective output contexts.

* * Example JSP Usage: *
@@ -1195,9 +1228,8 @@ public static void forJava(Writer out, String input)
      *     
      *       U+002F/
      *       \/
-     *       This encoding is used to avoid an input sequence
-     *       "</" from prematurely terminating a </script>
-     *       block.
+     *       Escaping slash prevents it from contributing to
+     *       an HTML script end tag such as </script>.
      *     
      *     
      *       U+003C<
@@ -1212,8 +1244,10 @@ public static void forJava(Writer out, String input)
      *     
      *       C, I, P, R, S, T and lowercase
      *       \x##
-     *       Breaks every nonempty encoded substring of a
-     *       case-insensitive </script token.
+     *       Prevents a nonempty encoded fragment from completing
+     *       the case-insensitive sequences </script or
+     *       <script with
+     *       adjacent trusted text; see the insertion-boundary requirements above.
      *     
      *     
      *       U+005C\
@@ -1236,7 +1270,7 @@ public static void forJava(Writer out, String input)
      *       U+0000 to U+001F
      *       \x##
      *       Hexadecimal encoding is used for characters in this
-     *       range that were not already mentioned in above.
+     *       range that were not already listed above.
      *     
      *     
      *       U+002D-
@@ -1271,7 +1305,9 @@ public static void forJava(Writer out, String input)
      * preserve the string value in single-quoted, double-quoted, and ordinary
      * template literals. Tagged templates (including {@code String.raw}) are not
      * supported: tags can observe raw escapes or interpret the text in another
-     * language. This is not a JSON encoder; use a JSON serializer for JSON.
+     * language. This is not a JSON encoder; use a JSON serializer for complete
+     * JSON documents. JSON embedded in HTML must also be safe for that HTML
+     * context; see {@link #forJson(String)} for JSON string contents.
      * Do not use the result in {@code javascript:} or {@code data:} URLs;
      * URL decoding introduces a separate parsing context.

* @@ -1312,10 +1348,10 @@ public static void forJavaScript(Writer out, String input) *

DEL and C1 controls (U+007F to U+009F) are hex-escaped. Unpaired UTF-16 * surrogates use Unicode escapes; valid surrogate pairs remain unescaped.

* - *

Unless you are interested in saving a few bytes of - * output or are writing a framework on top of this library, it is - * recommend that you use {@link #forJavaScript(String)} over this - * method.

+ *

The HTML attribute value must also be enclosed in quotation marks. + * The insertion-boundary requirements of {@link #forJavaScript(String)} + * apply. This method avoids the additional HTML script-block escapes, + * which can substantially increase source size.

* * Example JSP Usage: *
@@ -1325,7 +1361,8 @@ public static void forJavaScript(Writer out, String input)
      * 

For ordinary template literals, insert the result into literal text, * not a ${...} expression. Tagged templates (including * {@code String.raw}) are not supported; see {@link #forJavaScript(String)}. - * This is not a JSON encoder; use a JSON serializer for JSON. + * This is not a JSON encoder; use a JSON serializer for complete JSON + * documents. For JSON embedded in HTML, see {@link #forJson(String)}. * Do not use the result in {@code javascript:} or {@code data:} URLs; * URL decoding introduces a separate parsing context.

* @@ -1366,10 +1403,10 @@ public static void forJavaScriptAttribute(Writer out, String input) *

DEL and C1 controls (U+007F to U+009F) are hex-escaped. Unpaired UTF-16 * surrogates use Unicode escapes; valid surrogate pairs remain unescaped.

* - *

Unless you are interested in saving a few bytes of - * output or are writing a framework on top of this library, it is - * recommend that you use {@link #forJavaScript(String)} over this - * method.

+ *

The insertion-boundary requirements and nonempty-fragment HTML + * protection of {@link #forJavaScript(String)} apply. This method retains + * the script-letter escapes; its shorter quote escapes do not make it safe + * for HTML event attributes.

* * Example JSP Usage: *
@@ -1381,7 +1418,8 @@ public static void forJavaScriptAttribute(Writer out, String input)
      * 

For ordinary template literals, insert the result into literal text, * not a ${...} expression. Tagged templates (including * {@code String.raw}) are not supported; see {@link #forJavaScript(String)}. - * This is not a JSON encoder; use a JSON serializer for JSON. + * This is not a JSON encoder; use a JSON serializer for complete JSON + * documents. For JSON embedded in HTML, see {@link #forJson(String)}. * Do not use the result in {@code javascript:} or {@code data:} URLs; * URL decoding introduces a separate parsing context.

* @@ -1422,10 +1460,10 @@ public static void forJavaScriptBlock(Writer out, String input) *

DEL and C1 controls (U+007F to U+009F) are hex-escaped. Unpaired UTF-16 * surrogates use Unicode escapes; valid surrogate pairs remain unescaped.

* - *

Unless you are interested in saving a few bytes of - * output or are writing a framework on top of this library, it is - * recommend that you use {@link #forJavaScript(String)} over this - * method.

+ *

The JavaScript insertion-boundary requirements of + * {@link #forJavaScript(String)} apply. This method avoids HTML-specific + * escaping and leaves http://google.com unchanged. Use it only + * for standalone JavaScript resources, not to reduce escaping in HTML.

* * Example JSP Usage: * This example is serving up JavaScript source directly: @@ -1437,7 +1475,8 @@ public static void forJavaScriptBlock(Writer out, String input) *

For ordinary template literals, insert the result into literal text, * not a ${...} expression. Tagged templates (including * {@code String.raw}) are not supported; see {@link #forJavaScript(String)}. - * This is not a JSON encoder; use a JSON serializer for JSON. + * This is not a JSON encoder; use a JSON serializer for complete JSON + * documents. For JSON embedded in HTML, see {@link #forJson(String)}. * Do not use the result in {@code javascript:} or {@code data:} URLs; * URL decoding introduces a separate parsing context.

* @@ -1480,6 +1519,16 @@ public static void forJavaScriptSource(Writer out, String input) * > or &. * * + *

For HTML script embedding, encode the complete contents of each JSON + * string value and member name, including any trusted text that belongs + * inside that string, and then supply its double quotes. Do not insert the + * result into an unfinished JSON escape sequence. This method does not + * protect arbitrary fragments joined to unencoded string text: for example, + * trusted </scr + forJson("i") + trusted + * pt> still forms an HTML closing script tag. The rest of + * the JSON document and enclosing template must also be safe for the HTML + * context.

+ * *

The encoding is:

* *
    @@ -1490,8 +1539,9 @@ public static void forJavaScriptSource(Writer out, String input) * \f, \r or \u00xx. *
  • <, > and & * are encoded as \u003c, \u003e and - * \u0026, so the output cannot close or comment out an - * enclosing HTML <script> element.
  • + * \u0026, so the complete encoded string content cannot + * supply an HTML script end tag or comment token. The surrounding text + * remains subject to the requirements above. *
  • U+2028 and U+2029 are encoded as \u2028 and * \u2029.
  • *
  • Unpaired surrogates are encoded as \ud800 to diff --git a/core/src/main/java/org/owasp/encoder/Encoders.java b/core/src/main/java/org/owasp/encoder/Encoders.java index 9e4fcef..99cfc4e 100644 --- a/core/src/main/java/org/owasp/encoder/Encoders.java +++ b/core/src/main/java/org/owasp/encoder/Encoders.java @@ -220,7 +220,7 @@ public final class Encoders { static final JavaScriptEncoder JAVASCRIPT_ENCODER = map(JAVASCRIPT, new JavaScriptEncoder(JavaScriptEncoder.Mode.HTML, false)); /** - * Encoder for JavaScript appearing in XML/HTML attributes. + * Encoder for JavaScript string literal text in quoted HTML event attributes. */ static final JavaScriptEncoder JAVASCRIPT_ATTRIBUTE_ENCODER = map(JAVASCRIPT_ATTRIBUTE, new JavaScriptEncoder(JavaScriptEncoder.Mode.ATTRIBUTE, false)); diff --git a/core/src/main/java/org/owasp/encoder/JavaScriptEncoder.java b/core/src/main/java/org/owasp/encoder/JavaScriptEncoder.java index 74fa230..0cfb82a 100644 --- a/core/src/main/java/org/owasp/encoder/JavaScriptEncoder.java +++ b/core/src/main/java/org/owasp/encoder/JavaScriptEncoder.java @@ -48,9 +48,9 @@ class JavaScriptEncoder extends Encoder { */ enum Mode { /** - * Standard encoding of JavaScript Strings. Escape sequences are chosen - * according to what is the shortest sequence possible for the - * character. + * Encoding for string literal text in standalone JavaScript, including + * ordinary template literals. Template syntax is escaped even where + * a shorter spelling would be possible for a particular string. */ SOURCE, /** @@ -59,15 +59,17 @@ enum Mode { * use a sequence of encodes that would actually be longer. In this mode * double-quote is "\x22" and single-quote is "\x27". (In HTML * attributes the alternate would be encoding "\"" and "\'" with entity - * escapes to "\&#34;" and "\&39;"). + * escapes to "\&#34;" and "\&#39;"). */ ATTRIBUTE, /** * Encoding for use in HTML script blocks. The main concern here is * prematurely terminating a script block with a closing * "</script" token inside the string. Characters that can contribute - * to an HTML script delimiter are escaped so an encoded substring - * cannot complete a delimiter supplied partly by trusted literal text. + * to an HTML script delimiter are escaped so a nonempty encoded fragment + * cannot complete a raw token supplied partly by trusted literal text. + * The surrounding template must satisfy the insertion-boundary + * requirements documented by Encode.forJavaScript. */ BLOCK, /** @@ -83,9 +85,9 @@ enum Mode { */ private final Mode _mode; /** - * True if quotation characters should be hex encoded. Hex encoding quotes - * allows JavaScript to be included in XML attributes without additional - * XML-based encoding. + * True if quotation characters should be hex encoded, preventing those + * quotes from terminating a quoted HTML attribute. This is not a promise + * of XML attribute safety; XML has separate escaping and validity rules. */ private final boolean _hexEncodeQuotes; /** @@ -133,11 +135,12 @@ enum Mode { if (mode == Mode.BLOCK || mode == Mode.HTML) { // In \";"; + Document document = Jsoup.parse("

    after

    "); + // The image spelling is consumed as end-tag attributes. A marker + // count alone would falsely suggest that all text stayed in script. + assertEquals(0, document.select("img#pwn").size()); + assertFalse(source.equals(document.selectFirst("script").data())); + assertEquals("var value=\"", document.selectFirst("script").data()); + } + } + + public void testEmptyJavaScriptInputCannotSeparateTrustedTokens() { + for (String encoded : new String[]{Encode.forJavaScript(""), + Encode.forJavaScriptBlock("")}) { + Document document = Jsoup.parse(""); + assertEquals(1, document.select("img#pwn").size()); + } + } + public void testJavaScriptCommentOpenPrefixesAreBroken() { String token = "`; hyphen uses `\x2d` | JavaScript string values are preserved, but common letters and spaces can change encoded bytes. Attribute-only and standalone-source modes retain their narrower rules. | +| HTML script JavaScript (`forJavaScript`, `forJavaScriptBlock`) | Escapes every character that can contribute to case-insensitive ``; hyphen uses `\x2d` | JavaScript string values are preserved, but common letters and spaces can change encoded bytes. Attribute-only and standalone-source modes retain their narrower rules. | | XML CDATA | Represents every `]` and `>` with a close/character-data/reopen spelling | Parsed XML text is preserved, apart from documented XML normalization/replacement. Output can expand 13× and parser event boundaries can change. | | XML comment | Replaces every hyphen with `~` | Prevents cross-fragment `--` and `-->`; comment text is deliberately lossy. | The trusted fragments must already be valid for the selected parser context. +In JavaScript, insertion must not continue or extend an escape sequence, +including an extendable numeric escape such as `\0` before an input digit. In +HTML, encoding cannot undo a trusted prefix that has already entered an end tag +such as `` script -tokens. This keeps any nonempty encoded substring from completing a delimiter +part of case-insensitive `` +script tokens. This keeps the encoding of any nonempty value from completing a delimiter supplied partly by adjacent trusted literal string text. The additional output changes include space, `!`, hyphen (`\x2d`), `<`, `>`, slash, and both cases of the letters in `script`. JavaScript interprets these spellings as the original @@ -79,6 +87,25 @@ string value, but byte-for-byte output, snapshots, signatures and cache keys can change. `forJavaScriptAttribute` and `forJavaScriptSource` do not apply the HTML raw-text rule because their output is not for an HTML script element. +The opening `` and preserves the XML parser's text value, subject to the existing invalid-character replacement and line-ending normalization policies. Its output can expand to thirteen @@ -96,6 +123,13 @@ HTML script data block. A complete JSON document should come from a JSON seriali choose one configured for safe HTML embedding if it is put inside a ``. The rest of the document and template must also be safe for HTML. + Java `null` is encoded as the text `null`: with the caller's quotes this is the JSON **string** `"null"`, not the JSON null value. The facade generally renders null as text; JSP EL conversion has its own contract. `forJson` preserves unpaired diff --git a/docs/usage.md b/docs/usage.md index 7a37227..b818682 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -41,12 +41,24 @@ Encode.forXmlComment(out, userText); out.write(" -->"); ``` -The trusted prefix and suffix must themselves be valid syntax. Keep the encoder +The trusted prefix and suffix must keep the insertion in the intended context. +In JavaScript, do not insert encoded output where it can continue or extend an +escape sequence, including after an unmatched backslash, an incomplete hex +escape, or `\0` before an input digit. In HTML script content, the trusted prefix must +not already have formed an end-tag name followed by whitespace or `/`, such as +` Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script - blocks, or standalone JavaScript source. In HTML script blocks, additional hex - escapes prevent encoded fragments from completing </script, <!--, or --> - tokens across trusted boundaries; hyphen uses \x2d. + blocks, or standalone JavaScript source. Additional escapes are always applied so + nonempty encoded fragments cannot complete </script, <script, <!--, or --> across trusted + boundaries in an HTML script element. Most use hex escapes; slash uses \/ and + hyphen uses \x2d. The output can be substantially longer than the original text. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScript @@ -145,17 +155,26 @@ Encodes a JavaScript string in an HTML event attribute (such as onclick). Not safe in HTML script blocks. Uses the same encoding as forJavaScript except that slash, hyphen, space, !, <, >, and both cases of C, I, P, R, S, and T are not - escaped because these characters protect the outer HTML script context. + escaped; those additional escapes protect an enclosing HTML script element. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptAttribute @@ -177,14 +196,23 @@ backslash escapes. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptBlock @@ -207,14 +235,23 @@ are not escaped; double and single quotes use backslash escapes. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptSource @@ -234,7 +271,10 @@ Encodes for the contents of a JSON string literal (RFC 8259). The caller MUST provide the surrounding double quotation marks. Safe for JSON string values in a JSON document or in an HTML script element, - including script type="application/json". " and \ are encoded as \" + including script type="application/json". For HTML embedding, encode the complete + contents of each string value and member name, including any trusted text in it. + Do not join encoded fragments to unencoded string text or unfinished JSON escapes; + the remaining document and template must also be safe for HTML. " and \ are encoded as \" and \\, control characters as \b, \t, \n, \f, \r or \u00xx, and <, >, &, U+2028, U+2029 and unpaired surrogates as \uxxxx with lowercase hex digits. Valid surrogate pairs and all other @@ -651,19 +691,29 @@ Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script - blocks, or standalone JavaScript source. In HTML script blocks, additional hex - escapes prevent encoded fragments from completing </script, <!--, or --> - tokens across trusted boundaries; hyphen uses \x2d. + blocks, or standalone JavaScript source. Additional escapes are always applied so + nonempty encoded fragments cannot complete </script, <script, <!--, or --> across trusted + boundaries in an HTML script element. Most use hex escapes; slash uses \/ and + hyphen uses \x2d. The output can be substantially longer than the original text. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScript @@ -677,17 +727,26 @@ Encodes a JavaScript string in an HTML event attribute (such as onclick). Not safe in HTML script blocks. Uses the same encoding as forJavaScript except that slash, hyphen, space, !, <, >, and both cases of C, I, P, R, S, and T are not - escaped because these characters protect the outer HTML script context. + escaped; those additional escapes protect an enclosing HTML script element. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptAttribute @@ -703,14 +762,23 @@ backslash escapes. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptBlock @@ -727,14 +795,23 @@ are not escaped; double and single quotes use backslash escapes. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptSource @@ -751,7 +828,10 @@ Encodes for the contents of a JSON string literal (RFC 8259). The caller MUST provide the surrounding double quotation marks. Safe for JSON string values in a JSON document or in an HTML script element, - including script type="application/json". " and \ are encoded as \" + including script type="application/json". For HTML embedding, encode the complete + contents of each string value and member name, including any trusted text in it. + Do not join encoded fragments to unencoded string text or unfinished JSON escapes; + the remaining document and template must also be safe for HTML. " and \ are encoded as \" and \\, control characters as \b, \t, \n, \f, \r or \u00xx, and <, >, &, U+2028, U+2029 and unpaired surrogates as \uxxxx with lowercase hex digits. Valid surrogate pairs and all other diff --git a/jakarta/src/main/resources/META-INF/java-encoder.tld b/jakarta/src/main/resources/META-INF/java-encoder.tld index 5f8d32b..3886770 100644 --- a/jakarta/src/main/resources/META-INF/java-encoder.tld +++ b/jakarta/src/main/resources/META-INF/java-encoder.tld @@ -99,19 +99,29 @@ Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script - blocks, or standalone JavaScript source. In HTML script blocks, additional hex - escapes prevent encoded fragments from completing </script, <!--, or --> - tokens across trusted boundaries; hyphen uses \x2d. + blocks, or standalone JavaScript source. Additional escapes are always applied so + nonempty encoded fragments cannot complete </script, <script, <!--, or --> across trusted + boundaries in an HTML script element. Most use hex escapes; slash uses \/ and + hyphen uses \x2d. The output can be substantially longer than the original text. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScript @@ -131,7 +141,10 @@ Encodes for the contents of a JSON string literal (RFC 8259). The caller MUST provide the surrounding double quotation marks. Safe for JSON string values in a JSON document or in an HTML script element, - including script type="application/json". " and \ are encoded as \" + including script type="application/json". For HTML embedding, encode the complete + contents of each string value and member name, including any trusted text in it. + Do not join encoded fragments to unencoded string text or unfinished JSON escapes; + the remaining document and template must also be safe for HTML. " and \ are encoded as \" and \\, control characters as \b, \t, \n, \f, \r or \u00xx, and <, >, &, U+2028, U+2029 and unpaired surrogates as \uxxxx with lowercase hex digits. Valid surrogate pairs and all other @@ -469,19 +482,29 @@ Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script - blocks, or standalone JavaScript source. In HTML script blocks, additional hex - escapes prevent encoded fragments from completing </script, <!--, or --> - tokens across trusted boundaries; hyphen uses \x2d. + blocks, or standalone JavaScript source. Additional escapes are always applied so + nonempty encoded fragments cannot complete </script, <script, <!--, or --> across trusted + boundaries in an HTML script element. Most use hex escapes; slash uses \/ and + hyphen uses \x2d. The output can be substantially longer than the original text. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScript @@ -495,7 +518,10 @@ Encodes for the contents of a JSON string literal (RFC 8259). The caller MUST provide the surrounding double quotation marks. Safe for JSON string values in a JSON document or in an HTML script element, - including script type="application/json". " and \ are encoded as \" + including script type="application/json". For HTML embedding, encode the complete + contents of each string value and member name, including any trusted text in it. + Do not join encoded fragments to unencoded string text or unfinished JSON escapes; + the remaining document and template must also be safe for HTML. " and \ are encoded as \" and \\, control characters as \b, \t, \n, \f, \r or \u00xx, and <, >, &, U+2028, U+2029 and unpaired surrogates as \uxxxx with lowercase hex digits. Valid surrogate pairs and all other diff --git a/jsp/src/main/resources/META-INF/java-encoder-advanced.tld b/jsp/src/main/resources/META-INF/java-encoder-advanced.tld index 355abc9..2aed81e 100644 --- a/jsp/src/main/resources/META-INF/java-encoder-advanced.tld +++ b/jsp/src/main/resources/META-INF/java-encoder-advanced.tld @@ -113,19 +113,29 @@ Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script - blocks, or standalone JavaScript source. In HTML script blocks, additional hex - escapes prevent encoded fragments from completing </script, <!--, or --> - tokens across trusted boundaries; hyphen uses \x2d. + blocks, or standalone JavaScript source. Additional escapes are always applied so + nonempty encoded fragments cannot complete </script, <script, <!--, or --> across trusted + boundaries in an HTML script element. Most use hex escapes; slash uses \/ and + hyphen uses \x2d. The output can be substantially longer than the original text. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScript @@ -145,17 +155,26 @@ Encodes a JavaScript string in an HTML event attribute (such as onclick). Not safe in HTML script blocks. Uses the same encoding as forJavaScript except that slash, hyphen, space, !, <, >, and both cases of C, I, P, R, S, and T are not - escaped because these characters protect the outer HTML script context. + escaped; those additional escapes protect an enclosing HTML script element. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptAttribute @@ -177,14 +196,23 @@ backslash escapes. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptBlock @@ -207,14 +235,23 @@ are not escaped; double and single quotes use backslash escapes. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptSource @@ -234,7 +271,10 @@ Encodes for the contents of a JSON string literal (RFC 8259). The caller MUST provide the surrounding double quotation marks. Safe for JSON string values in a JSON document or in an HTML script element, - including script type="application/json". " and \ are encoded as \" + including script type="application/json". For HTML embedding, encode the complete + contents of each string value and member name, including any trusted text in it. + Do not join encoded fragments to unencoded string text or unfinished JSON escapes; + the remaining document and template must also be safe for HTML. " and \ are encoded as \" and \\, control characters as \b, \t, \n, \f, \r or \u00xx, and <, >, &, U+2028, U+2029 and unpaired surrogates as \uxxxx with lowercase hex digits. Valid surrogate pairs and all other @@ -651,19 +691,29 @@ Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script - blocks, or standalone JavaScript source. In HTML script blocks, additional hex - escapes prevent encoded fragments from completing </script, <!--, or --> - tokens across trusted boundaries; hyphen uses \x2d. + blocks, or standalone JavaScript source. Additional escapes are always applied so + nonempty encoded fragments cannot complete </script, <script, <!--, or --> across trusted + boundaries in an HTML script element. Most use hex escapes; slash uses \/ and + hyphen uses \x2d. The output can be substantially longer than the original text. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScript @@ -677,17 +727,26 @@ Encodes a JavaScript string in an HTML event attribute (such as onclick). Not safe in HTML script blocks. Uses the same encoding as forJavaScript except that slash, hyphen, space, !, <, >, and both cases of C, I, P, R, S, and T are not - escaped because these characters protect the outer HTML script context. + escaped; those additional escapes protect an enclosing HTML script element. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptAttribute @@ -703,14 +762,23 @@ backslash escapes. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptBlock @@ -727,14 +795,23 @@ are not escaped; double and single quotes use backslash escapes. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScriptSource @@ -751,7 +828,10 @@ Encodes for the contents of a JSON string literal (RFC 8259). The caller MUST provide the surrounding double quotation marks. Safe for JSON string values in a JSON document or in an HTML script element, - including script type="application/json". " and \ are encoded as \" + including script type="application/json". For HTML embedding, encode the complete + contents of each string value and member name, including any trusted text in it. + Do not join encoded fragments to unencoded string text or unfinished JSON escapes; + the remaining document and template must also be safe for HTML. " and \ are encoded as \" and \\, control characters as \b, \t, \n, \f, \r or \u00xx, and <, >, &, U+2028, U+2029 and unpaired surrogates as \uxxxx with lowercase hex digits. Valid surrogate pairs and all other diff --git a/jsp/src/main/resources/META-INF/java-encoder.tld b/jsp/src/main/resources/META-INF/java-encoder.tld index 8b850df..fd5ea9f 100644 --- a/jsp/src/main/resources/META-INF/java-encoder.tld +++ b/jsp/src/main/resources/META-INF/java-encoder.tld @@ -96,19 +96,29 @@ Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script - blocks, or standalone JavaScript source. In HTML script blocks, additional hex - escapes prevent encoded fragments from completing </script, <!--, or --> - tokens across trusted boundaries; hyphen uses \x2d. + blocks, or standalone JavaScript source. Additional escapes are always applied so + nonempty encoded fragments cannot complete </script, <script, <!--, or --> across trusted + boundaries in an HTML script element. Most use hex escapes; slash uses \/ and + hyphen uses \x2d. The output can be substantially longer than the original text. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScript @@ -128,7 +138,10 @@ Encodes for the contents of a JSON string literal (RFC 8259). The caller MUST provide the surrounding double quotation marks. Safe for JSON string values in a JSON document or in an HTML script element, - including script type="application/json". " and \ are encoded as \" + including script type="application/json". For HTML embedding, encode the complete + contents of each string value and member name, including any trusted text in it. + Do not join encoded fragments to unencoded string text or unfinished JSON escapes; + the remaining document and template must also be safe for HTML. " and \ are encoded as \" and \\, control characters as \b, \t, \n, \f, \r or \u00xx, and <, >, &, U+2028, U+2029 and unpaired surrogates as \uxxxx with lowercase hex digits. Valid surrogate pairs and all other @@ -466,19 +479,29 @@ Encodes a JavaScript string for HTML event attributes (such as onclick), HTML script - blocks, or standalone JavaScript source. In HTML script blocks, additional hex - escapes prevent encoded fragments from completing </script, <!--, or --> - tokens across trusted boundaries; hyphen uses \x2d. + blocks, or standalone JavaScript source. Additional escapes are always applied so + nonempty encoded fragments cannot complete </script, <script, <!--, or --> across trusted + boundaries in an HTML script element. Most use hex escapes; slash uses \/ and + hyphen uses \x2d. The output can be substantially longer than the original text. Caller must supply single (') or double (") quotation marks, or backticks (`) for an ordinary (untagged) template literal. Insert encoded output into literal text, - not a ${...} expression. Dollar sign ($), backtick, and opening brace ({) are encoded + not a ${...} expression or where it can continue or extend a JavaScript escape + sequence, including a numeric escape such as \0 before an input digit. + The surrounding template must keep the insertion in its intended context; + encoding cannot repair an already-started HTML end tag such as </script followed + by a space, or dangerous trusted text joined around empty input. + Where event attributes are supported, quote the HTML attribute value too and do not + continue an HTML character reference begun by trusted text, such as an unencoded &. + Encode the complete string value, including trusted text, when possible. + Dollar sign ($), backtick, and opening brace ({) are encoded as \x24, \x60, and \x7b. Escaping { also prevents input after a trusted $ from completing ${...}. DEL and C1 controls (U+007F to U+009F) use \xNN escapes. Unpaired UTF-16 surrogates use \uXXXX escapes; valid surrogate pairs remain unescaped. Tagged templates (including String.raw) are unsupported: tags can observe raw escapes or interpret another language. This is not a JSON encoder; use a JSON serializer for - JSON. Do not use in javascript: or data: URLs, where URL decoding introduces a separate + complete documents. JSON embedded in HTML also needs HTML-safe serialization; see forJson. + Do not use in javascript: or data: URLs, where URL decoding introduces a separate parsing context. forJavaScript @@ -492,7 +515,10 @@ Encodes for the contents of a JSON string literal (RFC 8259). The caller MUST provide the surrounding double quotation marks. Safe for JSON string values in a JSON document or in an HTML script element, - including script type="application/json". " and \ are encoded as \" + including script type="application/json". For HTML embedding, encode the complete + contents of each string value and member name, including any trusted text in it. + Do not join encoded fragments to unencoded string text or unfinished JSON escapes; + the remaining document and template must also be safe for HTML. " and \ are encoded as \" and \\, control characters as \b, \t, \n, \f, \r or \u00xx, and <, >, &, U+2028, U+2029 and unpaired surrogates as \uxxxx with lowercase hex digits. Valid surrogate pairs and all other