szukaj

03.02.2026 | 20:00

avatar

Michał Leszczyński

Kto i dlaczego losuje w Polsce rozkład jazdy PKP

Twój pociąg odjeżdża o 21:36. A nie, o 22:35. Nie, nie, jednak o 20:36. Każde odświeżenie strony daje nowy wynik, a żaden z nich nie jest prawidłowy. Koszmarny sen? Nie, tak naprawdę działa (czasem i dla niektórych klientów) oficjalny rozkład jazdy PKP online, czyli Portal Pasażera.

Historia zaczyna się 16 stycznia 2026 roku. Wchodzę na Portal Pasażera sprawdzić, z którego peronu odjeżdża mój pociąg i czy ma jakieś opóźnienie. Zaraz… godzina odjazdu pociągu podawana przez system nie pokrywa się z rzeczywistością. Odświeżam stronę jeszcze kilka razy – za każdym razem ten sam numer pociągu, a zupełnie inny rozkład. Zgodnie z zasadą Brzytwy Ockhama nie wnikałem zbytnio w szczegóły, ponieważ jedynym logicznym i racjonalnym wyjaśnieniem tej sytuacji jest po prostu przejściowa awaria.

Wróciłem do domu i znowu sprawdziłem Portal Pasażera – działa jak należy. Wychodzę na kolejny pociąg – nie działa. Dwa dni później zaobserwowałem, że wspomniana awaria wcale nie jest chwilowa, a co więcej, doświadczam jej, tylko gdy jestem “w terenie”.

Wykonajmy szybki eksperyment. Czy występowanie lub brak występowania błędu zależy od tego, z jakiego operatora internetu korzystam? Bingo.

Kliknij tutaj, aby wyświetlić treść z YouTube.
Dowiedz się więcej w polityce prywatnościYouTube.

Na kablówce Portal Pasażera zawsze działa jak należy, ale po przełączeniu na internet mobilny z Plusa awaria ponownie się ujawnia.

Analiza

Zawodowo zajmuję się cyberbezpieczeństwem, więc obserwowanie tego typu niewyjaśnionych sytuacji powoduje u mnie co najmniej lekki dyskomfort, szczególnie jeżeli występują na moim prywatnym sprzęcie. Zgodnie ze sztuką spróbujmy na początek wykluczyć jak najwięcej czynników i hipotez, aby móc później precyzyjnie zdiagnozować problem.

Coś pomieszało się z konfiguracją przeglądarki albo z ciasteczkami

Sprawdziłem mobilne wersje Chrome’a, Firefoxa i Opery, również w trybach „incognito”. Przeglądarka i jej konfiguracja nie ma dla sprawy żadnego znaczenia. Zawsze otrzymuję błędny rozkład na internecie mobilnym z Plusa, nigdy nie otrzymuję błędnego rozkładu na lokalnej kablówce (przez Wi-Fi).

Może mam zainfekowany telefon albo uszkodził się RAM/karta SD?

Sprawdziłem na dwóch innych smartfonach, których używam sporadycznie i jedynie do testów aplikacji. Ponownie – te same wyniki, niezależnie od użytego urządzenia.

Atak Man-in-the-Middle (MITM)?!

Portal Pasażera wykorzystuje szyfrowany protokół HTTPS. Co ciekawe, nawiązanie połączenia przez nieszyfrowany port 80 nie jest w ogóle możliwe:

$ nc -vvv portalpasazera.pl 80
nc: connect to portalpasazera.pl (20.215.179.104) port 80 (tcp) failed: Connection timed out

To może ktoś (jakimś cudem) podsłuchuje mój ruch sieciowy i modyfikuje odpowiedzi przesyłane przez serwer?!

$ cat /dev/null | openssl s_client -connect portalpasazera.pl:443 > /dev/null
depth=2 C = PL, O = Unizeto Technologies S.A., OU = Certum Certification Authority, CN = Certum Trusted Network CA
verify return:1
depth=1 C = PL, O = Unizeto Technologies S.A., OU = Certum Certification Authority, CN = Certum Domain Validation CA SHA2
verify return:1
depth=0 CN = *.portalpasazera.pl
verify return:1
DONE

No nie. Niezależnie od użytego dostawcy internetu, zawsze otrzymujemy ten sam, poprawny certyfikat SSL/TLS Portalu Pasażera, pochodzący od globalnie zaufanego wystawcy.

Wnioski? Połączenie z Portalem Pasażera jest poprawnie, zgodnie ze sztuką szyfrowane i uwierzytelnione. Tym samym mój operator internetu nie ma żadnego wglądu w to, co robię na stronie internetowej PKP. Widzi jedynie zaszyfrowane zapytania i zaszyfrowane odpowiedzi. Gdyby SSL/TLS był błędnie skonfigurowany albo ktoś faktycznie manipulował moim ruchem sieciowym na którymkolwiek poziomie, przeglądarka wyświetlałaby na ten temat słynne wielkie czerwone ostrzeżenie, a nic takiego nie miało miejsca.

Może to jednak jakiś skomplikowany bug i coś różni się w zapytaniach HTTP?

Przechodzę na komputer. Uruchamiam przeglądarkę, podpinam ją do Burp Suite i wyszukuję na Portalu Pasażera jeden z pociągów. Zapisuję sobie pełną treść faktycznego zapytania HTTP, które wysłała moja przeglądarka.

Nie zgadniecie. Identyczne zapytanie zawsze zwraca poprawny rozkład na kablówce i zawsze zwraca pomylone dane na internecie mobilnym Plusa. Nie różni się ani jeden bajt, a więc absolutnie jedyna techniczna różnica to adres IP pytającego o rozkład.

Operator internetowy wprowadził “transparent proxy”/cache i coś zepsuł

To technicznie niemożliwe bez zgody użytkownika. SSL/TLS w tym przypadku uniemożliwia operatorowi jakąkolwiek ingerencję w treść danych generowanych przez Portal Pasażera, niezależnie od tego, czy charakter tej ingerencji byłby „złośliwy”, czy „pomocniczy”.

Wielki eksperyment loteryjny

Skoro już zacząłem „dłubać” na poziomie zapytań HTTP, postanowiłem, że poeksperymentuję dalej. Napisałem program, który z mojego internetu mobilnego w Plusie (tego objętego „losowaniem rozkładów”) wyśle 3000 zapytań o rozkład pociągu KM 93312. Następnie przeanalizowałem te dane statystycznie. Analizowałem tylko jeden parametr – godzina odjazdu z Warszawy Wschodniej zgłoszona przez system.

Na dzień wykonania eksperymentu (19 stycznia 2026 r.) prawdziwa godzina odjazdu tego pociągu z Warszawy Wschodniej to 16:12.

Wyniki, które otrzymałem:

  1. Najwcześniejsza godzina odjazdu spośród tych 3000 zebranych próbek: 15:12 (dokładnie -60 minut).
  2. Najpóźniejsza godzina odjazdu: 17:11 (dokładnie +59 minut).
  3. Średnia wartość pomyłki: -0.35 minuty ≈ 0 minut.
  4. Odchylenie standardowe pomyłek: 34.736 minuty.

Wnioski? Pomyłki Portalu Pasażera mają rozkład równomierny dyskretny (ang. discrete uniform distribution) w przedziale [-60, 59] minut. Z praw matematyki wynika więc, że charakter pomyłki jest całkowicie losowy, niczym w rzucie kostką.

Co więcej, jeżeli zapytamy 3000 razy o ten sam pociąg, weźmiemy te wszystkie rozkłady i wyciągniemy z nich średnią, to… otrzymamy prawdziwe godziny odjazdu.

No dobra, ale może Portal Pasażera po prostu myli ze sobą różne pociągi?

Gdyby tak było, nie obserwowalibyśmy pomyłek o całkowicie losowym charakterze, tylko w danych byłoby widać jakiekolwiek logiczne trendy.

W zdecydowanej większości przypadków, zwracane rozkłady nie pasują do jakiegokolwiek fizycznie istniejącego pociągu. Co więcej:

  1. system zapomina o jakimkolwiek opóźnieniu, ale
  2. odległości minutowe/kilometrowe pomiędzy poszczególnymi stacjami zawsze są poprawne i zgodne z rzeczywistym rozkładem pociągu, którego szukamy, ale
  3. znika opis dla niepełnosprawnych na przycisku „wydrukuj” – w normalnej sytuacji ten opis zawiera datę i godzinę odjazdu pociągu.

Do tego wszystkiego, przypomnijmy, że tak pokręcony bug dotyczy jedynie wybranych adresów IP.

Pomieszało się coś ze strefami czasowymi

Standardowe strefy czasowe operują na rozdzielczości godzinowej, w skrajnych przypadkach może to być przesunięcie o 30 lub 45 minut (np. strefa czasowa Australian Central Western Standard Time – ACWST). Byłoby to niesamowicie dziwne i nieprawdopodobne, gdyby strefa czasowa losowo przeskakiwała o kilka minut w przód lub w tył.

Co więcej, algorytm wyszukiwania rozkładu jazdy pociągu o określonym numerze z definicji powinien być algorytmem deterministycznym – tj. na to samo pytanie zawsze zwracać tę samą odpowiedź. Skąd więc element losowy?

Oficjalna odpowiedź PKP PLK S.A.

W obliczu tak kuriozalnej sytuacji zwróciliśmy się do PKP PLK S.A., odpowiedzialnej za serwis Portal Pasażera, z prośbą o wyjaśnienia. Otrzymaliśmy taką oto odpowiedź od rzecznika prasowego (cytujemy w całości):

Dzień dobry,

Informujemy, że kwestie dotyczące zabezpieczeń Portalu Pasażera nie podlegają upublicznieniu.

Działanie sieci operatorów nie leży w gestii Polskich Linii Kolejowych.

Pozdrawiamy

Zespół Prasowy PLK SA

Możliwe wyjaśnienia

Skoro rzecznik nie wyjaśnia, to spróbujmy sami. Dlaczego niektórzy użytkownicy Portalu Pasażera raczeni są losowymi rozkładami jazdy? Po ostrożnym wykluczeniu wszystkich racjonalnych wytłumaczeń wszystko wskazuje na to, że programiści PKP PLK postanowili w ten sposób „zrobić pranka” osobom, które korzystając z botów, na bieżąco zbierają z portalu informacje o rozkładach jazdy i faktycznych wartościach opóźnień pociągów w sposób automatyczny (tj. scrapują), a później tworzą z tego statystyki albo – o zgrozo – chcą stworzyć konkurencyjną wyszukiwarkę pociągów.

Motywacje przeciwko scrapowaniu

Dlaczego ktoś miałby chcieć utrudniać automatyczne pobieranie rozkładu jazdy pociągów? Nie wiemy, ale interes mógłby mieć np. dostawca usługi API, umożliwiającej automatyczne pobieranie danych o rozkładzie jazdy w ustrukturyzowanej formie, np. takiej, jaką od niedawna za darmo (mimo obecności wariantu „Premium” w menu) oferuje PKP PLK S.A. Ale to tylko spekulacje.

Ale… ja nie mam żadnego bota, a i tak otrzymuję losowy rozkład!

No dobrze, a dlaczego niektórzy użytkownicy zostali przerzuceni w tryb „losowania rozkładów”, pomimo że nie robili nic złego? Odpowiedź brzmi CGNAT (ang. Carrier Grade Network Address Translation). Cóż to za potwór? Spieszę z wyjaśnieniem.

Jak doskonale wiemy, pula dostępnych adresów IPv4 już kilka lat temu uległa wyczerpaniu, a użytkowników internetu od tego czasu wcale nie ubywa. Operatorzy internetu radzą sobie w ten sposób, że przydzielają jeden adres IP do kilkuset, a nawet kilku tysięcy użytkowników jednocześnie. Tym samym wystarczy, że inny użytkownik współdzielący z Wami adres IP, został sklasyfikowany jako osoba łamiąca regulamin (automat, scrapper), a w konsekwencji Wy również możecie zacząć otrzymywać fałszywe informacje o rozkładach jazdy.

Portal Pasażera przestaje losować

Wiemy, że oprócz naszej redakcji pytania związane z dziwnym zachowaniem portalu przesłało co najmniej kilka innych osób, które również zaobserwowały podobne efekty. Po tym gradzie pytań około 20 stycznia efekt losowości rozkładu jazdy znika.

Portal Pasażera zaczyna losować, ale tylko trochę

Około 30 stycznia losowość znienacka powraca i na dzień publikacji tego artykułu nadal występuje. Tym razem średnio na trzy zapytania wysłane z „podejrzanego” adresu IP dwa zwracają prawidłowe wyniki, a jedno losowy. Charakter losowości jest identyczny jak poprzednio, tylko zdarza się trzy razy rzadziej. Dlaczego? Niestety nie wiemy, ale może komuś niechcący przywrócił się backup na jednym z trzech serwerów za load balancerem. Ale to tylko spekulacje.

Podsumowanie

Aby mieć pewność, że otrzymacie prawidłowy rozkład jazdy na Portalu Pasażera, pobierzcie go minimum 3000 razy i wyciągnijcie średnią. Powinno działać dla każdego przypadku opisanego powyżej.

Spółce PKP PLK przypominamy natomiast, że z Portalu Pasażera korzystają również osoby niepełnosprawne, które mogą dać wiarę błędnie wyświetlanym informacjom, a w efekcie ten żart stanie się dla nich wyjątkowo nieśmieszny.

Czy Wasz adres IP też jest objęty „losowaniem”? Wyszukajcie dowolny pociąg, wejdźcie w „[Szczegóły połączenia]”, odświeżcie kilka razy i dajcie znać w komentarzu. I pamiętajcie, że kwestie dotyczące zabezpieczeń Portalu Pasażera nie podlegają upublicznieniu.

Powrót

Komentarze

  • avatar
    2026.02.03 20:38 Leszek

    kablówka VECTRA – brak losowości

    Odpowiedz
  • avatar
    2026.02.03 21:48 Jakub

    Tym powinien się zająć Urząd Transportu Kolejowego

    Odpowiedz
  • avatar
    2026.02.03 22:03 eh

    czepiacie sie
    wszystko jest tak jak trzeba
    raz sie pociag spozni a raz przyjedzie o czasie wiec ….sredni czas opoznienia sie zmniejszy
    a liczy sie tylko statystyka przeciez

    Odpowiedz
  • avatar
    2026.02.03 22:19 Marcin

    to jest naprawde chore, oficjalny portal od PKP, nie dość że wolny i w porównaniu do np. mObywatela wykonany dość „kiepsko”, to jeszcze losowy. wstyd… UTK i unia europejska powinna się tym zająć. kolejna sprawa: gdyby dane były udostępniane w jakiś sensowny sposób, to nikt by nie musiał niczego scrapować. masakra.

    Odpowiedz
    • avatar
      2026.02.04 08:06 Jiiri

      Ja tam akurat (przynajmniej do niedawna) nie narzekałem na Portal Pasażera. Ma wszystkich przewoźników łącznie z RegioJetem oraz na bieżąco pokazuje opóźnienia tak samo, jak tablice w pociągach. Moim zdaniem to bardzo użyteczne narzędzie.

      Wyjaśnienia wymaga, rzecz jasna, opisany przez autora artykułu problem. Mam nadzieję, że PKP PLK S.A. nie zamiecie problemu pod dywan.

      Odpowiedz
  • avatar
    2026.02.03 22:21 Kadoo

    Mnie tylko ciekawi po ilu zapytaniach system uznaje cię za scrappera. Bo po trzech tysiącach to raczej na pewno możesz mieć problem… (razem z kilkoma tysiącami innych podpiętych pod ten sam adres)

    Odpowiedz
    • avatar
      2026.02.04 02:04 Michał Leszczyński

      Żeby nie było, ja nigdy nie scrapowałem Portalu Pasażera, aż do momentu jak bez powodu uznał mnie za bota i zaczął mi losować rozkłady. Dopiero wtedy puściłem pierwszą serię 3k requestów w ramach analizy.

      Na jednej z grup Facebookowych kilku użytkowników zaobserwowało efekt dokładnie ten sam, co na nagraniu w artykule, pomimo że też nigdy nie scrapowali.

      Odpowiedz
  • avatar
    2026.02.03 22:42 Dawid

    Netia i Plus – brak losowości 🤔

    Odpowiedz
  • avatar
    2026.02.03 22:58 Jędrek

    Niemcy, internet kablowy O2: brak losowości

    Odpowiedz
  • avatar
    2026.02.03 23:03 Grzegorz

    Mobile Vikings (korzystają chyba z nadajników Play) zwraca powtarzalne, spójne wyniki.

    Odpowiedz
  • avatar
    2026.02.04 08:11 Mateusz

    Sprawdziłem na internecie z plusa, brak losowości. Podejrzewam, że albo wyłączyli to faktycznie pod wpływem publikacji, albo adresy IP dla których randomizacja była ustawiona jednak relatywnie bardzo mała. No ale w sumie dlaczego takie rozwiązanie a nie prosty rate limiter żeby scrapperów wyeliminować to nie wiem.

    Odpowiedz
  • avatar
    2026.02.04 08:31 Andrzej

    Testowałem na kilku kartach sim. Również z plusa. Wszędzie wyniki powtarzalne i prawidłowe. Coś ta historia śmierdzi, przyznajesz się do łamania ich regulaminu i dziwisz się że dostajesz po łapach…

    Odpowiedz
    • avatar
      2026.02.04 20:47 adamh

      Może w końcu wyłączyli. Coś ten komentarz śmierdzi PKP ;)

      Odpowiedz
  • avatar
    2026.02.04 08:40 Bunio

    Ciekawy artykuł, ale może zamiast uderzać w zabezpieczenia tego lub innego portalu przed scrapingiem (lesze lub gorsze, dobrze czy głupio wdrożone) warto uwagę skierować gdzie indziej, czyli na operatorów internetowych, którzy od lat odwlekają pełne wdrożenie IPv6. To właśnie powszechne stosowanie współdzielonych adresów IPv4 sprawia, że pojedynczy użytkownik może zostać „ukarany” za działania kogoś zupełnie obcego, korzystającego z tego samego adresu IP. W takiej sytuacji nawet najlepiej zaprojektowane zabezpieczenia takiego czy innego serwisu będą wyglądały jak losowe lub zwyczajnie ułomne. Dopóki każdy użytkownik nie będzie miał realnie własnej, publicznej tożsamości sieciowej podobne problemy będą wracać niezależnie od tego, jak działa ta czy inna usługa. Może więc zamiast krytykować skutki, warto głośniej mówić o przyczynie zbyt wolnej migracji do IPv6?

    Odpowiedz
  • avatar
    2026.02.04 10:16 Mirek

    Jak to czytam to myślę gdzie ja żyję. Czy tam nikt kurna nie myśli. Taka losowość wyświetlona niewłaściwej osobie w najgorszym przypadku zepsuje dzień i nerwy a może doprowadzić do straty pieniędzy, spóźnienia do pracy i wielu innych konsekwencji. Nie wspominając już o osobach niepełnosprawnych dla których wszystko jest trudniejsze.

    Odpowiedz
  • avatar
    2026.02.04 18:36 Marcin

    Fajna ta odpowiedź od rzecznika. Taka w stylu „dostajesz losowy rozkład jazdy i nic nam nie zrobisz”.

    Odpowiedz
  • avatar
    2026.02.04 19:39 Mariusz

    Rozwiązanie mówiąc wprost idiotyczne. Ale lepiej zapytać: czy ono jest w ogóle legalne? Czy można legalnie wprowadzać kogoś w błąd lub nie, w zależności od decyzji jakiegoś automatycznego systemu wykrywającego boty (a te systemy nieomylne nie są i nigdy nie będą).

    Co innego gdy system wyświetli captchę lub nawet błąd. Wtedy wiadomo, że coś nie działa i można sprawdzić gdzieś indziej. Ale jeśli system celowo dezinformuje pasażerów… brak słów.

    Problem będzie coraz większy. Wykruszają się ostatni operatorzy, którzy dawali automatycznie i za darmo publiczne IP. CGNAT w sieciach komórkowych był od dawna, ale teraz wielu operatorów stacjonarnych zaczęło go używać. Na światłowodzie chyba Netia niedawno przestała dawać publiczne adresy i wprowadziła CGNAT, a np. Play miał CGNAT od dawna.

    Odpowiedz

Zostaw odpowiedź

Jeśli chcesz zwrócić uwagę na literówkę lub inny błąd techniczny, zapraszamy do formularza kontaktowego. Reagujemy równie szybko.

Kto i dlaczego losuje w Polsce rozkład jazdy PKP

Komentarze