Cross-Site Scripting (XSS), Cross-Site Request Forgery (CSRF), SQL Injection and HTML Injection are security flaws that have been around for years. They are well-known vulnerabilities with well-known solutions. As we've seen in recent weeks, even well-established tech companies are not immune to these basic flaws:
I believe one of the reason these flaws are still present in new websites is due to the fact that their exploitation and consequences are not fully understood. Here are few misconceptions I have heard.
XSS is simply about popups
Proof-of-concept for XSS flaws often consists of showing a JavaScript alert popup being displayed. This is just for demonstration purposes. A successful XSS injection can insert any JavaScript into the page, which can, amongst other things:
SQL Injection is not only used to dump a database, or to login without valid user credentials. A lot of web applications, like Wordpress, store the site content into a database. If an attacker get write access to the database, he can insert malicious code which will then be rendered for all users.
Users are at fault for not being diligent
Another belief is that a user must click on link that contains the XSS, CSRF of HTML infection in order to be affected. Since the "bad" content is often shown in the URL the user clicks on, users should simply be more careful.
First, "bad" links can be hidden with a URL shortener, for example and users may not be aware were they will be redirected. Second, all attacks are not necessarily transient. Malicious content can be inserted by one user, or the attacker, and displayed to all other users via a persistent XSS or HTML Injection flaw. It is the responsibility of the webmaster to protect users. This responsibility should not be placed on each user.
A good denylist will do the trick
User input filtering is often performed by a denylist: allow anything, except a few dangerous strings. Unfortunately with HTML and JavaScript, there are too many ways to do the same things. Here are a couple of examples
Conditional comments
HTML comment should be safe, right? Wrong. Internet Explorer actually interprets the content of HTML comments called conditional comments. These 2 lines will make Internet Explorer load and execute JavaScript for evil.com:
Conditional comments for Internet Explorer also exist for Javascript:
XSS can hide anywhere
A XSS attack does not require the addition of a new script tag on a page. It can hide in a link, tag attributes, CSS, etc.
Encoding
Don't forget about HTML encoding, JavaScript encoding, JavaScript obfuscation, ASCII-7, UTF with null characters, etc.
It's pretty much impossible to get a comprehensive list of dangerous strings. Instead, a tight allowlist of authorized strings and/or characters should be used first, and only supplemented with a denylist as needed.
I hope that the high-profile attacks that happened recently will push web developers to pay more attention to the code injection vulnerabilities. Many programming frameworks include libraries and functions to take care of most of these issues. Hopefully they will be used everywhere user input is received and displayed. Don't ever trust external input!
-- Julien
- MySQL was compromised by SQL Injection
- Wordpress.com was compromised by an HTML Injection/Cross-Site Request Forgery
- Facebook was hit by a worm exploiting an XSS vulnerability
- Barracuda Networks was compromised by SQL Injection
- Twitter had an HTTP Response Splitting flaw
I believe one of the reason these flaws are still present in new websites is due to the fact that their exploitation and consequences are not fully understood. Here are few misconceptions I have heard.
XSS is simply about popups
Proof-of-concept for XSS flaws often consists of showing a JavaScript alert popup being displayed. This is just for demonstration purposes. A successful XSS injection can insert any JavaScript into the page, which can, amongst other things:
- steal user credentials (login, password, session, etc.) and other confidential information (credit card number, mailing address, etc.)
- hijack administrator sessions
- force the download of malicious executables
- run other types of code: Flash, Java, ActiveX, etc.
SQL Injection is not only used to dump a database, or to login without valid user credentials. A lot of web applications, like Wordpress, store the site content into a database. If an attacker get write access to the database, he can insert malicious code which will then be rendered for all users.
Users are at fault for not being diligent
Another belief is that a user must click on link that contains the XSS, CSRF of HTML infection in order to be affected. Since the "bad" content is often shown in the URL the user clicks on, users should simply be more careful.
First, "bad" links can be hidden with a URL shortener, for example and users may not be aware were they will be redirected. Second, all attacks are not necessarily transient. Malicious content can be inserted by one user, or the attacker, and displayed to all other users via a persistent XSS or HTML Injection flaw. It is the responsibility of the webmaster to protect users. This responsibility should not be placed on each user.
A good denylist will do the trick
User input filtering is often performed by a denylist: allow anything, except a few dangerous strings. Unfortunately with HTML and JavaScript, there are too many ways to do the same things. Here are a couple of examples
Conditional comments
HTML comment should be safe, right? Wrong. Internet Explorer actually interprets the content of HTML comments called conditional comments. These 2 lines will make Internet Explorer load and execute JavaScript for evil.com:
These lines are not interpreted as comments by IE |
document.write is executed by Internet Explorer |
XSS can hide anywhere
A XSS attack does not require the addition of a new script tag on a page. It can hide in a link, tag attributes, CSS, etc.
Examples of harmful JavaScript/HTML insertion |
Don't forget about HTML encoding, JavaScript encoding, JavaScript obfuscation, ASCII-7, UTF with null characters, etc.
Some examples of encoding |
It's pretty much impossible to get a comprehensive list of dangerous strings. Instead, a tight allowlist of authorized strings and/or characters should be used first, and only supplemented with a denylist as needed.
I hope that the high-profile attacks that happened recently will push web developers to pay more attention to the code injection vulnerabilities. Many programming frameworks include libraries and functions to take care of most of these issues. Hopefully they will be used everywhere user input is received and displayed. Don't ever trust external input!
-- Julien