Diferència entre revisions de la pàgina «SQL injection»

De Cacauet Wiki
Salta a la navegació Salta a la cerca
Línia 69: Línia 69:
 
== PDO vs mysqli ==
 
== PDO vs mysqli ==
 
Hi ha 2 llibreries per accedir MySQL des de PHP. Ambdúes se suposa que no permeten fer 2 queries seguides (per seguretat). Però els resultats pràctics son:
 
Hi ha 2 llibreries per accedir MySQL des de PHP. Ambdúes se suposa que no permeten fer 2 queries seguides (per seguretat). Però els resultats pràctics son:
* [https://uf.ctrl-alt-d.net/material/mostra/50/php-acces-a-dades-amb-pdo PDO]: sí que permet fer 2 queries seguides
+
* [https://uf.ctrl-alt-d.net/material/mostra/50/php-acces-a-dades-amb-pdo PDO]: <strike>sí que permet fer 2 queries seguides</strike> Amb php 7.x ja no passa (en anteriors versions caldria revisar-ho)
 
* mysqli: NO permet fer 2 queries seguides
 
* mysqli: NO permet fer 2 queries seguides

Revisió del 09:28, 1 des 2017

SQL injection és una forma d'atac cibernètic per manipular la base de dades remota a través dels formularis.

Introducció

Una bona manera d'introduir-se a aquest tema és amb aquest acudit:

http://stackoverflow.com/questions/332365/how-does-the-sql-injection-from-the-bobby-tables-xkcd-comic-work?rq=1

Fes-li un cop d'ull a aquest article també:

http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php?rq=1


Coneixements previs

Cal que coneixem el llenguatge de programació PHP i el llenguatge de manipulació de dades SQL.


Un petit exemple amb LOGIN

Qualsevol formulari on l'usuari pugui entrar text lliure pot ser un punt vulnerable. Per exemple, el formulari de login típic per entrar al sistema.

En aquest exemple tenim la taula d'usuaris típica:

mysql> desc users;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(11)      | NO   | PRI | NULL    | auto_increment |
| username | varchar(200) | YES  |     | NULL    |                |
| name     | varchar(200) | YES  |     | NULL    |                |
| password | varchar(600) | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+
4 rows in set (0,01 sec)

En aquest cas, tenim diversos usuaris: enric, crypto, pepa i manolo. La password està encriptada amb SHA2-512

El més habitual és entrar el teu nom d'usuari i la password, i llavors entraríem amb l'usuari.

Fixeu-vos en què la sentència SQL que apareix abans del formulari no hi hauria de ser, la hem posat per il·lustrar quin serà la manera de perpetrar la injecció.

Sqlinjection1.png


La sentència que hem executat utilitza el username i password que l'usuari ha subministrat.

Però si enlloc de posar el nom d'usuari posem una sentència SQL hàbil i preclara, podem manipular la query que finalment enviarem a la base de dades. En el següent exemple, enlloc del nom d'usuari entrarem:

enric' or 1=1; -- lala'

...que es transformarà en el següent:

SELECT * FROM users WHERE username='enric' or 1=1; -- lala' AND password=SHA2('asd',512);

El què hi ha després de la "--" es transforma en un comentari, pel que s'ignora. I al haver posat "OR 1=1", ens donarà TRUE per a tots els registres.

I el resultat serà aquest:

Sqlinjection3.png

...que com podreu imaginar, és una possible manera de liar el codi i efectuar un "fals positiu" i entrar amb el nom d'usuari que vulguem (o que puguem, que en segons quina situació pot ser suficient per entrar en algun lloc amb privilegis).


PDO vs mysqli

Hi ha 2 llibreries per accedir MySQL des de PHP. Ambdúes se suposa que no permeten fer 2 queries seguides (per seguretat). Però els resultats pràctics son:

  • PDO: sí que permet fer 2 queries seguides Amb php 7.x ja no passa (en anteriors versions caldria revisar-ho)
  • mysqli: NO permet fer 2 queries seguides