В данной статье речь пойдёт о том, как я обнаружил уязвимость, которая позволяла получить список пассажиров рейсов Международных Авиалиний Украины — самого крупного авиаперевозчика Украины, а также об отношении самой компании к факту наличия такой информации в публичном доступе.

Больше месяца назад я начал готовиться к отпуску и как раз пришло время бронировать авиабилеты. Так я оказался на сайте авиакомпании МАУ. В процессе выбора мест в самолёте, страница, которая должна была отображать схему мест, никак не хотела загружаться.



Я решил открыть в Google Chrome инструмент разработчика, чтобы попытаться понять, в чём проблема. Изучив запросы к серверу, я увидел, что данные о доступных местах сервером возвращаются.

Опробовав несколько разных браузеров, я так и не решил проблему, однако заметил, что запрос, который возвращает список доступных мест, выполнялся во всех браузерах успешно, не смотря на то, что сессионные куки были доступны только в Google Chrome.

Запрос выглядел следующим образом:

https://bookapi.flyuia.com/ancillary/seatmap?pnr=XXXXXX&currency=USD&flyuiacountrycode=uk&flyuialanguagecode=ru&locale=RU

где XXXXXX — PNR или, так называемый, код бронирования.
Ответ же сервера имел следующий вид во всех браузерах:

[ {
  "paxDetails" : {
    "uniqueId" : "2",
    "firstName" : "IVANOV",
    "title" : "Г-жа (Ms.)",
    "lastName" : "IVAN",
    "paxType" : "Adult",
    "cartPaxId" : "b1da2ebf-4525-35bd-afc1-b1f448132ad3"
  },
  "segmentDetails" : [ {
    "company" : "PS",
    "bookingClass" : "B",
    "flightNumber" : "1234",
    "departureAirport" : "KBP",
    "arrivalAirport" : "JFK",
    "departureDateTime" : "2018-02-01T00:05",
    "operatingAirline" : "PS"
  } ],
  "segmentId" : "1",
  "isAvailableForCheckIn" : true,
  "seat_rows" : [ {
    "seats" : [ {
      "id" : "aab4ca38-2c28-1f13-359d-4ad264d53a0e_1e80aae3-a68b-44de-ae14-aff839563612",
      "occupation" : "AVAILABLE",
      "letter" : "A",
      "rowNumber" : 4,
      "seatCharacteristics" : [ "W", "CH", "EK", "H", "for_infant" ],
      "price" : {
        "amount" : "16.00",
        "currency" : "USD"
      },
      "class" : "ECONOMY",
      "seat_type" : "SEAT",
      "ticket_value" : "FD3A"
   },...]

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

Мне стало интересно, какие ещё «сюрпризы» хранит данный сервис.
Продолжив оформление билетов, я выбрал пункт заказа места для багажа.



Запрос имел похожий вид:

https://bookapi.flyuia.com/ancillary/luggage?pnr=XXXXXX&currency=USD&locale=RU 

Однако ответ сервера содержал чуть больше информации о пользователе:

[ {
  "paxDetails" : {
    "uniqueId" : "2",
    "firstName" : "ivan",
    "title" : "Г-н",
    "lastName" : "ivanov",
    "paxType" : "Adult",
    "dateOfBirth" : "1978-10-20",
    "cartPaxId" : "a30928c1-219b-8d15-8345-b517f0fda360"
  },...]

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

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

Исследуя дальше «возможности» сервиса, я перешёл на страницу оплаты. Здесь меня ждал новый сюрприз. Запрос имел вид:

https://bookapi.flyuia.com/payportal/transaction/123456?flyuiacountrycode=ua&flyuialanguagecode=ru&locale=RU

Он так же выполнялся во всех браузерах без сессионных куков:

{
  "id" : 211334,
  "payportal" : "UkrEximBank",
  "creationTime" : "2017-12-25 14:32:13",
  "status" : "INIT",
  "amount" : 15578.00,
  "currency" : "UAH",
  "errorCode" : 0,
  "errorCategory" : "UNDEFINED",
  "data" : "{\"Locale\":\"ru_RU\",\"ORDER\":\"000000450187\",\"PosId\":\"12e66438b256e10f74424133\",\"Pnr\":\"XXXXXX\",\"fopType\":\"CREDIT_CARD\",\"Country\":\"492ac4aae7f43c6e6a4336f9\",\"Passenger\":\"ivanov ivan\",\"PayerEmail\":\"ivanov.ivan@gmail.com\",\"BackReference\":\"https://book.flyuia.com/RU/default/paymentstatus\",\"OaDRoute\":\"01Feb18JFKKBP-10Feb18KBPJFK\",\"LANG\":\"UKR\",\"DESC\":\"XXXXXX, ivanov ivan, 01Feb18JFKKBP-10Feb18KBPJFK\"}",...}

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

В итоге набор всех уязвимых запросов позволяет злоумышленникам организовать сервис, который сможет в режиме реального времени незаметно для администраторов ресурсов составлять список пассажиров рейсов авиакомпании. Однако список пассажиров не является публичной информацией и защищается в целях безопасности авиакомпаниями, а в некоторых странах и законами. Доступ к таким данным имеют как правило только сотрудники компаний и определённые госструктуры. Тем больше было моё удивление, когда обратившись в клиентскую поддержку компании МАУ и сообщив им о наличии данных уязвимостей, в процессе переписки и уточнения статуса моей заявки я получил следующий ответ:



Однако на вопрос, предоставляют ли они по запросу клиентов список пассажиров рейса, мне ответили негативно.

Не смотря на такой странный ответ компании, разработчики в течении месяца устранили все вышеуказанные уязвимости, что успокоило меня, как клиента.

Отдельным пунктом хотелось бы обратить внимание на то, что опять же, как в случае и с другими крупными компаниями, в МАУ отсутствует отдельный канал связи для сообщений о найденных уязвимостях. На мою просьбу связать меня со службой безопасности или ответственными разработчиками, мне ответили отказом:



Подводя итоги, хочу сказать следующее.

Авиакомпании должны заботиться о безопасности своих пассажиров не только в аэропортах и на борту самолёта, но также и в сети. Ведь данные о пассажирах — это очень чувствительная информация. Владея ею, воры могут ограбить квартиру жертвы, пока та будет в отъезде. Экс-супруг может преследовать свою бывшую жену, зная о её перемещениях. Злоумышленник, получив коды бронирований, может через сайт авиакомпании массово отменить регистрации пассажиров, что потенциально может привести к задержке рейсов. Публичная информация о перемещениях бизнес-конкурентов может нанести ущерб их компаниям. Способов использования такой информации со злым умыслом множество и охраняться она должна соответствующим образом.

Комментарии (45)


  1. Ugrum
    26.02.2018 13:22

    «Не пускайте программистов в интернет — они обязательно там что-нибудь сломают.»
    Ну хоть починили, а не стали отмазываться, что всё нормально, а автор — злобный хакер, который нанёс стомиллионный ущерб критическому сервису и ему надо атата выписать.
    Скидку на билеты хоть предложили?


    1. dinikin Автор
      26.02.2018 15:05

      Скидку? За что? Данные же не являются конфиденциальными с точки зрения авиакомпании, а значит уязвимости нет


      1. JC_IIB
        26.02.2018 15:14

        Почему «дата рождения и паспортные данные» не являются конфиденциальными? Разве оператор ПД не обязан хранить эти самые ПД в тайне? Тем более, что у них, вон, все засекречено настолько, что даже контакты СБ и те — конфиденциальны!


        1. dinikin Автор
          26.02.2018 15:18

          Они имеют ввиду, что в тех данных, которые доступны публично, нет даты рождения и паспортных данных, а соответственно они не являются конфиденциальными. Хотя как раз дата рождения там и была.


  1. snikes
    26.02.2018 14:09

    Главное американцам такого не писать, а то закроют, скажут русский хаккер, поломал систему.


  1. Token2
    26.02.2018 14:20

    Насколько я знаю, код бронирования это что-то вроде пароля. Его, по идее, должен знать только сам пассажир и агенство.


    1. site6893
      26.02.2018 18:01
      -2

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


  1. JC_IIB
    26.02.2018 14:39

    контакты данных служб являются конфиденциальной информацией


    Походу дела, люди в принципе не знакомы с понятием и определением «конфиденциальной информации». В переводе на человечий это значит — «Я не несу ни за что ответственности и не хочу нести, я понятия не имею, можно ли вам дать эти контакты, мне лениво спрашивать у начальства, и моя хата — с краю, а вдруг чо.»
    Сколько же всякого людского тупизма, сколько лени и инертности прикрывается фразой «это конфиденциальная информация». Доходило до того, что сотрудники сервис-центра залепили мне такую отговорку, когда я спросил, авторизованным партнером каких вендоров они являются! Товарищу аналогично ответили, когда он попросил показать, на основании каких документов запрещена фотосъемка витрин в магазине.

    Но чтобы причислить контакты СБ к «конфиденциальной информации»… это финиш.


    1. dinikin Автор
      26.02.2018 15:04

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


    1. LynXzp
      27.02.2018 00:12

      Контакты СБ могут быть «служебной информацией». То что у них нет публичного контакта — другое дело.


  1. throttle
    26.02.2018 15:56

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

    Закон — как дышло. Одно дело — когда заходишь на страничку, и видишь чужие данные. совсем другое — когда открываешь инструменты разработчика, начинаешь анализировать подноготную обмена. Перебирать PNR, и вот это вот все. Тут уже не публичный доступ к персональным данным — тут уже вмешательство в работу могут припаять.


  1. mirsev
    26.02.2018 15:57

    1. Заглавие статьи: Получаем список пассажиров рейсов авиакомпании… Но данные-то — только об одном пассажире. Либо этой компанией только он и летает, либо название не соответствует содержанию.

    2. Номер PNR — действительно что-то вроде пароля, как уже указано выше. Если его какой-нибудь «шутник» узнает, он может и бронирование отменить. Так что…


    1. dinikin Автор
      26.02.2018 15:59

      Но данные-то — только об одном пассажире.

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


      1. mirsev
        26.02.2018 16:04

        Нет PNR — нет данных. Где доступность?


        1. Ugrum
          26.02.2018 16:10

          1. RomanL
            26.02.2018 16:22

            Ну так нефиг фоточки билетов в инстаграмчик выкладывать ))


        1. AllexIn
          26.02.2018 17:00

          Пол статьи посвящено тому, как PNR получить.


    1. dmitryredkin
      26.02.2018 16:12
      +2

      Автор же во второй части рассказывает, как инкрементальным перебором номеров получать PNR.


      1. mirsev
        26.02.2018 16:26
        -2

        И как?


        1. AllexIn
          26.02.2018 17:00

          Перебором транзакций?


          1. mirsev
            26.02.2018 17:09

            А они точно инкрементальные? Тогда странно, что автор не привёл доказательства этого. Можно было бы попробовать выудить несколько записей, замазать часть данных в результатах и опубликовать для иллюстрации.


            1. VulvarisMagistralis
              27.02.2018 20:26

              Тогда странно, что автор не привёл доказательства этого.

              Какой ты нудный.
              Ну сам попробуй, рецепт приведен.


    1. site6893
      26.02.2018 18:04
      -1

      хоть статью дочитай перед там как писать, что-то.


      1. mirsev
        26.02.2018 19:35

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


  1. pyrk2142
    26.02.2018 17:49

    Вообще, код бронирования — опасная штука. У некоторых авиакомпаний можно, зная код бронирования и фамилию пассажира, получить его полное ФИО и паспортные данные, которые были указаны при заказе. Плюс всю информацию о полёте и других пассажирах в одном бронировании (?).


    1. Dreyk
      26.02.2018 19:13

      а в некоторых компаниях еще и все будущие запланированные поездки


    1. pyrk2142
      26.02.2018 19:54

      UPD: если я правильно нашел, то у МАУ можно поискать свой рейс на checkmytrip.com по имени и коду бронирования. Проверьте, пожалуйста, кто может.


      1. Gorodnya
        27.02.2018 21:24

        Tickets.ua пишет, что для проверки статусов билетов есть следующий сайты:
        www.checkmytrip.com — для авиабилетов, забронированных через Amadeus;
        www.viewtrip.com — для авиабилетов, забронированных через Galileo;
        www.virtuallythere.com — для авиабилетов, забронированных через Sabre;
        www.myairlines.ru — для авиабилетов, забронированных через Сирену.


      1. Gorodnya
        27.02.2018 21:35

        … а на checkmytrip.com немного поменялась процедура, теперь им нужно отправлять подтверждение бронирования на e-mail.


  1. rewiaca
    26.02.2018 19:04

    dinikin, а вам нравится взрывать себе мозг репортами в компании, которые и не слышали о политике vulnerability disclosure? :) Некоторые не такие как сдержанные и этичные как вы #FuckResponsibleDisclosure

    Это еще хорошо, что взялись пофиксить, кстати, как долго фиксили?


    1. dinikin Автор
      26.02.2018 19:37

      вам нравится взрывать себе мозг репортами в компании

      а что делать, когда приватные данные твоей семьи доступны любому
      кстати, как долго фиксили?

      примерно месяц


  1. SerggioS
    26.02.2018 19:47
    +1

    Работал в своё время в авиакомпании, но не в МАУ. Хочу сказать спасибо автору за бдительность. К сожалению национальный и единственный перевозчик настолько убог, что даже не удивлён. Были у них этапы, когда им на топливо с трудом хватало, а вы хотите офицера безопасности найти, его контакты.
    Действительно с помощью pnr и фамилии можно получить данные, которые по идее должны быть защищены, но подавляющее большинство а/к так и остались в прошлом веке.
    Есть ресурсы от тех же систем бронирования, которые позволяют введя pnr и фамилию законно получить данные. Тут уже дело в настройках, которые по умолчанию многое показывают. В некоторых GDS есть возможность ограничивать вывод «чувствительных данных». В целом индустрия в упадке, каждый ищет себя, пытается найти выход, но получается не очень.
    На месте МАУ я бы Вам бесплатные билеты выдал.


    1. LangovoyAndrey
      26.02.2018 20:04

      На месте МАУ я бы Вам бесплатные билеты выдал.

      но
      перевозчик настолько убог

      что
      что даже не удивлён


    1. DS28
      27.02.2018 06:29

      Подавляющее большинство а/к так и остались в прошлом веке.

      Увы, это проблема всей отрасли. Очень всё медленно меняется…


  1. vlad00777
    26.02.2018 19:56
    +1

    Меня еще удивляет регистрация и авторизация в «Панорама клаб». При регистрации пароль обязательно должен быть из 6 цифр! Причем при авторизации нужно указать лишь номер карты, а она всегда имеет формат 100XXXXXXX — где Х, только цифры. Причем при авторизации нет никакой каптчи. Стоит только пройтись по всем номерам карт с паролями «123456» и т.п.


  1. SerggioS
    26.02.2018 20:21
    +1

    Места для авиакомпании, не считая «высокого сезона» это самый примитивный и выгодный момент взаиморасчетов. По сути, это как продажа воздуха.
    Но убогость проявляется во всех сферах деятельности. И часта эта убогость выражается не в финансах…


  1. Faceless
    27.02.2018 00:38

    Кстати похожая уязвимость есть и у Белавиа. Я тоже когда бронировал места мне выдавался список пассажиров на данном PNR. В принципе можно было сделать так что забронировать места для пассажиров из одной семьи на разных рядах. Если быть редиской


  1. alek0585
    27.02.2018 02:47

    А вот если это была бы статья про российского оператора, то в комментариях столько бы тонн грязи полилось по теме «в рашке всё плохо». И bug bounty program нет, и сотрудники негодяи бестолковые, не то что в штатах. Где-то на хабре даже есть подобная статья, но про банк кажется.


  1. php7
    27.02.2018 10:52

    Вопрос с другой темы:
    Что будет банку, если он нарушил PCI DSS?


  1. saboteur_kiev
    27.02.2018 12:50

    Думаю, что любая компания, у которой есть публичный интернет сервис обязана не только не скрывать контакты «служб», а наоборот, специально указывать на сайте конкретный адрес или форму, по которому можно связаться в случае найденной уязвимости.

    В идеале конечно еще bugbounty открыть, но это я размечтался.


  1. Extremum
    27.02.2018 16:12

    Какая компания, такой и сайт. Летал с ними дважды — первый раз в Тель-Авив, при цене чуть выше конкурента El Al отсутствовало не то что питание (в отличие от конкурента), второй стакан воды который я попросил мне предложили купить. Самолет хуже, сиденья неудобные.
    Второй раз в Милан прошлой осенью — опоздали с вылетом на 4 часа, в аэропорт попал в половине второго ночи, никто из компании даже не почесался чтобы доставку пассажиров в город сделать из Бергамо.



  1. phoenixx
    27.02.2018 17:45

    Автор поста умалчивает детали. Чтобы отослать и получить PNR по TransactionId нужно так же чтобы в запросе была кука SESSION=9b2b4e6a-7107-49bd-9980-627aba16e71c;. А если куки не будет, то в ответ прийдет 403. Поэтому фактически перебрать TransactionId не перебирая гуид в SessionID — весьма проблемно


    1. dinikin Автор
      27.02.2018 17:46

      нет, запрос отрабатывал без куки, в том то и суть


  1. igi7
    27.02.2018 17:45

    Еще один в камень в огород МАУ и повод ими не пользоватся.