Full Report
The email standard comes from a multitude of RFCs written over 50 years ago. Emails can have quoted values, comments, escapes, encodings, and much more. Many applications use email for user identification. This post discusses exploiting email parsers to bypass account isolation mechanisms that rely on the perceived domain of the email. While giving weird inputs to PostFix and Sendmail, they saw an interesting error message: DSN (delivery status notification) with an invalid host. In particular, oastify.com!collab\@example.com had caused this error to occur. UUCP is an ancient protocol that existed before the Internet and email, allowing messages to be sent between Unix systems. The exclamation mark is a separator between the domain and the user part of the email. This domain goes to oastify.com because of the UUCP support. We're getting somewhere! Doing similar things on Postfix gave them the output of collab%psres.net(@example.com via the ancient protocol source routes. Source routes allow you to chain servers together to send mail. This was sent to BOTH example.com and psres.net as a result. The key is that the ( is commenting out the domain part of the email which Postfix uses the local-part of the source route to send the email to an unexpected location. Regardless, all of this made Gareth want to dive deeper into email parsing. Encoded word is an email scheme that allows different characters to be used than what is provided. In encoded word, =? can be used to indicate the start of an encoded word. Next, you provide the charset, type of encoding within question marks and then the encoded data. Finally, the encoded word is ended with ?= in the email. For instance, [email protected] results in [email protected]. Upon testing this on several systems, they found that several websites using Ruby were accepting it. The library accepted utf-7 and several other charsets. Armed with all this knowledge, they began tackling real targets, such as GitHub, to see what they could uncover. The main goal was to use their ability to trick the email provider to domain to gain access to something that they shouldn't have access to. One problem with exploitation is the lack of feedback though. On GitHub, they played around with double quotes, encoding and such for a long time. Eventually, they noticed that encoded @ signs would be processed. Unfortunately, it was still failing because of the rest of the data following. So, they just added an extra encoded null byte to it, which cancelled the rest of the email data out. This allowed them to have an arbitrary trailing domain but have the email get sent to a user-controlled location. This allowed bypassing the IdP verification on GitHub. A similar thing was done on Zendesk. On GitLab, they were able to use encoded spaces to get an email sent to more than one user! By including =20 to encode the email, it would add a space between the emails. According to email standards, this is alright to do to send for multiple emails. The rest of the provided email was treated as the second email, even though the service itself only saw the second email for validation purposes. They found a similar exploit using > as well. They found that another library for email parsing supported Punnycode within the email. They used this trick within Joomla to get XSS by converting the domain character being rendered in the page from a domain to an opening style tag. From there, they leaked the CSRF token via XSS and got RCE via installing a malicious extension. Pretty neat! The end of the article has several other interesting attack vectors, like using double quotes to add optional fields into an email, like the ORCPT field. To protect against this, the article says to block all encoded-word related characters like =[?].+[?]=. Besides this, the domain of an email should not be fully trusted when it comes from an SSO provider. Great post on parser differentials, once again from Portswigger!
Analysis Summary
# Vulnerability: Email Parser Differentials and Encoded-Word Injection
## CVE Details
- **CVE ID**: Not explicitly cited in the context (Note: These findings often fall under specific bug bounty reports rather than a single CVE, though specific instances like the Joomla RCE may have individual identifiers).
- **CVSS Score**: Estimated 8.0 - 9.8 (High/Critical) depending on the target system (e.g., GitHub IdP bypass or Joomla RCE).
- **CWE**: CWE-436 (Interpretation Conflict), CWE-20 (Improper Input Validation), CWE-74 (Injection).
## Affected Systems
- **Products**: GitHub, GitLab, Zendesk, Joomla, Ruby-based web applications, Postfix, and Sendmail.
- **Versions**: Specific versions not provided; refers to generic library vulnerabilities (e.g., Ruby email parsing libraries).
- **Configurations**: Systems using email domains for identity verification (SSO/IdP), systems parsing RFC-compliant "Encoded-Word" syntax, or legacy mail transfer agents (MTAs) supporting UUCP/Source Routing.
## Vulnerability Description
The vulnerability arises from **parser differentials**—inconsistencies in how different components of a system (e.g., a web application vs. a mail server) interpret complex email address syntax defined in legacy RFCs. Key technical flaws include:
1. **Encoded-Word Abuse**: Using `=?charset?encoding?data?=` syntax to hide special characters (like `@`, spaces, or null bytes) from the application's validation logic, while the downstream mailer decodes and executes them.
2. **Legacy Protocol Support**: Exploit of UUCP (`!`) and Source Routing (`%`, `@`, `()`) syntax to redirect mail to unintended domains.
3. **Null Byte Injection**: Using encoded null bytes (`=00`) to truncate email strings, allowing an attacker to satisfy domain validation requirements while the actual mail is delivered to a different address.
4. **Delimiter Injection**: Using encoded spaces (`=20`) or angle brackets (`>`) to inject multiple recipients into a single email field.
## Exploitation
- **Status**: Exploited in the wild (via professional security research/Bug Bounty programs).
- **Complexity**: High (Requires deep knowledge of RFC parsing and specific library behaviors).
- **Attack Vector**: Network (Remote).
## Impact
- **Confidentiality**: High (Ability to bypass Identity Provider [IdP] verification and access unauthorized accounts).
- **Integrity**: High (Ability to perform RCE via XSS/CSRF, as seen in the Joomla example).
- **Availability**: Medium (Potential for mail flow disruption or account takeover).
## Remediation
### Patches
- Systems like GitHub, GitLab, and Zendesk have patched these specific parser inconsistencies following the research.
- Ensure all Ruby email libraries and CMS platforms (Joomla) are updated to their latest versions.
### Workarounds
- **Input Filtering**: Implement strict regex to block "Encoded-Word" syntax in email fields: `=[?].+[?]=`.
- **Zero Trust Domains**: Do not implicitly trust the domain part of an email address provided by an SSO/IdP without additional verification.
- **MTA Hardening**: Disable support for ancient protocols like UUCP and source routing in Postfix and Sendmail configurations.
## Detection
- **Indicators of Compromise**: Email addresses containing `=?`, `%`, `!`, or encoded characters like `=20` or `=00` in registration or SSO logs.
- **Detection methods**: Monitor for DSN (Delivery Status Notification) errors containing "invalid host" or unexpected routing paths in mail server logs.
## References
- **Vendor advisories**: PortSwigger Research (Gareth Heyes).
- **Relevant links**:
- hxxps[://]portswigger[.]net/research/abusing-email-parsers-with-character-encodings
- hxxps[://]github[.]com/advisories (Search for email parsing issues)