Безпека веб-сайтів MVC
"Ломати - не будувати", говорить народна мудрість. Щоб створити корисну для користувачів веб-додаток, доводиться докладати багато зусиль, вигадувати потрібну функціональність та реалізовувати її. Щоб зламати веб-програму, існує набір стандартних методик, розрахованих на те, що розробник веб-програми не подумав або полінувався захистити свою веб-програму від певного типу атак.
Прихильники «хакерських ігор» можуть обуритися, що злом веб-сайту теж складна і кропітка робота. Так-то воно, можливо, і так, проте за своєю суттю злом у переважній більшості випадків заснований на стандартних підходах і залишених розробником лазівках. Зрештою винайти колесо складніше, ніж придумати, як проколоти його цвяхом, хоча останнє може бути захоплюючим завданням.
Таким чином, у нападаючого на сайт зломщика є набір практик та інструментів, що дозволяють пробувати стандартні підходи для злому веб-сайту, тому веб-розробник, який створює веб-додаток, повинен також мати власний список завдань із забезпечення безпеки веб-додатку. Основні поради я наводжу у цій невеликій статті. Пізніше я напишу докладніше про кілька найпоширеніших атак.
Базові поради щодо безпеки веб-додатків
1. Валідація введення користувача
При отриманні будь-яких даних від користувача обов'язково повинна здійснюватися перевірка на розмір та формат даних, застосування обмежень за допустимими значеннями, передбаченими бізнес-логікою та перевірка даних на безпеку. Якщо з даними щось не так, то існує два стандартні підходи – або повернути їх користувачу з помилкою, або спробувати їх «очистити». Другий шлях часто обирають для полегшення життякористувача, наприклад, при введенні дати або часу в неправильному форматі, однак цей шлях небезпечний не тільки з точки зору можливих помилок в коді, що «очищає» дані, так і з точки зору порушення логіки програми.
Основна рекомендація – відхиляти некоректні дані та пропонувати користувачеві ввести дані у правильному форматі.
Складнощі виникають у класичному завданні: введення HTML тегів для оформлення текстів, що публікуються на сайті. Якщо намагатися вирізати неприпустимі теги, існує ймовірність, що зловмисник придумає спосіб, як обійти «вирізалку» теги. Якщо ж відхиляти введений текст, то користувач може бути дуже засмучений тим, що не розуміє, чому його текст був відхилений і де в ньому неприпустимий тег. Тут на допомогу приходить наступна порада.
Для перевірок, що часто використовуються, має сенс створити допоміжний клас, що містить методи для перевірки введених даних, тоді код може виглядати якось так:
У свій час для MVC Framework 1.0 створювалися різні бібліотеки валідації на кшталт Validator Toolkit for ASP.NET MVC або xVal – можна подивитися на їхній пристрій для загального розвитку. З непоганих сучасних фреймворків для валідації даних існує FluentValidation.
Якщо використовуються механізми валідації даних на клієнті, вони повинні бути продубльовані на сервері. Зловмисник нічого не варто модифікувати клієнтські сторінки або емулювати передачу даних зі сторінок на сервер. Ставтеся до коду клієнтської валідації як до можливості заощадити час користувача при підготовці даних у потрібному форматі, а не як додаткового ступеня захисту додавання.
2. Форматування виведення даних
Щоб уникнути проблем з виведенням розмітки, там де ви її неочікуєте, використовуйте метод Html.Encode(). Якщо потрібно допустити виведення деяких тегів, то ви можете скористатися методами AntiXss.HtmlEncode() і AntiXss.HtmlAttributeEncode(), реалізованому в бібліотеці AniXSS, що входить до проекту Microsoft Web Protection Library. У бібліотеці AniXSS також доступний метод AntiXss.GetSafeHtmlFragment(), що дозволяє виводити "безпечні" теги, вирізуючи "небезпечні" та коректно форматуючи розмітку.
Бібліотеку AntiXss можна зареєструвати для використання за умовчанням для кодування HTML розмітки, про це написано покрокове керівництво в блозі у Філа Хаака.
3. Коректне використання методу POST та захищеного протоколу HTTPS
Для даних, що мають велику цінність, наприклад, таких як персональні дані та дані про кредитні картки, варто використовувати безпечний протокол передачі даних HTTPS. При цьому самі форми, що запитують дані, повинні бути надіслані HTTPS користувачу, щоб не давати зловмиснику можливостей вкрасти або модифікувати дані перед відправкою на ваш сервер. На допомогу приходить атрибут RequireHttps на відповідних діях контролерів, що вимагає передачі даних за протоколом HTTPS.
У випадках, коли користувача необхідно перенаправити на ту ж форму за протоколом HTTPS, можна реалізувати власний фільтр, який автоматично здійснюватиме перенаправлення для позначених ним дій.
4. Коректна обробка помилок та винятків
Окремо варто звернути увагу на поведінку веб-застосування при спробі невдалого завантаження файлу: перевірити коректність повідомлень про помилки при нестачі вільного місця в часовій директорії на сервері, а також при завантаженні надмірно великого файлу (таймаут, обмеження на розмір запиту на рівніIIS). Зловмисник не повинен мати можливість отримувати інформацію про структуру файлової системи сервера.
5. Контроль прав доступу користувачів
Часта помилка, яку роблять розробники у таких випадках – приховують посилання на редагування об'єктів, не захищаючи сам метод, що дозволяє редагувати об'єкт.
Чому ці поради особливо важливі у контексті використання ASP.NET MVC?
У технології ASP.NET WebForms частина з описаних вище проблем безпеки була вирішена за розробника автоматично, наприклад, WebForms брали на себе кодування тексту, що виводиться на екран (якщо не використовувався Response.Write(), звичайно), валідацію ViewState, валідацію параметрів запитів і захист від ін'єкцій через валідацію механізму події клієнта. Зрозуміло, для повного захисту від різних типів атак, розробнику потрібно дотримуватися базових принципів безпеки, проте багато в чому платформа WebForms брала турботи про безпеку на себе.
Зрозуміло, додатковий захист, як і багато інших приємних корисностей у WebForms, знижував гнучкість рішення та підвищував навантаження на систему, власне, чому деякі розробники і вибирають ASP.NET MVC у гонитві за більшою гнучкістю та більшими можливостями розширення веб-додатків. У зв'язку з цим, відмовляючись від додаткових можливостей для гнучкості, потрібно бути готовим докласти більше зусиль до того, щоб убезпечити веб-додаток.
Навіщо ламають веб-сайти?
Цілі зловмисників можуть бути різні, тому головний принцип захисту – не дати їм отримати нічого, що сайт не дозволяє отримати анонімних користувачів. Будь-яка інформація, яка видається не цінною для вас, може бути цінною для ваших користувачів і може бути експлуатована зловмисниками.
Як житидалі?
Пам'ятайте про основні принципи безпеки веб-додатків і жити добре. Найближчими днями я опублікую ще кілька невеликих статей про найнеприємніші атаки на веб-додатки та боротьбу з ними.