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. Koszmar…

Zaufana Trzecia Strona

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.

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.

Katalog Polskich Firm z Sektora Cyberbezpieczeństwa

Cyber Katalog to niezależna platforma gromadząca zweryfikowane polskie firmy specjalizujące się w cyberbezpieczeństwie. Naszą misją jest wspieranie decydentów w wyborze rzetelnych partnerów do ochrony zasobów cyfrowych.

Copyright © 2026 Cyber Katalog. Wszelkie prawa zastrzeżone.

Projekt i wykonanie: Silesian Solutions

Zespół Cyber Katalog nie świadczy usług doradczych przy wyborze dostawców. Naszą misją jest rozwój polskiej branży cybersecurity. Tworzymy niezależną przestrzeń, w której decydenci mogą łatwo nawiązywać kontakt ze sprawdzonymi firmami. To specjaliści oferujący zaawansowane usługi z zakresu ochrony cyfrowej i bezpieczeństwa IT.

Zwiększ widoczność w branży cyberbezpieczeństwa

Dodaj swoją firmę