Skip to content

Reduce unnecessary JavaScript letter escaping while preserving boundary safety - #247

Merged
jmanico merged 3 commits into
mainfrom
fix/issue-243-script-letter-escaping
Oct 18, 2026
Merged

jmanico merged 3 commits into
mainfrom
fix/issue-243-script-letter-escaping

Conversation

@jmanico

@jmanico jmanico commented Oct 17, 2026 •

Copy link
Copy Markdown
Member

Change

Addresses #243, including the latest comment about whitespace and escaping <. forJavaScript and forJavaScriptBlock leave interior script-name letters readable and escape such a letter only when it is the final input character. Punctuation and whitespace escapes remain.

Input Output
http://google.com http:\/\/google.com
script scrip\x74
csript csrip\x74
i \x69
scripture scripture

HTML does not remove whitespace inside tag names. Escaping < addresses the HTML tag delimiter concern for a complete encoded string, alongside necessary JavaScript escapes. It cannot protect a fragment whose trusted prefix supplies <. The terminal escape retains the documented fragment protection. This rule is conservative, not minimal; csript and cat still receive a terminal escape. Attribute-only and source modes are unchanged.

Streaming retains one undecidable trailing letter. EncodedWriter.flush() safely emits a pending script letter or high surrogate before flushing the wrapped writer. Explicit flushes can add escapes while preserving JavaScript UTF-16 values; ordinary chunking remains byte-identical to whole-value encoding. General/block callers must flush before writing directly to the wrapped writer. Low-level callers must retain unread input after UNDERFLOW and supply more input or mark end-of-input.

Compatibility

No public API, Java 8 requirement, dependency, module, bundle, or servlet-namespace change. Emitted bytes change, and the guarantee is refined from prohibiting literal </script substrings to preventing recognized HTML tokens. Longer names such as </scripture> remain harmless. Existing insertion preconditions apply. Review snapshots, signatures, and cache keys. Recommend 1.6.0; this PR retains the development version and does not publish a release.

Validation and review

Final revision: da8b7a0d298c952aee9064f67dec75e0ab16a32f.

  • Final clean JDK 17 reactor: passed, including 1,866 core unit tests, 218 per adapter, coverage/style/Javadocs/API and packaged engine checks.
  • Python repository tests: 36 passed; compatibility tests: 17 passed; source/TLD parity passed. Packaged Java 17 consumers passed locally.
  • Existing implementation: all 12 actual-Chrome tests passed, covering 355,372 fixtures including unsafe controls. Follow-up changes are documentation only.
  • Focused latest-comment check: 36 Chrome 155 cases passed for whitespace, tag-name controls, whole-value < escaping and fragment composition.
  • Final GitHub required gates passed: Java CI (including Docker/browser/WAR), packaged consumers on Java 8/11/17/21/25 and Java 8 tests, and Java/Actions/Python CodeQL.
  • Model-assisted implementation review followed MODELS.md using Astra, Sol, Opus, Mythos and Sonnet. Daybreak eligibility was unavailable; no Daybreak review is claimed. Reviews supplement maintainer review, not replace it.
  • A low-priority measured streaming cost remains: after a pending script letter, a long run of script letters uses the leftover buffer repeatedly. A local 1 MiB case measured roughly 4.3x the direct-write time, with linear work and bounded buffer memory. No general performance improvement is claimed.

Jim Manico explicitly authorized the existing audit-visible PR-only review bypass for this PR after review and required CI success. No required CI/security control is bypassed. Release signing and publication remain separate gates.

  • Scoped change; existing notices preserved.
  • Context documentation, Javadocs, TLDs and changelog updated.
  • No credentials or undisclosed vulnerability evidence included.

Comment thread core/src/main/java/org/owasp/encoder/JavaScriptEncoder.java

@arpadf78 arpadf78 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one comment

@jmanico
jmanico marked this pull request as ready for review October 18, 2026 17:26
@jmanico
jmanico requested a review from jeremylong as a code owner October 18, 2026 17:26
@jmanico
jmanico merged commit 300ef20 into main Oct 18, 2026
18 checks passed
@jmanico jmanico mentioned this pull request Oct 18, 2026
3 tasks done
@jmanico
jmanico deleted the fix/issue-243-script-letter-escaping branch October 18, 2026 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants