Przeprowadziłem małe testy - wywaliłem preg_match'owanie logina oraz hasła i testowałem różne znaki - czy po ich wpisaniu w login/hasło nie będzie problemów z rejestracją, czy będzie można się później zalogować i czy login będzie dobrze wyświetlany na stronie. Hasło przed zapisaniem do bazy jest hashowane. Kodowanie w bazie: utf8_unicode_ci, na stronie - utf-8. Oto wyniki testów:
Cytat
`~!@#$%^&*/()rejestracja:
OKlogowanie:
OKwyświetlanie na stronie:
OK-=_+[] {};:,.?<>|*
(tam w środku jest też spacja)
rejestracja:
OKlogowanie:
OKwyświetlanie na stronie:
OK'"\
rejestracja: przez strlen interpetowane jako 6 znaków -
\'\"\\ (przynajmniej u mnie, to zależy chyba od tego, czy magic_quotes'owanie są włączane)
logowanie:
OK wyświetlanie na stronie: wyświetlane jako
\'\"\\ - wystarczy dać wyświetlanie w stripslashes (wywala slashe) i będzie się dobrze wyświetlać (no i przy sprawdzaniu długości ciągu, poprzez strlen, sprawdzać tak: strlen(stripslashes($_POST['login'])). Ale dając stripslashes do bazy (wyczyszczenie ze slashy) musimy być pewni, że mamy dobrze zabezpieczoną komunikację z bazą - bindowanie zmiennych używanych w zapytaniach SQL (np. przy pomocy PDO), które może przesłać użytkownik. Można zapisywać do bazy bez wywalania slashy (chociaż stosując bindowanie rozsądniej jest wywalać slashe), a tylko przy wyświetlaniu na stronie te slashe wywalać, bo jak już zaznaczyłem - z logowaniem nie ma kłopotów. Ale z drugiej strony, jeżeli mamy w bazie limit znaków na np. login, to jeżeli w loginie będzie w sumie 20 znaków (przy limicie 20) i w tym np. jeden znak cudzysłowia, skrypt będzie chciał zapisać do bazy ciąg z 21 znakami, więc prawdopodobnie zapisze pierwszych 20, co z kolei przełoży się na niemożność zalogowania się. Co do hasła - jeżeli jest hashowane, nie ma problemu - wywalamy slashe, hashujemy hasło i zapisujemy do bazy. Co do limitu zero kłopotu - nie wiem nawet jaki, i czy jest limit ciągu, który można shashować np. w md5, ale zapewniam że tego limitu (jeżeli istnieje) przy takim czymś nie przekroczymy
łńćżźąśóęĘÓĄŚŁŻŹĆŃrejestracja: Każdy z tych znaków przez funkcję strlen interpretowany jest jako 2 znaki - i poprawnie, bo w utf-8 zapisywane one są jako dwa znaki. Mam blokadę na długość loginu/hasła w php, więc zarejestrowanie nie powiodło się - wywaliło komunikat o tym, że login/hasło za długie. Ale istnieje nieco rozszerzona funkcja strlen - mb_strlen. Przyjmuje dwa argumenty - ciąg to sprawdzenia i kodowanie. Jeżeli mamy stronę i bazę na utf-8, podajemy jako drugi argument "utf-8" i już ładnie polskie znaki interpetowane są jako pojedyncze znaki

Ale wtedy w bazie trzebaby powiększyć aktualny limit 2x - gdyby ktoś wpisał 20 polskich znaków (lub ',",\), w bazie potrzebaby miejsca na 40 znaków. A jeżeli chcielibyśmy udostępnić znaki więcej niż 2 bitowe (np. chińskie) - najlepiej dać limit na $naszlimit*8 (w UTF-8 - jak sama nazwa mówi, mogą w nim być max. 8-bitowe znaki), np. w moim przypadku - 160.
logowanie:
OK wyświetlanie na stronie:
OK Wnioski:
Problemy są tylko z polskimi znakami i znakami ['\"], lecz tak jak to opisałem powyżej - wszystko to można obejść, pamiętając jednocześnie o ustawieniu dobrego limitu znaków w bazie. Można też po prostu zdjąć limity - ustawić pole login na TEXT, a nie VARCHAR albo CHAR z określonym limitem. Co do różnic między tymi trzema rodzajami troche poczytałem w necie, no i prawdopodobnie wyszukiwanie w bazie przy pomocy LIKE dla VARCHAR'a i pewnie CHAR'a jest szybsze niż w przypadku TEXT (choć nie jestem pewien). No i pola TEXT nie można zindeksować, w przeciwieństwie do VARCHAR i CHAR.
Testami tymi dowiodłem, że nie trzeba walidować ani hasła, ani loginu, jeżeli się wszystkiego dopilnuje
Komentarze mile widziane
Jeszcze mam pytanie co do bezpieczeństwa - czy używając PDO i bindując dane, na które ma wpływ użytkownik, można już do bazy wprowadzać dane po stripslash'owaniu (po wywaleniu slashów)? PDO ma chyba jakieś zabezpieczenia od tego.