21:27
9/10/2014

Jeden z naszych czytelników “Andzik” zauważył ciekawy błąd w aplikacji mobilnej sieci sklepów Piotr i Paweł. Dzięki dziurze i prostemu trikowi, aplikacja pozwalała każdemu na pobranie danych osobowych stałych klientów sklepu. Taki fuckup wykorzystać mogłaby np. konkurencjna sieć hipermarketów, która przy pomocy promocji mogłaby przejąć wartościowych klientów.

Na czym polegał błąd?

Aplikacja mobilna Piotra i Pawła posiada funkcję przyśpieszającą zakładanie konta. Polega ona na wykorzystaniu kamery smartphona do zeskanowania kodu kreskowego karty stałego klienta — po odczytaniu kodu kreskowego, formularz rejestracji konta automagicznie wypełnia się danymi z karty (pobieranymi z serwera PiP na podstawie numeru klienta zakodowanego w kodzie kreskowym).

Są to:

    imię i nazwisko
    adres e-mail
Aplikacja Piotra i Pawła

Aplikacja Piotra i Pawła

Ktoś jednak nie do końca przemyślał tę funkcję… Jak pisze nasz czytelnik:

Aplikacja PiP umożliwia pobieranie danych klienta automatycznie, po zeskanowaniu kodu kreskowego w formacie EAN-13 zapisanego na plastikowej karcie wydanej wcześniej w sklepie. Dokonuje tego po szyfrowanym (SSL/TLS) połączeniu do serwerów OVH. (…) Innymi słowy: umożliwia pobranie danych (losowego) klienta poprzez przedstawienie dla skanera zgodnego kodu kreskowego.

Format kodów kreskowych EAN-13 to:

Format Kodu Kreskowego

Format Kodu Kreskowego

Jak zauważa Andzik, format kodów kreskowych EAN-13 dla kart stałego klienta jest zgodny ze standardem, tj:
2 011100 XXXXX Y
gdzie:
Y - cyfra kontrolna
X - kod produktu
(aczkolwiek możliwe, iż część “kodu wytwórcy” zmienia się wraz z rozrostem ilości wydanych kart)

Enumeracja wszystkich kart jest więc możliwa — wystarczy wybrać dowolne 5 cyfr, podstawić pod pola oznaczone jako X i wyliczyć sumę kontrolną, np. za pomocą tego generatora

W ten sposób można wygenerować, np. te 2 przykładowe kody:

2 011100 12345 0
png;base6449c9b33d7cdfae90

2 011100 12346 7
png;base64fdb07171dc9dadd2

Jeden pozwala pobrać dane Pana Jerzego, drugi pozwala pobrać dane Pana Arkadiusza — o czym przekonujemy się skanując wizualizacje kodów:

Pobranie danych klienta Piotra i Pawła na podstawie wygenerowanego kodu

Pobranie danych klienta Piotra i Pawła na podstawie wygenerowanego kodu

Teraz już posta droga, aby z “wiarygodnego” konta założonego na dane klienta zacząć trolling…

Przypominamy, że w podobny sposób kilka lat temu generowaliśmy fałszywe karty lojalnościowe do IKEI, które m.in. dają dostęp do darmowej kawy :)

Co na to Piotr i Paweł

Próbowaliśmy się skontaktować z Piotrem i Pawłem. Była to droga przez mękę. Pierwszy raz napisaliśmy e-maila 9 września na adres rzecznika prasowego, p. Ewy Aleszczyk-Kalinowskiej. Cisza. Ponowiliśmy próbę kontaktu 19 września. Dalej cisza. 26 września napisaliśmy, że dłużej nie czekamy i publikujemy artykuł, niech się dzieje, co ma się dziać. Dopiero wtedy pani Ewa Aleszczyk-Kalinowska, dyrektor departamentu marketingu i PR, odpowiedziała.

Uprzejmie dziękujemy za zgłoszenie możliwości nieuprawnionego pobrania danych z naszej aplikacji mobilnej Piotr i Paweł.

Nasz system został przygotowany z zachowaniem wszelkich niezbędnych środków zabezpieczających dane osobowe naszych klientów,
Wykonawcą aplikacji była firma Serious Impact.

Po informacji z Państwa strony, ww. firma w trybie natychmiastowym usunęła opisaną przez Państwa lukę w konstrukcji całego systemu aplikacji.

Przeprowadzona obecnie analiza danych pozwoliła stwierdzić, iż nie doszło do masowego wycieku danych.

Zmiana polega na tym, że próba zeskanowania kodu najprawdopodobniej została całkiem zablokowana po stronie API — każde naciśnięcie (dalej istniejącego w aplikacji przycisku “zeskanuj kartę”) kończy się bowiem komunikatem:

Jak można naprawić tego typu błąd logiczny w aplikacji?

“Dziury”, jak zauważa Andzik, można było w prosty sposób uniknąć, np. wprowadząc wymóg uwierzytelnienia się klienta przed wysłaniem zapytania poprzez API do bazy klientów. Uwierzytelnienie mogłoby odbywać się poprzez podanie np. e-maila.

Drugą alternatywną proponowaną przez czytelnika metodą jest — po zeskanowaniu numeru karty — wysłanie e-maila z linkiem, który klient musi kliknąć aby potwierdzić posiadanie karty. Dopiero wtedy jego dane są dodawane do aplikacji.

PS. Jeśli interesuje Was analiza aplikacji mobilnych pod kątem bezpieczeństwa, przypominamy, że 23-24 października prowadzimy szkolenie z tego tematu w Krakowie. Wciąż są wolne miejsca!


Dowiedz się, jak zabezpieczyć swoje dane i pieniądze przed cyberprzestępcami. Wpadnij na nasz kultowy ~3 godzinny wykład pt. "Jak nie dać się zhackować?" i poznaj kilkadziesiąt praktycznych i przede wszystkim prostych do zastosowania porad, które skutecznie podniosą Twoje bezpieczeństwo i pomogą ochronić przed atakami Twoich najbliższych. Uczestnicy tego wykładu oceniają go na: 9,34/10!

Na ten wykład powinien przyjść każdy, kto korzysta z internetu na smartfonie lub komputerze, prywatnie albo służbowo. Wykład prowadzimy prostym językiem, wiec zrozumie go każdy, także osoby spoza branży IT. Dlatego na wykład możesz spokojnie przyjść ze swoimi rodzicami lub mniej technicznymih znajomych. W najbliższych tygodniach będziemy w poniższych miastach:

Zobacz pełen opis wykładu klikając tutaj lub kup bilet na wykład klikając tu.

62 komentarzy

Dodaj komentarz
  1. “Po informacji z Państwa strony, ww. firma w trybie natychmiastowym usunęła opisaną przez Państwa lukę w konstrukcji całego systemu aplikacji.”

    No tak, wyłączyli możliwość dodawania karty w apce mobilnej. Brawo, problem solved :D

    • Postąpili najsłuszniej jak mogli. Luka jest, dość poważna, więc do czasu opracowania lepszego rozwiązania i jego dokładnego przetestowania (co pewnie potrwa dłużej niż dzień), wyłączyli dostęp do tej funkcjonalności szczególnie, że nie jest ona jakoś szczególnie konieczna.

      Postąpiłbym podobnie w tej sytuacji – szybka reakcja, a następnie opracowanie kompleksowej łatki. Mam nadzieję, że tego tak nie zostawią ;-)

    • Funkcjonalność =/= funkcja

      To, że brzmi mądrzej wcale nie oznacza, że jest synonimem.

    • @Emil

      No cóż, widać sporo osób łyknęło ten marketingowy bełkot i nomenklaturę stosowaną przez krawaciarzy z korpo;]

    • “Modna” ostatnio walka “funkcjonalność vs funkcja” dotarła już nawet na niebezpiecznika.

      A więc podpowiem, że funkcja sama w sobie jest funkcjonalna, a więc wyłączając tę funkcję, wyłącza się również funkcjonalność, jaką ona zapewniała.

    • @Paweł

      Dokształć się, “młody pelikanie”;]
      http://filolozka.brood.pl/funkcja-a-funkcjonalnosc/
      http://wittamina.pl/funkcjonalnosc-czy-funkcja/

    • „(dalej istniejącego w aplikacji przycisku «zeskanuj kartę») kończy się bowiem komunikatem:” („Nieprawidłowy kod kreskowy”) — Rety! Jak ja nie cierpię, kiedy aplikacja robi z użytkownika idiotę! Człowiek traci czas na kolejne próby, kombinowanie co może robić nie tak, co producent (w tym przypadku lamerzy „Piotr i Paweł”) mógł zrobić nie tak, czy pisać maila z pytaniem, zgłaszać problem, może zadzwonić… No masakra, a tu Piotr i Paweł całkiem świadomie robi w durnia swoich użytkowników…

    • Wystarczyło napisać dwa słowa: „Funkcja wyłączona”, ale nie — matołki mimo wszystko wolały zrobić durniów ze swoich użytkowników: „Nieprawidłowy kod kreskowy” — czyli powtarzaj do skutku…

    • Prawdopodbnie aplikacja mobilna w obecnej wersji nie ma możliwości wyświetlenia innego komunikatu. Można to zmienić jedynie poprzez wydanie nowszej wersji aplikacji, ale to nie rozwiązuje problemu problemu ludzi posiadających starą wersję.

    • Zoltar – masz rację, ale pewnie API zwraca status błędu a to aplikacja wyświetla tekst adekwatny do statusu. Idąc dalej tą drogą wychodzi, że nie mieli innego statusu na tą okoliczność i zastosowali takie rozwiązanie. Całościowo pewnie musieliby zaktualizować i API (o nowy status) i aplikację (o jego obsługę) – a jeśli już tę by aktualizowali to mogli w ogóle na formularzu to wyłączyć (co nie?). No ale tak było szybciej i taniej :)
      Co nie zmienia faktu, że nie jest to poprawne rozwiązanie zaistniałej sytuacji.

    • @Łukasz
      “Postąpiłbym podobnie w tej sytuacji – szybka reakcja, a następnie opracowanie kompleksowej łatki. Mam nadzieję, że tego tak nie zostawią ;-)”

      Gorzej, że dopiero musieli przeczytać, że zostaną opisani na łamach niebezpiecznika, by jakoś zareagować :D

      Do tego to nie jest aplikacja używana w domu(chyba..) więc wystarczyłoby gdyby w sklepie pani/pan za kasą mówił: “proszę o zaktualizowanie aplikacji” :D

    • @ogot68 Toz to poprostu kalka z angielskiego jakich wiele, szczegolnie w informatyce. Patrzac na obecna tendencje proponuje sie przyzwyczajac zamiast doksztalcac.

    • Najlepszy sposób to najłatwiejszy sposób ;)

    • @Łukasz , szybko to by było gdyby zrobili to 10 września. A oni czekają całe tygodnie a potem robią łatkę na szybko.

  2. “z Piotrem i Pawełem”. ;)

  3. Skoro po kontakcie druga strona milczała, to i tak sporo czekaliście na publikacje tego artykułu ;)

  4. Ciekawe, na pewno powinna to być nauczka dla firm wykonujących soft na zlecenie: myśleć samodzielnie zamiast na ślepo wykonywać wszystko, co chce klient. Bo zapewne odbyło się to tak, że PiP chciał “aby klient miał jak najłatwiej” – a wykonawca nie zauważył potencjalnego zagrożenia…

    Swoją drogą – jeżeli zawiodła kontrola na poziomie projektu, to nawet średnio rozgarnięty programista powinien podczas pisania zauważyć lukę i zgłosić…

    • Programista nie ma tutaj nic do rzeczy, może jedynie zasugerować usprawnienia ale kiedy klient oczekuje maksymalnej prostoty to taką się mu dostarcza.

    • Zgadza się, ale pamiętaj, że klient nie musi być wyczulony na bezpieczeństwo i nie musi zauważyć potencjalnego zagrożenia. Klient widzi zadowolonych użytkowników którzy w łatwy sposób używają aplikacji. Od tego, by klienta sprowadzać na ziemię jest ktoś, kto będzie system projektował. Jeżeli on tego nie przewidzi, to ostatnim ‘bezpiecznikiem’ powinien być programista, względnie ogarnięty tester. Ty sugerujesz, że można wypuścić jakiś badziew, bo klient chciał – zapominasz, że narażasz wtedy klientów PiP na wyciek ich danych.

      Sam jako programista miałem sytuację, gdzie zgłaszałem podobne błędy w logice oprogramowania. Bo zostały przeoczone w fazie projektowania, a i na testach mogło by to nie wyjść na jaw.

    • @Po co

      Rozumiem, ze jakby klient zarzadal samochodu bez hamulcow to firma tez powinna stworzyc i puscic go na droge ? Jak bank zarzada systemu, ktory nie bedzie w zaden sposob szyfrowany/ uwierzytelniany/ whatever to tez mu takowy wykonasz ? To juz nie mozna odmowic wykonania PARTACKIEJ uslugi ? Nie masz odrobiny dumy i odpowiedzialnosci za produkt, ktory oferujesz ? To gratulacje za tok myslenia rodem z PRL ^^

    • @Rafał, myślę, że czytasz to co ktoś pisze z równą uwagą jak kolega niżej.
      @Jarro, czytaj ze zrozumieniem wtedy nie będziesz musiał niczego “rozumieć”.

      “…może jedynie zasugerować usprawnienia…”

    • Moim skromnym zdaniem to nie wina wykonawcy, a zamawiającego oprogramowanie. Podanie w komunikacie nazwy firmy- wykonawcy jest sui generis krzywdzącym wskazaniem “winnego”, a prawdziwym sprawcą jest moim zdaniem firma PiP i chora chęć uproszczenia interfejsu klientowi (ew. błąd testera w co jednak trudno mi uwierzyć- przeoczenie takiej rzeczy?). Sorry ale przerabiałem już tyle gamoni, które chciały zrobić coś na szybko aby klient miał max 2 kliknięcia – dział bezpieczeństwa / it może zaopiniować, dać rekomendacje. W korpo niestety zawsze decyduje biznes / managment po zaopiniowaniu i w świadomości ryzyka :(.

  5. Ciekawe jak zachowują się inne appki tej firmy :) Na próbę: http://serious-impact.com/project/show/id/58/LOTOS.html

  6. Dla zorientowanych zasłonięcie danych Pana Jerzego nie wiele zmienia. Pozdrawiam studentów elektroniki WAT :P

  7. Piotr i Paweł ma od zawsze fatalną komunikację z klientem więc nie dziwi mnie ta sytuacja z rzeczniczką.

  8. E, mogli generować QR z losowym kodem (kluczem per-klient) o rozmiarze np. 128 bitów. Wtedy enumeracja raczej by się nie udała…

    • CIekaw jestem jak pani Zosia na kasie odczyta taki QR, aby nabić punkty lojalnościowe czy inne pierdółki.

    • Ja tam wprawdzie się nie znam, ale nie jestem przekonany, że w PiP na kasach mają czytniki QR-kodów.

    • No dobra. To może taki alfanumeryczny 1D, po prostu o większej przestrzeni klucza. Lenovo chyba takie nakleja na opakowania z laptopami i desktopami – zawierają tekst ASCII.
      Nie pamiętam, który to kod, ale coś z rodziny “Code *” (Code 128?).

      Na 100% użycie UPC/EAN nie było zbyt dobrą decyzją pod kątem bezpieczeństwa.

      Nasuwa się za to ciekawsza kwestia: kiedy będziemy w stanie enumerować by PESEL?

    • Pisząc o PESELu sugerujesz trudność w iteracjach po dacie, numerze od 0000-9999 w tym płci (0-9) i tyle bo sumę kontrolną liczysz? Moje bliźniaki wpuściły między siebie 28-21=7 dzieci, których PESEL znam z dokładnością do płci, która to wygląda na jedyny losowany składnik.

  9. Zabezpieczenie polega na odpięciu obsługi eventu od przycisku czy faktycznym wyłączeniu tego po stronie serwera? Mam dziwne przeczucie, że naprawa jest godna pierwotnego wykonania ;).

    • Też tak czuje :-) Że dziura po stronie backendu została. :-D

    • A łatwiej wyłączyć API na serwerze czy poprawić program i zaktualizować go na urządzeniach wszystkich użytkowników?

  10. …albo zmienić karty i zastosować kod obrazkowy. Przynajmniej dla nowych.

  11. Firma jest z Sosnowca, więc co tu od nich wymagać :]

    • Aleś się wysilił… Pewnie z Pcimia jesteś :P

    • @shen – nie, on z drugiej strony Brynicy…;]

  12. @mpan z pewnością było to wycięte w API, rolling update aplikacji mobilnej trwa u użytkowników wieki, tym bardziej, że nie wszyscy mają autoupdate’y
    @Zoltar jeśli jest wyłączone w API (czyli API zawsze zwraca “false” przy takim zapytaniu) to tekst jest wszyty w appkę – “niepoprawny kod” i nie da się tego zmienić bez wydania apki – dlatego takie zachowanie

    Co do sugestii zabezpieczeń z artykułu: ta funkcjonalność miała po zeskanowaniu kodu wypełnić użytkownikowi pole email i imię, nazwisko aby ułatwić rejestrację. Sugerowanie, że dobre zabezpieczenie to podawanie emaila przed zapytaniem do API sprawia, że cała funkcjonalność staje się bezużyteczna.

    Drugie sugerowane rozwiązanie mówi o mailu z linkiem – to kompletnie przerywa flow tego, co użytkownik chce zrobić. Musi w innej aplikacji, a najlepiej na komputerze coś klikać a potem wrócić do aplikacji PiP – to już nie chodzi o magiczne “usability” – po prostu większość użytkowników sobie z tym nie poradzi.

    Tak tylko chciałem uświadomić czytelników, że nawet taka “prosta” funkcjonalność z błędem logicznym generuje wiele zależności i nie ma tutaj łatwych rozwiązań z czego nie każdy zdaje sobie sprawę.

    • Nie rób proszę z ludzi idotów ;]

      A moim zdaniem (skoro karta w teorii jest przez kogoś wydawana) wystarczy dodać do niej kilku znakowy pin. Po każdym niepoprawnym podaniu kodu pin, zwiększenie okresu po jakim można spróbować ponownie. Po 10 nieudanych próbach, całkowita blokada. Wystarczy tylko chwile ruszyć makówką i chcieć przewidywać tego typu sytuacje.

      Doświadczenie z kartą i pinem ma chyba większość klientów.

  13. Można było zastosować bardziej pojemny CODE-128 i zakodować w nim, oprócz numeru klienta, losową sekwencję cyfr, małych i dużych liter jako klucz zabezpieczający. Rozwiązanie przypominałoby kod CVV1/CVC1 zapisany na pasku i w chipie karty płatniczej. Chyba, że czytniki kasowe obsługują tylko EAN ale wątpię bo obecnie produkowane czytniki radzą sobie z większością kodów 1D.

  14. Fajna nazwa firmy :D

  15. Rzeczywiście ten komunikat jest nietrafiony. Zamiast ‘Niepoprawny kod’ mogli napisać, że opcja tymczasowo niedostępna.

    • Myślę, że mają słabą obsługę błędów, tj. jedna ogólna wiadomość na wszystkie sytuacje. I tak 99% przypadków to będzie właśnie to. Nie zapominajmy, że to “aplikacja mobilna”, czyli zwykle coś taniego ;)

  16. Mogą przy generowaniu kodów kreskowych w kodzie wytwórcy zapisywać hash numeru klienta, a po tym jak ktoś poda więcej niż 3 różne kody z nieprawidłowym hashem uznawać klienta z intruza i blokować do czasu wyjaśnienia sprawy funkcjonalność dla jego adresu ip/mac.
    Być może nawet teraz już to tak działa i stąd ten niepoprawny komunikat dla usera.

    • Popieram plan blokowania na serwerze requestów po źródłowym adresie MAC przychodzących ramek. :D

  17. To nie dziura w aplikacji mobilnej, tylko po stronie serwera. :facepalm:

  18. A kto każe nam podawać prawdziwe dane zakłądając kartę lojalnościową? Nie chcę, żeby sieci mnie profilowały więc podaję fikcyjną tożsamość. Jeśli się zorientują to nawet nie mogą mnie za to ukarać.

    • W tego typu programach lojalnościowych nie mogą uczestniczyć osoby niepełnoletnie, więc tutaj musisz podac prawdziwe dane a pracownik zakładający kartę może sprawdzić dane z dowodem, szczególnie datę urodzenia.
      Jakbyś się zarejstrował – jako niepełnoletni – i potem dostał kupony na alkohol – wtedy taki PiP od razu dostałby po koncesji.

  19. Panowie i Panie jest inna aplikacja lepiej napisana firmy eLider ja tam zamawiam i płacę a zakupy same przyjadą :)
    https://play.google.com/store/apps/details?id=eu.eleader.piotripawel

  20. Nie można naprawić tej luki. Skanowanie jest po to aby użytkownik nie musiał żmudnie wprowadzać swoich danych. Wprowadzanie dodatkowych zabezpieczeń mija się z celem.

    • Można. Kody EAN-13 stosuje się do kodowania artykułów. Nigdy nie zakładano dla nich szczególnej tajności. Lepiej by się sprawdziło kodowanie Data Matrix, gdzie o wiele trudniej spoofować.

  21. Jestem poirytowany czytając takie historie! można by pomyśleć że to przypadek jednostkowy..ale tak nie jest..

    Firma z branży windykacyjnej, notowana na giełdzie…dziury jak we francuskim serze! + nadużycia którymi spokojnie mógłby zainteresować się inspektorat danych osobowych i co…

    Pierwszy mail do rzecznika – cisza
    Drugi mail do rzecznika – cisza
    Nie działało po prośbie to może po groźbie? – upublicznie tą informację na niebezpieczniku – cisza…

    Ktoś powie…to przypadek jednostkowy…
    Spółka akcyjna z branży metalurgicznej – dzwonie, chcę rozmawiać z prezesem bo mam bardzo poufną informacje – login: admin, hałso:admin do strony www firmy oczywiście nie mówię jej o tym, informuję o dużym zagrożeniu możliwym do wykorzystania przez np konkurencje.

    Sekretarka, nie wie o co chodzi…chcę rozmawiać z prezesem…prezes nie ma czasu…mówi cyt” nie wiem czy się tym zainteresuje..nie wiem…a Pan czego właściwie chce pyta ?
    – przeprowadzamy testy penetracyjne.
    – a co to?
    – symulowany atak na sieć firmy, badamy bezpieczeństwo, przygotowujemy raport.
    – dobrze..to ja połączę z informatykiem.

    Do licha! na co mi informatyk! chcę wykonać test penetracyjny..zarobić kasę…
    Polskie firmy w temacie bezpieczeństwa są jak koń zaciągnięty do pługa.

    może poczekam jeszcze 2-3 lata, albo zrobię deafce strony..i ostatecznie zgłoszą się do niebezpiecznika z prośbą o test penetracyjny…;)

    Jak żyć?

  22. Niebezpieczniku daliście plamę z tym zamazywaniem. Pana Jerzego (10 liter w nazwisku) bardzo łatwo znaleźć, bo nie zamazaliście domeny.

    • ale nie podali wprost danych, wiec sa czysci.

    • Czyści jak łza :-)

  23. hehe pewnie uszkodzone drzwi w autobusie czy tramwaju najlepiej zespawać

    • Może lepiej zdemontować.

  24. Wynika z tego, że hakerzy cały czas są lepiej wykształceni niż ci co powinni – to jest jakiś niesamowity absurd

    • Toś się wystawił (kosze ozdobne) :P

  25. Szczerze wątpię, by użycie akurat EAN-13 było konieczne. Wszystkie skanery kodów kreskowych obecne na rynku skanują wiele innych formatów, jak choćby drugi najpopularniejszy code128. Gdyby użyli tego formatu na kartach stałego klienta, otrzymaliby możliwość generowania długich kodów, które mogłyby składać się nie tylko z kolejnego numeru klienta, ale zawierać też hash wygenerowany na jego podstawie. Ochrona przed brute-forcowaniem byłaby wtedy dużo łatwiejsza, a sam proceder raczej niewarty świeczki.

  26. Sorry, że nie na temat, ale “polska język – trudny język”.
    “Drugą alternatywną”? A także trzecią, czwartą i kolejnymi?
    Ludzie! “Alternatywa” to wybór “albo-albo” nie ma więc “drugiej alternatywy” jest po prostu alternatywa. Przy większej liczbie możliwości można mówić o “opcjach”, “możliwościach” itp ale alternatywa to alternatywa i koniec. Chyba, ze macie na myśli “Alternatywy 4” :)

    • xkcd386 mode on

      “Druga alternatywa”, a nawet trzecia czy setna może być prawidłowym wyrażeniem, chociaż faktycznie zazwyczaj jest ono używane w niewłaściwym znaczeniu (jako druga, trzecia, setna opcja). Tutaj jednak jest użyty przymiotnik i dotyczy on rzeczownika “metoda”. Metoda jest alternatywna wobec innej metody. I takich metod jest wiele.

      Próbujesz właśnie przeprowadzić rozumowanie wg schematu: “drugi czarny kot” jest błędne, bo czerń może być tylko jedna.

      Z tym, że tutaj są przedstawione tylko dwie metody. Zatem powiedziałbym, że ze stylistycznego punktu widzenia “druga” i “alternatywna” to alternatywa.

      xkcd386 mode off

Odpowiadasz na komentarz Johnny

Kliknij tu, aby anulować

Zamieszczając komentarz akceptujesz regulamin dodawania komentarzy. Przez moderację nie przejdą: wycieczki osobiste, komentarze nie na temat, wulgaryzmy.

RSS dla komentarzy: