Repository navigation
Decide whether strict base64url belongs in this output-encoding library #149
Description
Reviewed 2026-09-25 (America/Los_Angeles) against main at bd249f5. Execution order and cross-issue ownership: #169. Batch 06.
This scope replaces the dated implementation prescriptions in the original report and earlier comments; linked historical evidence remains useful but must be rechecked before implementation.
Review disposition
The proposal delegates transport encoding to Java 8's Base64 API and proposes canonical decoding. No submitted implementation is present and no security regression is established. Its decoding/canonicalization surface conflicts with this library's documented output-encoding scope, so resolve that product/API decision before adding public methods or tag bindings.
- Record whether to reject, document JDK use, or accept a narrowly justified utility. Base64url is transport encoding, not XSS prevention, validation, authentication, encryption or token-signature verification.
- If accepted, specify byte/String types, canonical padding policy, null/error contracts, strict UTF-8 decoding and malformed UTF-16 handling for String encoding. Default UTF-8 replacement can silently map different Java strings to the same bytes; choose/reject explicitly.
- Define rejection of nonalphabet/whitespace, invalid lengths, padding variants and nonzero trailing bits; errors must not echo input. Test canonical round trips and negative cases with the JDK codec as an implementation primitive, not a new codec implementation.
- Specify bounded allocation/Writer semantics for large input and explain why byte grouping does not fit the existing char-to-char Encoder/EncodedWriter contract.
- Decide whether view-layer exposure is useful; if accepted, encoding only, no decoder tags, and update facade/TLD/parity tests deliberately rather than weakening Guard facade mappings and JSP/Jakarta parity #167's invariants.
- Document output-context restrictions and version the new API deliberately. Leave ESAPI delegates unchanged.
Implementation is deferred pending this explicit decision. #142/#128 own the larger scope/versioning policy. Deferral is not evidence that 1.5's backlog gate is complete.
Activity
Akhil-1527 commentedon Sep 26, 2026
Hi, I'd like to work on this one. I'd follow the proposal in the issue: a new
org.owasp.encoder.Base64Urlclass built onjava.util.Base64, unpadded output as the canonical form, and a strict decoder that only accepts input that re-encodes to the same string, with an error that doesn't echo the input.Encode.forBase64Urlwould forward to it, and both taglibs would get theforBase64Urltag and EL function. I'd include the tests, Javadoc, README and CHANGELOG updates from the acceptance criteria. Could you assign it to me?[-]Add base64url encoding and strict decoding (RFC 4648 section 5)[/-][+]Decide whether strict base64url belongs in this output-encoding library[/+]jmanico commentedon Sep 26, 2026
Resolved by #190's base64url scope decision and JDK example. The disposition is not planned for Java Encoder: no
Base64Urlclass, facade method, tag or EL binding is accepted. Transport codecs and canonical decoding require byte/protocol contracts outside contextual output encoding.The record documents JDK 8+ byte encoding, protocol-specific padding, output-context restrictions, and why successful JDK decoding is not proof of canonical spelling. It also records strict Unicode/error/resource-limit considerations and why byte grouping does not fit Encoder/EncodedWriter. These are boundaries for applications or a future separate proposal, not an accepted decoder specification. Existing ESAPI delegates remain unchanged. Conditional implementation/API/parity acceptance criteria are therefore not applicable.
The Java example compiled with
--release 8and ran on JDK 17; padded/unpadded decoder behavior was checked. Sol and then Astra reviewed the final documentation without actionable findings; all 28 PR checks passed before merge.Thank you for offering to implement this. The requested assignment is not being made because the product decision is to keep this feature outside the library. No submitted implementation is being classified as vulnerable. A materially different future proposal needs a new, narrow justification before implementation work begins. #169 records completion; this is not 1.5 release approval.