Защита Web-приложений. Учебное пособие
.pdf
Проблема с этим кодом в том, что он безопасен, но не надежен. Если условия изменятся, то код больше не будет функционировать так, как должен.
|
Рис. 5. Проверка диапазона |
|
|
||
Следующий |
пример RangeCheck2.html |
повышает |
|
||
надежность |
кода, |
привязывая |
проверку |
диапазона |
к |
атрибутам min и max тега <input>: |
|
|
|
||
<!DOCTYPE html> <html>
<head>
<title>Performing a Range Check</title>
<script language="javascript"> function testValue()
{
inputObj = document.getElementById("Data"); value = inputObj.value;
if (value == "")
{
alert("Please type a number!"); return;
}
if ((value < inputObj.getAttribute("min")) || (value > inputObj.getAttribute("max")))
{
alert("Value must be between 0 and 5!");
}
else
{
alert("Value = " + value);
}
}
</script>
</head>
<body>
<h1>Performing a Range Check</h1>
41
<input id="Data" type="number" value="0" min=0 max=5 /><br />
<button id="Test" onclick="testValue()"> Test </button>
</body>
</html>
Основные проверки работают как прежде. Однако, если |
|
||||||||
кто-то |
решит |
изменить |
минимальное |
и |
максимальное |
||||
значения, принятые тегом <input>, код автоматически ответит |
|
||||||||
изменением условий проверки. Точек отказа в этом примере |
|
||||||||
меньше. |
|
|
|
|
|
|
|
|
|
Однако |
чтобы |
получить |
, |
кодкоторый |
является |
|
|||
одновременно |
безопасным |
и |
надежным, придется |
|
|||||
пожертвовать |
скоростью работы приложения. Обратите |
|
|||||||
внимание |
на |
количество |
дополнительных |
строк кода |
во |
||||
втором примере и увеличенное количество вызовов функций. |
|
||||||||
Вероятно, |
вы |
не |
заметите разницы в |
|
скорости |
этого |
|||
конкретного примера, но когда вы начнете |
добавлять эти |
||||||||
виды проверок для всего приложения, вы увидите серьезное |
|
||||||||
снижение |
скорости. |
Код |
является |
более |
|
надежным |
и |
||
безопасным, но пользователь вашего приложения может быть |
|
||||||||
не доволен скоростью работы. |
|
|
|
|
|
|
|||
2.3. Проблема использования сторонних решений |
|
||||||||
Использование |
сторонних |
решений |
|
повлияет |
на |
||||
надежность вашего приложения. Вы полагаетесь на код, написанный кем-то другим, поэтому этот код также будет является частью расчета надежности. Далее рассмотрим проблемы, которые необходимо учитывать при работе с сторонним кодом.
Работа с внешними библиотеками
Внешние библиотеки создают ряд интересных проблем с надежностью. Наиболее важная проблема заключается в том, что приложение обычно загружает копию библиотеки каждый раз, когда начинает работать. Если вы продолжаете работу приложения, этот процесс происходит не часто, но
большинство веб-приложений запускаются в клиентской
42
системе, а это значит, что клиент должен будет загружать
библиотеку |
каждый |
,разкогда |
запускает |
приложение. |
|||||
Скорость |
работы |
|
становится |
медленнее |
из-за |
загрузки |
|||
библиотеки. Однако приложение может даже не запуститься, |
|||||||||
если |
что-то |
мешает |
успешной |
.загрузкеНапример, |
|||||
рассмотрим |
использование |
пользовательского |
интерфейса |
||||||
jQuery |
для |
создания |
эффекта«аккордеона» (выпадающий |
||||||
список), подобного показанному на рис. 6. |
|
|
|
||||||
|
Рис. 6. Выпадающий список |
|
|
|||
Этот |
пример |
даже |
не |
запустится, если |
файлы |
|
библиотеки, от которых он зависит, по какой-то причине |
||||||
станут недоступными. Следующий код (находится в файле |
||||||
Accordian.html) появляется |
в |
заголовке |
для |
создания |
||
необходимого подключения: |
|
|
|
|
||
<script src="https://code.jquery.com/jquery-latest.js">
</script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.js">
</script>
<link rel="stylesheet" href="https://code.jquery.com/ui/ 1.9.2/themes/base/ jquery-ui.css” />
Если какой-либо из трех файлов, показанных в этом
примере, отсутствует, приложение |
не запустится. В этом |
||
примере |
также показаны два |
разных подхода к выбору |
|
библиотек. |
Обратите |
внимание, |
что библиотека jQuery |
43
использует последнюю версию, а это означает, что вы автоматически получаете исправления ошибок и другие
обновления. |
Однако |
|
библиотека |
|
пользовательского |
||||
интерфейса jQuery (и связанный с ней файл CSS) полагаются |
|
||||||||
на конкретную версию библиотеки. В этом случае |
вы |
не |
|||||||
будете |
получать |
обновления, но |
можете |
получить |
|||||
исправления |
ошибок, |
которые могут |
привести |
к сбою |
|||||
приложения, если вы уже включили |
обходной |
код |
для |
||||||
решения проблемы. |
|
|
|
|
|
|
|||
Один |
|
из |
лучших |
способов |
повысить |
надежность |
|||
использования |
|
внешней |
библиотеки– |
это |
загрузить |
||||
библиотеку на локальные диски и использовать эту копию, а |
|
||||||||
не копию |
на |
сайте поставщика. Эта стратегия |
гарантирует, |
|
|||||
что у вас всегда будет одна и та же версия библиотеки и меньше шансов, что библиотека не будет доступна для
использования. |
Конечно, |
вам |
понадобится |
место |
на |
||||
локальном жестком диске для хранения библиотеки, но |
|
||||||||
увеличение |
|
использования |
|
локальных |
ресурсов– это |
|
|||
небольшая цена за стабильность, которую вы получаете. |
|
||||||||
Как |
и |
во |
всем |
|
остальном, существует |
цена |
за |
||
использование локализованной копии библиотеки. Самым |
|
||||||||
важным из этих вопросов является отсутствие обновлений. |
|||||||||
Большинство |
поставщиков |
|
предоставляют |
обновления |
|||||
относительно часто, которые включают исправления ошибок, |
|
||||||||
улучшения |
в |
надежности |
и |
улучшения |
скорости. Конечно, |
|
|||
библиотека обычно содержит и новые функции. Чтобы добиться повышения надежности, вы отказываетесь от некоторых потенциальных улучшений безопасности и других обновлений, которые вы действительно хотите использовать в своем приложении.
Срединный подход заключается в том, чтобы загружать библиотеку локально, отслеживать улучшения в обновлениях и рассчитывать время обновления ваших приложений в соответствии с необходимыми обновлениями безопасности и
функций в большинстве используемых вами библиотек. Это |
|
||||
будет |
означать |
выполнение |
обновлений |
по |
вашему |
расписанию, а не |
по расписании |
поставщика. Хотя |
эта |
|
|
44
альтернатива может показаться идеальным решением, это не так. Хакеры часто полагаются на эксплойты нулевого дня,
чтобы нанести максимальный вред наибольшему числу
приложений. |
Поскольку |
ваше |
приложение |
не |
будет |
|
автоматически получать необходимые обновления, вы по- |
|
|||||
прежнему сталкиваетесь с |
возможностью |
разрушительной |
||||
атаки нулевого дня. |
|
|
|
|
|
|
Работа с внешними API |
|
|
|
|
|
|
Внешние |
API предоставляют |
средства |
для |
доступа |
к |
|
данным и другим ресурсам с использованием внешнего источника. API обычно представляет собой набор классов, которые вы создаете в качестве объектов и используете для
выполнения |
вызовов. |
Код |
не выполняется |
в клиентской |
|||
системе. Скорее, он |
выполняется |
как |
удаленный |
вызов |
|||
процедуры (RPC) вне процесса на сервере. Создание ссылки |
|||||||
на API очень похоже на создание ссылки на библиотеку, за |
|||||||
исключением |
того, что вы |
обычно |
должны |
предоставить |
|||
какой-то ключ для получения доступа, как показано здесь для |
|||||||
файла GoogleAPI.html: |
|
|
|
|
|
|
|
<head> |
|
|
|
|
|
|
|
<script type=”text/javascript” |
|
js?key=Your |
Key |
||||
src=”https://maps.googleapis.com/maps/api/ |
|||||||
Here&sensor=false”> |
|
|
|
|
|
|
|
Запрос требует, чтобы клиент создал запрос и отправил его на сервер. При работе с Google API необходимо указать такие элементы, как долгота и широта интерфейса, а также предпочтительный тип карты. API фактически записывает данные непосредственно в местоположение приложения, предоставленное как часть запроса, как показано здесь:
//This function actually displays the map on
//screen. Function GetMap()
{
// Create a list of arguments to send to Google. Var MapOptions =
{
center: new google.maps.LatLng( Latitude.spinner(“value”), Longitude.spinner(“value”)), zoom: 8,
mapTypeId: google.maps.MapTypeId.ROADMAP
45
}
//Provide the location to place the map and the
//map options to Google.
Var map = new google.maps.Map( document.getElementById(“MapCanvas”), MapOptions);
};
|
Использование |
внешних API-интерфейсов |
позволяет |
|
||||||||||
использовать чужой код с меньшим количеством проблем |
||||||||||||||
безопасности и, возможно, с меньшим количеством проблем |
|
|||||||||||||
со |
скоростью (в |
зависимости |
от |
,тогочто |
|
быстрее: |
|
|||||||
запрашивать ли данные или загружать код). Однако с точки |
|
|||||||||||||
зрения надежности внешниеAPI представляют все виды |
|
|||||||||||||
рисков. Любое |
|
прерывание |
соединения |
означает, о |
|
|||||||||
приложение перестает работать. Конечно, для разработчика |
|
|||||||||||||
относительно легко создать код, который компенсирует эту |
|
|||||||||||||
проблему |
и |
представляет |
сообщение |
для |
пользователя. |
|||||||||
Сложнее |
исправить |
проблему |
медленного |
|
соединения, |
|||||||||
искажения данных и другие проблемы, которые |
|
могут |
|
|||||||||||
отражать состояние соединения. |
|
|
|
|
|
|
|
|
||||||
|
Работа с фреймворками |
|
|
|
|
|
|
|
|
|
||||
|
Фреймворки представляют собой золотую середину |
|||||||||||||
надежности между библиотеками иAPI. По большей части |
|
|||||||||||||
фреймворки представляют собой сжатый .кодОдним из |
|
|||||||||||||
наиболее |
часто |
|
используемых |
|
фреймворков |
является |
||||||||
MooTools (рис. 7). Однако |
существует |
множество |
других |
|
||||||||||
платформ, и вам нужно найти подходящую для ваших нужд. |
|
|||||||||||||
В |
большинстве |
|
случаев |
фреймворки |
могут |
работать |
на |
|||||||
сервере, клиенте или их комбинации. В зависимости от того, |
|
|||||||||||||
как вы используете платформу, вы можете увидеть те же |
|
|||||||||||||
проблемы |
с |
|
надежностью, которые |
|
встречаются |
в |
||||||||
библиотеках, API или их комбинации. |
|
|
|
|
|
|
|
|||||||
|
Вы можете выполнять многие из тех же задач, что и при |
|
||||||||||||
использовании |
библиотек. Например, |
вы |
можете |
создать |
|
|||||||||
версию |
примера «аккордеона», |
используя |
MooTools. |
|
||||||||||
Следующий |
код |
значительно |
упрощен, о |
он |
помогает |
|
||||||||
понять: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
46
|
|
Рис. 7. Использование MooTools |
|
|
|
|
|||||
|
Микросервисы |
|
|
|
|
|
|
|
|
|
|
|
Микросервисы |
– |
это |
небольшие |
|
самодостаточные |
|
||||
программы |
или |
|
сервисы, которые |
выполняют |
одну |
|
|||||
маленькую |
задачу. |
Они работают совместно с другими |
|
||||||||
программами (сервисами). |
|
|
|
|
|
|
|
||||
|
Современные |
тенденции |
развития |
|
веб-архитектуры |
|
|||||
ведут |
к |
постоянному |
усложнению. При |
|
разработке, |
|
|||||
улучшении |
и |
дальнейшем |
развитии |
|
успешного- |
веб |
|||||
приложения наступает такой момент, что становится тяжело |
|
||||||||||
поддерживать существующий код, тяжело внедрять новые |
|
||||||||||
решения. И |
тут |
архитектор |
|
задумывается |
о |
разделении |
|
||||
проекта на небольшие части. Это и есть первый шаг к |
|
||||||||||
микросервисам. |
|
|
|
|
|
|
|
|
|
||
|
Стиль |
разработки |
микросервисов– |
это |
|
подход, при |
|
||||
котором единое приложение строится, как набор небольших |
|
||||||||||
сервисов. При этом каждый из них работает в собственном |
|
||||||||||
окружении и общается с остальными. Практически это могут |
|
||||||||||
быть |
крон-задачи, |
небольшие |
|
сетевые |
|
демоны, HTTP- |
|
||||
сервисы. Сами по себе эти сервисы могут быть написаны на |
|
||||||||||
разных языках и использовать разные технологии хранения |
|
||||||||||
данных. |
|
|
|
|
|
|
|
|
|
|
|
|
Основные преимущества микросервисной архитектуры: |
|
|||||||||
· автономные сервисы позволяют быстрее |
локализовать |
|
|||||||||
|
неисправность; |
|
|
|
|
|
|
|
|
|
|
47
· скорость |
разработки |
маленького |
, проектагде |
||
минимальная связанность компонент выше; |
|
||||
· масштабирование проще; |
|
|
|
||
· технологическая |
разнородность |
позволяет |
внедрять |
||
сервис с использованием тех технологий, которые наилучшим образом подходят для решения данной подзадачи;
·лучшая устойчивость – в маленьких проектах;
·простота развертывания;
·быстродействие, простой маленький проект дает более
быстрый отклик, чем монструозное приложение.
Однако в некоторых отношениях микросервисы также отличаются от API просто потому, что они меньше и больше адаптированы. Имея это в виду, вот некоторые вопросы надежности, которые необходимо учитывать при работе с микросервисами:
· использование |
большего количества |
микросервисов |
из |
|||||||
разных источников увеличивает вероятность потери |
||||||||||
соединения и снижает надежность приложения; |
|
|
||||||||
· выбор |
микросервисов, |
которые |
|
действительно |
||||||
оптимизируют предоставляемый сервис для конкретной |
|
|||||||||
потребности, увеличит надежность приложения, так как |
|
|||||||||
риск возникновения серьезных ошибок меньше; |
|
|
||||||||
· использование |
|
единого |
|
интерфейса |
для |
вызовов |
||||
микросервисов |
|
уменьшает |
потенциальные |
ошибки |
||||||
кодирования, повышая надежность приложений; |
|
|
||||||||
· наличие |
более |
одного |
|
источни, |
каоторый |
может |
||||
выполнять одну и ту же услугу, уменьшает количество |
|
|||||||||
отдельных |
|
точек |
отказа, повышая |
надежность |
||||||
приложения; |
|
|
|
|
|
|
|
|
|
|
· сохранение |
сервисов небольшого |
размера |
означает, что |
|
||||||
потеря одного сервиса не означает, что все сервисы становятся недоступными, как это было бы при использовании API, поэтому надежность в этом случае также выше.
48
|
|
|
|
2.4. Объединение библиотек |
|
|
|
|
||||
Мы не будем пытаться убедить вас в ценности |
|
|||||||||||
использования библиотек. Вы, вероятно, уже познали все их |
|
|||||||||||
преимущества для себя. Однако вы, возможно, не учли все |
|
|||||||||||
последствия |
|
|
использования |
чужого |
|
кода |
в |
ваше |
||||
приложении. Всегда есть последствия их использования. |
|
|
||||||||||
То, как вы используете библиотеку, напрямую влияет на |
|
|||||||||||
ее безопасность, по крайней мере, до определенной степени. |
|
|||||||||||
Например, |
прямое |
участие |
библиотеки |
с |
вашим |
кодом |
||||||
JavaScript |
|
имеет |
|
тенденцию |
|
открывать |
больше |
|||||
потенциальных дыр в безопасности, чем использование |
|
|||||||||||
библиотеки для форматирования страницы. Конечно, любое |
|
|||||||||||
использование библиотеки может открыть потенциальные |
|
|||||||||||
пробелы в безопасности, которые будут стоить вашей |
|
|||||||||||
организации время, усилия и ресурсы. |
|
|
|
|
|
|||||||
Улучшение CSS с помощью библиотек |
|
|
|
|
||||||||
CSS |
– |
это |
все, |
что |
касается |
форматировании |
|
|||||
содержимого |
страницы. Web-разработчики используют CSS, |
|
||||||||||
чтобы |
сделать |
скучную страницу |
лучше. Использование |
|
||||||||
только HTML-тегов для форматирования контента сделало бы |
|
|||||||||||
практически |
|
невозможным |
использование |
страниц |
на |
|||||||
широком спектре устройств, которые сегодня используются. |
|
|
||||||||||
Один |
|
только CSS, |
вероятно, может |
|
сделать |
все |
|
|||||
необходимое для создания фантастических страниц. Тем не |
|
|||||||||||
менее, важно |
понимать, |
что |
даже |
самый |
лучший |
- веб |
|
|||||
разработчик |
|
не |
успевает |
создавать |
весь CSSэтот-код |
|
||||||
вручную. Есть несколько способов упаковать кодCSS |
в |
|
||||||||||
библиотеку, |
но |
одной |
из |
наиболее |
интересных является |
|
||||||
функция |
css |
|
(). |
Пользовательский |
интерфейс jQuery, |
|
||||||
содержащийся в файле Transform.html:
<!DOCTYPE html> <html>
<head>
<script src=”https://code.jquery.com/jquery-latest.js”>
</script>
<script src=”https://code.jquery.com/ui/1.9.2/jquery-ui.js”>
</script>
49
<script
src=”jquery.transform.js”>
</script>
<link
rel=”stylesheet” href=”https://code.jquery.com/ui/1.9.2/themes/base/jqueryui.css” />
<title>jquery.transform.js Demonstration</title> <style type=”text/css”> #TransformMe
{
border: double; border-color: Blue; border-width: thick;
position: absolute; width: 120px; height: 40px; top: 90px; left: 75px;
}
#TransformMe p
{
margin: 0;
padding: 0; height: 40px;
font-family: “Comic Sans MS”, cursive, sans-serif; fontsize: large;
color: Red; background-color: Yellow;
}
#Rotate
{
position: absolute; top: 190px; left: 75px;
}
</style>
<script type=”text/javascript”> $(function()
{
$(“#Rotate”).click(function()
{
$(“#TransformMe”).css(“transform”, “rotate(45deg)”); }); })
</script>
</head>
<body>
<h1>jquery.transform.js Demonstration</h1> <div id=”TransformMe”>
<p>Some Text</p> </div>
<div>
<input type=”button” id=”Rotate”
value=” Rotate 45 Degrees “ /> </div>
</body>
</html>
50
