Skip to content

HTTP Basic: opt-in UTF-8 credentials (RFC 7617), read token68 challenges - #1617

Merged
thboileau-git merged 6 commits into
2.6from
fix/basic-utf8-2.6
Nov 1, 2026
Merged

thboileau-git merged 6 commits into
2.6from
fix/basic-utf8-2.6

Conversation

@thboileau-git

@thboileau-git thboileau-git commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

The aim

Fixes #1455. Fixes #191.

  • HTTP Basic: the server always decodes the credentials as ISO-8859-1 and advertises charset="UTF-8" only if set by hand, so UTF-8 logins and passwords cannot work (RFC 7617 section 2.1).
  • WWW-Authenticate: Negotiate <base64>==, Basic realm="a": the = padding of a token68 (RFC 9110 section 11.2) made the reader throw, and the whole header was dropped.

The solution

Opt-in, disabled by default (no behavior change): with the system property org.restlet.engine.security.basic.utf8=true (HttpBasicHelper.UTF8_PROPERTY):

  • a Basic ChallengeAuthenticator advertises charset="UTF-8";
  • the server decodes the credentials as UTF-8, falling back to ISO-8859-1 if they are not valid UTF-8;
  • a ChallengeResponse built from a challenge request copies its charset, so the client encodes UTF-8.

Bug fixes:

  • ChallengeRequestReader reads a token68 ending with =.
  • The realm and charset parameters of a Basic challenge are matched case-insensitively (RFC 9110 section 11.2); Realm= used to give a null realm.

3.0 makes the UTF-8 behavior the default. Credentials are read at header parse time, before the authenticator is known, hence a global switch.

Reproduction

ChallengeRequestReader("Negotiate YIIabc==, Basic realm=\"a\"").readValues() is empty before the fix. For Basic: start the JVM with -Dorg.restlet.engine.security.basic.utf8=true and call with login zoë / password p€ss.

Check-list

  • PR size
    • Under 300 lines ✅
    • Can't be split without complicating the process even more
  • Tests
    • Added
  • Doc
    • Added (changes.md, Javadoc)
  • Reviewer
    • Asked for a review

🤖 Generated with Claude Code

thboileau and others added 6 commits October 31, 2026 21:21
- New opt-in, disabled by default: with the system property
  org.restlet.engine.security.basic.utf8=true a Basic challenge advertises
  charset="UTF-8", a server decodes the credentials as UTF-8 (falling back to
  ISO-8859-1) and a client answering such a challenge encodes UTF-8.
  Issue #1455.
- A WWW-Authenticate challenge made of a token68 ending with "=" (Negotiate)
  was dropped with the whole header. Issue #191.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
RFC 9110 section 11.2 makes auth-param names case-insensitive. "Realm=" was
ignored (null realm) and "Charset=" was not seen by the client.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Another test of the suite can leave a Restlet engine without the Basic
authenticator helper (seen on CI, depending on the test order): the new tests
now register a complete engine first.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@sonarqubecloud

sonarqubecloud Bot commented Nov 1, 2026

Copy link
Copy Markdown

@thboileau-git
thboileau-git merged commit 2c9ae7f into 2.6 Nov 1, 2026
3 checks passed
@thboileau-git
thboileau-git deleted the fix/basic-utf8-2.6 branch November 1, 2026 11:53
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