Bezpečnost je zajímavý pojem a přitahuje k němu spoustu lidí. Bohužel je to složité téma a i profesionálové se v něm pletou. Našel jsem bezpečnostní díry v Googlu (CSRF), Facebooku (více CSRF), několika velkých online prodejcích (hlavně SQL injection / XSS) a také tisících menších webů, firemních i osobních.
Toto jsou moje doporučení:
1) Použijte parametrizované dotazy
Parametrizované dotazy nutí k tomu, aby se s hodnotami předanými do dotazu zacházelo jako se samostatnými daty, takže vstupní hodnoty nemohou být systémem DBMS analyzovány jako kód SQL. Mnoho lidí vám doporučí, abyste své řetězce opustili pomocí mysql_real_escape_string()
, ale na rozdíl od všeobecného přesvědčení to není univerzální řešení pro SQL injection. Vezměte si například tento dotaz:
SELECT * FROM users WHERE userID = $_GET['userid']
Pokud $_GET['userid']
je nastaven na 1 OR 1=1
, neobsahuje žádné speciální znaky a nebude filtrováno. Výsledkem jsou vráceny všechny řádky. Nebo ještě hůř, co když je nastaveno na 1 OR is_admin = 1
?
Parametrizované dotazy zabraňují tomuto druhu injekce.
2) Ověřte své vstupy
Parametrizované dotazy jsou skvělé, ale někdy mohou neočekávané hodnoty způsobit problémy s vaším kódem. Ujistěte se, že ověřujete, že jsou v dosahu a že nedovolí aktuálnímu uživateli změnit něco, co by neměl mít možnost.
Můžete mít například formulář pro změnu hesla, který odešle požadavek POST skriptu, který změní jejich heslo. Pokud umístíte jejich ID uživatele jako skrytou proměnnou do formuláře, mohli by to změnit. Odesílání id=123
místo id=321
může znamenat, že změní heslo někoho jiného. Ujistěte se, že VŠECHNO je správně ověřeno, pokud jde o typ, rozsah a přístup.
3) Použijte htmlspecialchars k opuštění zobrazeného uživatelského vstupu
Řekněme, že váš uživatel zadá své „o mně“ přibližně takto:</div><script>document.alert('hello!');</script><div>
Problém s tím je, že váš výstup bude obsahovat označení, které uživatel zadal. Zkoušet to sami filtrovat pomocí blacklistů je prostě špatný nápad. Použijte htmlspecialchars
k odfiltrování řetězců, aby se značky HTML převedly na entity HTML.
4) Nepoužívejte $_REQUEST
Útoky CSRF (Cross-site request forgery) fungují tak, že přimějí uživatele kliknout na odkaz nebo navštívit adresu URL, která představuje skript, který provádí akci na webu, pro který je přihlášen. $_REQUEST
proměnná je kombinací $_GET
, $_POST
a $_COOKIE
, což znamená, že nemůžete rozeznat rozdíl mezi proměnnou odeslanou v požadavku POST (tj. prostřednictvím input
tag ve vašem formuláři) nebo proměnná, která byla nastavena ve vaší adrese URL jako součást GET (např. page.php?id=1
).
Řekněme, že uživatel chce někomu poslat soukromou zprávu. Mohou odeslat požadavek POST na sendmessage.php
, s to
, subject
a message
jako parametry. Nyní si představme, že někdo místo toho pošle požadavek GET:
sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!
Pokud používáte $_POST
, neuvidíte žádný z těchto parametrů, protože jsou nastaveny v $_GET
namísto. Váš kód neuvidí $_POST['to']
nebo kteroukoli z dalších proměnných, takže zprávu neodešle. Pokud však používáte $_REQUEST
, $_GET
a $_POST
zaseknou se, takže útočník může nastavit tyto parametry jako součást adresy URL. Když uživatel navštíví tuto adresu URL, neúmyslně odešle zprávu. Opravdu znepokojující je, že uživatel nemusí nic dělat. Pokud útočník vytvoří škodlivou stránku, může obsahovat iframe
který ukazuje na URL. Příklad:
<iframe src="http://yoursite.com/sendmessage.php?to=someone&subject=SPAM&message=VIAGRA!">
</iframe>
To má za následek, že uživatel posílá zprávy lidem, aniž by si kdy uvědomil, že něco udělal. Z tohoto důvodu byste se měli vyhnout $_REQUEST
a použijte $_POST
a $_GET
místo toho.
5) Považujte vše, co dostanete, za podezřelé (nebo dokonce škodlivé)
Nemáte ponětí, co vám uživatel posílá. Mohlo by to být legitimní. Může to být útok. Nikdy nevěřte ničemu, co vám uživatel poslal. Převeďte na správné typy, ověřte vstupy, použijte bílé listiny k filtrování tam, kde je to nutné (vyhněte se blacklistům). To zahrnuje vše odeslané prostřednictvím $_GET
, $_POST
, $_COOKIE
a $_FILES
.
Pokud se budete řídit těmito pokyny, budete z hlediska bezpečnosti na rozumné úrovni.