Skip to content

Apply the IDNA Bidi Rule to every label of a Bidi domain - #188

Merged
JoshData merged 2 commits into
JoshData:mainfrom
Keerthana-64:idna-bidi-all-labels
Nov 7, 2026
Merged

JoshData merged 2 commits into
JoshData:mainfrom
Keerthana-64:idna-bidi-all-labels

Conversation

@Keerthana-64

Copy link
Copy Markdown
Contributor

validate_email_domain_name leaves the RFC 5893 bidi rule to idna.alabel and idna.encode, but the idna package only checks labels that themselves contain right-to-left characters. RFC 5893 section 1.4 and UTS #46 CheckBidi apply the rule to every label once any label has an R, AL or AN character, so x@1.אב.com and x@אב.1.com were both accepted as different addresses (1.xn--4dbc.com vs xn--4dbc.1.com) even though the bidi algorithm displays both as x@1.בא.com, which is the spoofing case the rule exists to prevent. the check now runs idna.check_bidi(label, check_ltr=True) on each label of the decoded domain when any rtl character is present, so A-label input like me@1.xn--4dbrk0ce is covered too, while ordinary rtl domains such as example.ישראל and مثال.إختبار still validate. one existing length test had digit-led labels after a hebrew label, so those labels now start with a letter and the test still checks the length message.

The idna package checks the RFC 5893 Bidi Rule only on labels that
contain right-to-left characters. RFC 5893 and UTS JoshData#46 CheckBidi
require every label to satisfy it once any label does, so domains like
1.אב.com and אב.1.com were both accepted although they render
identically.
@JoshData

JoshData commented Nov 6, 2026

Copy link
Copy Markdown
Owner

Huh, interesting. Did you encounter this in the wild, or is this an AI-found hypothetical?

I'm pleasantly bemused that one of the cases RFC 5893 addresses is Yiddish (a personal interest as an Ashkenazi Jew).

Anyway, I'd be glad to include. But:

I would like to avoid the odd Unicode actually appearing in the source code, because that now makes the library's source code hard to read. I had to plug them into (my site) https://unicode.run (a, b) to see the difference.

Would you revise the PR so that the test uses the IDNA ASCII (1.xn--4dbc.com, xn--4dbc.1.com) primarily and put the Unicode in a code comment, and revise the code comment in the main part and the CHNAGELOG to include the IDNA ASCII?

I also wonder if this should be handled by the upstream idna library instead. A PR there might be of interest.

@Keerthana-64

Copy link
Copy Markdown
Contributor Author

Switched the tests to 1.xn--4dbc.com and xn--4dbc.1.com, with the Unicode forms only in a comment above them, and the comment in syntax.py and the CHANGELOG entry now lead with the IDNA ASCII too.

On upstream: agreed it would fit better in idna. Right now idna.encode only runs check_bidi on labels that contain RTL characters, so the cross-label part of RFC 5893 isn't covered there. Raising it with them makes sense, but even if they change it, keeping the check here means it works regardless of which idna version is installed.

@JoshData
JoshData merged commit 8d1fbd2 into JoshData:main Nov 7, 2026
6 checks passed
@JoshData

JoshData commented Nov 7, 2026

Copy link
Copy Markdown
Owner

TY!

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