Skip to main content

Punycode

Convert Security

Synopsis

Converts between Unicode and Punycode (RFC 3492), either on a raw string or per domain label with the xn-- prefix.

Schema

- punycode:
field: <ident>
mode: <enum>
description: <text>
if: <script>
ignore_failure: <boolean>
ignore_missing: <boolean>
on_failure: <processor[]>
on_success: <processor[]>
tag: <string>
target_field: <ident>

Configuration

The following fields are used to define the processor:

FieldRequiredDefaultDescription
fieldY-Field containing the string to convert
modeY-encode, decode, domain_encode or domain_decode. Matched case-insensitively; any other value is an error
descriptionN-Explanatory note
ifN-Condition to run
ignore_failureNfalseSee Handling Failures
ignore_missingNfalseIf true, quietly exit if field doesn't exist
on_failureN-See Handling Failures
on_successN-See Handling Success
tagN-Identifier
disabledNfalseWhen true, the processor is skipped and the event continues to the next one. Lets you take a processor out of the path without removing its configuration
target_fieldNfieldField to store the result. Defaults to field, converting in place

Details

ModeOperation
encodePunycode-encode the whole string. No xn-- prefix is added
decodePunycode-decode the whole string. No xn-- prefix is expected
domain_encodeTreat the value as a domain and encode each label that is not already ASCII, prefixing each with xn--
domain_decodeTreat the value as a domain and decode each label that begins with xn--

The domain modes are the ones to use on a hostname. They split on the dot and convert label by label, so an ASCII label is left exactly as it is and only the labels that need converting are touched. The raw encode/decode modes operate on the entire string as one unit and are for a single label or an already-isolated component.

domain_encode and domain_decode also normalise the three alternative full-stop characters used in CJK text — , and — to an ASCII dot before splitting. A homograph domain that uses one of them therefore resolves to the same label structure as its ASCII counterpart, which is exactly the case this processor exists to make visible.

A conversion that fails yields an empty string rather than an error, so a downstream step should treat an empty result as "could not convert" rather than assuming a value is always produced.

Examples

Decoding an Internationalized Domain

Revealing what an xn-- hostname actually reads as...

{
"dns": {"question": {"name": "xn--80ak6aa92e.com"}}
}
- punycode:
field: dns.question.name
mode: domain_decode
target_field: dns.question.name_unicode

which is the form a homograph attack is spotted in:

{
"dns": {
"question": {
"name": "xn--80ak6aa92e.com",
"name_unicode": "аррӏе.com"
}
}
}

Encoding a Unicode Domain

Only the non-ASCII labels are converted...

{
"url": {"domain": "münchen.example.com"}
}
- punycode:
field: url.domain
mode: domain_encode
target_field: url.domain_ascii

leaving example and com untouched:

{
"url": {
"domain": "münchen.example.com",
"domain_ascii": "xn--mnchen-3ya.example.com"
}
}

A Single Label

The raw modes convert the whole string with no prefix handling...

{
"label": "münchen"
}
- punycode:
field: label
mode: encode
target_field: label_encoded

so the xn-- prefix is not added for you:

{
"label": "münchen",
"label_encoded": "mnchen-3ya"
}