Уразливості і платіжні сервіси

Часто програмісти при розробці фінансових систем з причини відсутності досвіду допускають прості, але досить серйозні помилки. І хоча не завжди пряма провина лежить на розробнику, як правило однією з причин появи таких помилок є відсутність розуміння їх наслідків.

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

Почалося все з того, що одного разу, коли я працював над одним з таких проектів, в нашу компанію надійшов лист від клієнта про те, що їм на нашому сайті виявлена уразливість, яка дозволяє отримати доступ до будь-якого файлу на сервері. Це було неприємно. І хоча уразливість швидко виправили, і яких-небудь серйозних наслідків цей інцидент не мав, мені стало цікаво, чи є ще подібні уразливості в моєму проекті. Згодом я почав їх шукати і на інших сайтах. Тепер мене цікавило інше питання: на скільки надійно зберігаються критичні для користувача дані в інших системах. В першу чергу мене цікавили платіжні сервіси, так як виявлення вразливостей на них могло мати набагато більш серйозні наслідки, ніж виявлення уразливостей на сайтах знайомств. З часом я зрозумів, що програмісти навіть в самих популярних і, на перший погляд, надійних проектах, допускають досить прості помилки. Тим не менш такі прості помилки призводять до появи серйозних дірок в безпеці, які дозволяють не тільки отримувати несанкціонований доступ до особистої інформації клієнтів, але і деколи виконувати фінансові операції над їх грошовими коштами.

Заздалегідь попереджу, я спеціалізуюся на пошуку вразливостей, які реалізуються через HTTP протокол і відповідно всі приклади будуть з використанням цього протоколу.

Для простоти, там, де це можливо. я буду описувати приклад у вигляді GET запиту замість POST для більш зручного сприйняття.

І так, поїхали…

Приклад №1. Відсутність перевірки прав доступу при запиті з використанням ідентифікатора
Приклад запиту:

http://my.site.com/getAccountInfo?id=12345

Це найпоширеніша помилка, яку я зустрічав у більшості вразливих сервісів. Як правило, в будь-якому інтерфейсі, частина запитів, які може сформувати клієнтська сторона, використовують числові ідентифікатори і в більшості випадків перевірка прав доступу успішно здійснюється сервером. Але рано або пізно виявляється запит, який не перевіряється і в підсумку нам вдається отримати особисту інформацію іншого клієнта. Такими даними на моєму досвіді були особисті повідомлення клієнта саппорт, паспортні дані, банківські виписки. Також, бували випадки, коли крім доступу до персональних даних клієнта, така вразливість дозволяла здійснювати платежі з рахунку іншого клієнта. Зазвичай такі помилки допускаються з кількох причин:
  • перша з них полягає в тому, що в проекті немає системного архітектора і питання безпеки сервісу лягають на плечі програмістів
  • друга причина — це коли серверний додаток взаємодіє з безліччю джерел зберігання даних за різними протоколами і немає універсального рішення для контролю за правами доступу до цих даних. У такому разі для кожного окремого типу запиту розробнику потрібно реалізовувати конкретне рішення по перевірці прав, що досить часто не робиться.


Приклад №2. Доступ до особистих даних по GET запит з використанням хеш без авторизації

http://my.site.com/getPaymentDetails?hash=c68f39913f901f3ddf44c707357a7d70

На моїй пам'яті було кілька сервісів, які допускали таку можливість. В одному випадку це був банк, який повертав по клієнту дуже детальну інформацію, а в другому випадку сайт, що надавав послугу на перекази з картки на картку і за такою адресою повертав збережену карту з терміном дії та cvv2, що, між іншим, що суворо заборонено правилами платіжних систем Visa і MasterCard.
Помилка програміста в тому, що він думає, що ні хто не може дізнатися цей урл крім самого користувача. Насправді будь-який сайт, на який ви перейдете з цієї сторінки за посиланням, отримає ваш url у поле заголовка Referer запиту. Також такий урл може проіндексувати пошуковик і згодом видавати його в пошуковій видачі.

Приклад №3. Передача у відповіді сервера надлишкової, чутливої інформації, яка в підсумку ні де не використовується.
Припустимо, у нас є форма на сторінці, яка за ajax запит повинна відображати яку-небудь додаткову інформацію, наприклад назва мерчанта. Тоді запит буде виглядати приблизно так:

http://my.site.com/getMerchantName?merch_id=12345

У відповіді нам має повернутися приблизно наступне:

{merch_id:'12345', name:'Test merchant'}

Але буває так, що у відповіді приходить не тільки назва мерчанта, але і вся сериализованная модель об'єкта Merchant, який замаплен на таблицю в базі даних, і таким чином від сервера приходить і така інформація, як, наприклад, пароль мерчанта

{merch_id:'12345', name:'Test merchant', password:'isdy5894yt8sdlg', ...}

У сукупності з вразливістю з приклад №1 ця помилка дає можливість здійснювати операції від імені чужого мерчанта.
Так, у моїй практиці був випадок, коли сайт інтернет-банку по простому ajax запит про ліміти повертав мало не всю наявну інформацію по клієнту, у тому числі номери карт, терміни їх дії, паспортні дані клієнта, адреси прописки і проживання. Необхідності передавати всю цю інформацію не було, так як користувачеві переглядати лише інформація за лімітами, але програміст мабуть, особливо не вникаючи, всю інформацію, отриману його додатком з внутрішнього API банку, передавав на клієнта. А так як ця помилка була допущена ним спільно з помилкою приклад №2, особисті дані клієнта могли бути доступні третім особам.

Приклад №4. Відсутність CSRF сертифіката ключа, асоційованого з сесією користувача
Приклад запиту:

http://my.site.com/createPayment?phone=0987654321&amount=100

Небезпека такого запиту полягає в тому, що якщо ви авторизовані на сайті, зловмисник просто попросивши вас перейти за посиланням, зможе у вашому акаунті створити платіж на поповнення мобільного телефону.

Як правило, всі ці помилки зустрічаються не поодинці, а в різних комбінаціях один з одним, що дає зловмиснику ще більший простір для дій.

Природно, велика частина цих вразливостей не з'явилася б при правильно побудованій архітектурі додатки. Але як ми всі знаємо, не завжди на старті проекту є можливість найняти розумного, досвідченого архітектора, та й не завжди сам архітектор може передбачити всі підводні камені, які згодом виникнуть в ході подальшої реалізації проекту.

Тож власникам таких сервісів потрібно приділяти особливу увагу тестування на наявність вразливостей і тут може активно допомогти інтернет-спільнота. Це чудово розуміють такі інтернет-гіганти, як Google, Amazon, eBay, Yandex і для цього вони організовують bug bounty програми, які передбачають заохочення за знайдені вразливості. Але я вважаю, що така програма посильна і для невеликих проектів, які тільки виходять на ринок. Це відмінний спосіб поліпшити захист даних клієнтів, уникнути непотрібного галасу в ЗМІ з-за опублікованій кимось уразливості і зберегти імідж компанії. Ну а бажаючі шукати дірки в сервісах, я впевнений, знайдуться, тим більше, що для цього будуть законні підстави та фінансова мотивація.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.