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.
Čá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.
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.