Sparametryzowane wywołanie procedur składowanych zabezpiecza przed SQL Injection. Ale jeśli będziemy to wywołanie sklejali ze stringów, to może nam to nic nie dać. O ile w przypadku MySQL ciężko będzie to wykorzystać, bo mysql_query nie zezwala na więcej niż jedną instrukcję, to dla innych baz już takiego ograniczenia nie ma:
<?php
// SQL Server
$_GET["user_id"] = "1234; DROP TABLE users";
$query = "EXEC getUserById " . $_GET["user_id"];
echo $query; // EXEC getUserById 1234; DROP TABLE users
$result = sqlsrv_query( $conn, $query ); // Instrukcje wykonają się poprawnie. Obie.
?>
Chodzi mi o to, że najwyższy już czas przedstawiać użytkownikom nowoczesne rozwiązania problemów. Funkcje mysql_* siedzą w pehapie już od przeszło dziesięciu lat. Doczekały się następców, nieobarczonych charakterystycznymi dla nich problemami (ręczne zabezpieczanie przed sql injection, błędy zamiast wyjątków, itd.). Ale pomimo to są w 90% przypadków przedstawiane jako podstawowe rozwiązanie problemu wykorzystania baz danych w php.
Co ciekawe gdy ludzie zadają na stackoverflow pytania odnośnie C#, nie dostają odpowiedzi z stylu "hmm... nie podałeś wersji .NET pod którą piszesz, więc na wszelki wypadek podam ci rozwiązanie dla .NET 1.1 z 2001 roku". Nie, zamiast tego piszą "W .NET 4.0 możesz bardzo łatwo zrobić to przy użyciu XXX oraz YYY (...)". Dzięki temu wiesz jak rozwiązać problem, lub szukasz odpowiedników XXX i YYY dla starszej wersji .NET.
Więc zgadzam się ze wszystkim o czym mówisz, oprócz:
Cytat
Programista wielokrotnie musi grzebać w czyimś kodzie, który "pierwszej świeżości" być nie musi
Otóż świeży kod, datowany na 2011 rok, również jest pisany przy użyciu mysql_* i zabezpieczany ręcznie przy użyciu mysql_real_escape_string, co nie zawsze się młodym programistom udaje, przykład:
// albo
mssql_query
( "SELECT * FROM users WHERE username = '" . addslashes( $_GET["name"] ) . "'" );
Dlatego ja nadal obstaję przy swoim i uważam, że aby pisać kod zabezpieczony przed SQL Injection, należy korzystać z prepared statements. A gdy już na prawdę nie ma innej możliwości, to wtedy czytamy o addslashes, magic_quotes, mysql_real_escape_string, rzutowaniu na typy liczbowe, itd. Może dzięki temu kilku początkujących zacznie pisać swoje pierwsze zapytania od razu w PDO.