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.
@@ -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 "\"" and "\&39;").
+ * escapes to "\"" and "\'").
*/
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 ". To do so we escape "/" as
+ // "". To do so we escape "/" as
// "\/" and hex-escape every other ASCII character that could form
// part of an HTML script delimiter. This prevents
- // any non-empty encoded substring from completing "" with adjacent trusted literal text. Other ASCII
+ // the encoding of any nonempty value from completing "" with adjacent trusted literal text. Other ASCII
// whitespace already uses JavaScript escapes in every mode.
// A JavaScript backslash escape would not prevent the exploits on
// "" and "`; 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 ``. 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