It is a well-known security best practice to validate user provided input before accepting it for further processing. There are a lot of resources in particular for web application developers on how to sanitize user provided input, how injection attacks like SQL injection or LDAP injection work, and what a cross-site scripting attacks is. A very good resource is the OWASP project, with their overview on data validation and their input validation cheat sheet.
Most guides around input validation focus on how to properly validate the syntax of the submitted data. While this is a very important step, it is also important to keep the underlying business logic in mind and consider how the semantics of the user provided input could compromise the underlying business logic.
Today, I came across a security hole that emerged although the application was correctly validating the syntax of the user provided data. However, the data sanitation mechanism did not take into account how that data would be used in the downstream components, and what an attacker could do with a seemingly harmless email address.
The application in question provides services to a user, and allows the user as an extra gimmick to register a customized or “vanity” email address in the form of
firstname.lastname@example.org. The team made sure that the email address always has the correct syntax, and even used a standard validation library with a well-tested regular expression instead of crafting their own.
However, although the validation ensured that the submitted addresses are syntactically correct, the seemingly harmless input can lead to a significant security hole that can enable a major phising attack on the application.
In this application, an attacker could simply request a seemingly “trusted” email address such as
email@example.com, and then use that email address to exploit other users on the system. As an example on how this attack could work, an attacker could request an anonymous SSL certificate from a third party (such as “comodo free SSL”) using such a “trusted” email address. In this example, the third party (comodo) would validate the ownership of the domain by sending an email to one of several “trusted” email addresses, and then grant the attacker an SSL certificate if he can prove that he has access to such a “trusted” email address.
The attacker can then use that certificate to create a spoofed website (in this case:
www.service-name.com) and phish users’ data – and the users would find it very hard to even notice the attack, because the SSL certificate from comodo (“trusted by 99.9% of browsers”) would be valid and actually be made out to the original server name!
To prevent this form of attack, the service in question would have to ensure that specific, usually “trusted” email addresses such as
firstname.lastname@example.org would not be available for a user to register.
In the case of comodo, the list of “trusted” email addresses available to choose from for domain ownership validation includes:
It is of course a really good idea to extend this list of prohibited addresses in the application with other addresses that are commonly abused for phising, including (but not limited to):
In this specific example, the connection between the potentially malicious user input and usage of this input in the business logic is fairly straight forward. However, this is often not the case, which makes it really necessary to keep downstream components and their business logic in mind when doing input validation.