Nezabezpečený přístup k osobním údajům milionu uživatelů Leo Expressu

Read this article in English.

Leo Express je společnost provozující vlakové a autobusové linky v Česku a ve střední Evropě. Pro cestující poskytují možnost registrace účtu a zapojení do věrnostních programů, stejně jak získávání bodů za každou jízdu.

Když jsem se zaregistroval, všiml jsem si, že při každém načtení stránky se odesílá GraphQL požadavek na jejich server, který vrací údaje o mém účtu.
GraphQL je dotazovací jazyk, alternativa k RESTu, který v jednom požadavku vrací data definovaná na straně klienta.

Zde je detail, jak vypadal obsah toho POST requestu:

{
   "query":"query getActualUserDataQuery($email: String, $token: String, $timestamp: Int, $locale: String) {
  getActualUserData(email: $email, token: $token, timestamp: $timestamp, locale: $locale) {
    token
    user {
      id
      login
      firstName
      lastName
      phone
      address_state
      address_city
      address_street
      address_zip
      facebook_id
      google_id
      sex
      currency
      language
      profile_picture
      clubmember
      credit_bonus
      credit_standard
      smilebus
      distance
    agreements {
        type
        enabled
        __typename
      }
      __typename
    }
    error {
      code
      message
      __typename
    }
    __typename
  }
}
",
   "variables":{
      "email":"info@example.com",
      "token":null,
      "timestamp":0,
      "locale":"cs"
   },
   "operationName":"getActualUserDataQuery"
}

V objektu variables nás budou nejvíc zajímat položky email a token, kde byl vyplněný můj email a bezpečnostní token. Nečekal jsem ale, že požadavek bude stále fungovat i když token jakkoliv změním nebo dám úplně pryč.

Zkusil jsem také z requestu odstranit všechny cookies v případě, že by to ověřovalo přístup díky nim, ale toto nebyl ten případ.
Znamenalo to tedy, že jsem mohl získat osobní údaje z profilu jakéhokoliv uživatele a stačilo mi k tomu znát jenom jeho email.

V odpovědi s daty uživatele se mj. nacházelo jméno, telefonní číslo, celá adresa a další údaje jako připojený facebook/google účet.

JSON response data

Část druhá, XSS a kreditní karty

Další problém ve spojení s reflected XSS umožnil získat info o uložených kreditních kartách přihlášeného uživatele.

Při dokončení objednávky proběhne přesměrování na následující URL, kde se ukáže zpráva, že jízdenka byla poslána na emailovou adresu uživatele.

https://www.leoexpress.com/en/order-confirmation?order=12345&email=info@example.com&state=success

Je ale problém v tom, že zobrazená emailová adresa je získaná z parametru email v URL a před vložením na stránku nejsou nijak ošetřeny speciální znaky. Jelikož na webu není nastavena ochrana CSP, znamená to, že je možné na stránce vykonat libovolný javascriptový kód.

Reflected XSS

Když jakýkoliv přihlášený uživatel klikne nebo je přesměrován na výše zmíněnou adresu, dostaneme prakticky neomezený přístup nad jeho účtem.

Stačí, aby uživatel měl uloženou kreditní kartu v profilu a máme přístup k jejím informacím; typ karty, kdy byla přidána, a prvních 6 a poslední 4 čísla kreditní karty. To je 10 číslic z celkem 16, s tím už se dá něco dělat…

Zmíněné problémy byly opraveny do tří měsíců od nahlášení, což není ideální, ale lepší než nic.

Written by Thomas Orlita
Follow me on Twitter: @ThomasOrlita / Mastodon: @ThomasOrlita@infosec.exchange

Leave a Reply