Diferència entre revisions de la pàgina «SQL injection»
(Hi ha 11 revisions intermèdies del mateix usuari que no es mostren) | |||
Línia 1: | Línia 1: | ||
SQL injection és una forma d'atac cibernètic per manipular la base de dades remota a través dels formularis. | SQL injection és una forma d'atac cibernètic per manipular la base de dades remota a través dels formularis. | ||
+ | |||
+ | #FpInfor #Daw #DawMp07 #DawMp07Uf3 #DawMp07Uf03 #Ceti #Ciber #CetiMp03 #CiberMp03 | ||
== Introducció == | == Introducció == | ||
Línia 6: | Línia 8: | ||
http://stackoverflow.com/questions/332365/how-does-the-sql-injection-from-the-bobby-tables-xkcd-comic-work?rq=1 | 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 | + | Fes-li un cop d'ull a aquests articles també per veure solucions: |
http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php?rq=1 | http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php?rq=1 | ||
+ | https://diego.com.es/tutorial-de-pdo | ||
<br> | <br> | ||
Línia 16: | Línia 19: | ||
* [[Curs de PHP]] | * [[Curs de PHP]] | ||
* [[Curs de SQL]] | * [[Curs de SQL]] | ||
− | * Partirem d' | + | * Partirem d'aquests exemples: |
+ | ** Utilitzant [https://uf.ctrl-alt-d.net/material/mostra/50/php-acces-a-dades-amb-pdo PDO] | ||
+ | ** Utilitzant mysqli [[PHP MySQL select]] | ||
<br> | <br> | ||
== Un petit exemple amb LOGIN == | == 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 | + | 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; | mysql> desc users; | ||
+----------+--------------+------+-----+---------+----------------+ | +----------+--------------+------+-----+---------+----------------+ | ||
Línia 38: | Línia 42: | ||
En aquest cas, tenim diversos usuaris: enric, crypto, pepa i manolo. La password està encriptada amb SHA2-512 | 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: | + | 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ó. | ||
+ | |||
+ | [[Fitxer:Sqlinjection1.png|600px]] | ||
+ | |||
+ | ---- | ||
+ | |||
+ | 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: | ||
+ | |||
+ | [[Fitxer:Sqlinjection3.png|600px]] | ||
+ | |||
+ | ...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). | ||
+ | |||
+ | <br> | ||
+ | |||
+ | == Llibreries == | ||
+ | Hi ha 2 llibreries per accedir MySQL des de PHP. Ambdúes se suposa que NO permeten fer 2 queries seguides (per seguretat). | ||
+ | * [https://uf.ctrl-alt-d.net/material/mostra/50/php-acces-a-dades-amb-pdo PDO] | ||
+ | * [http://php.net/manual/es/book.mysql.php mysql original] (obsoleta) | ||
+ | * [http://php.net/manual/es/book.mysqli.php mysqli : mysql millorada] | ||
+ | |||
+ | Si es permetés això (en anteriors versions sí que passava), què creus que passaria si introdueixo això com a nom d'usuari? | ||
+ | enric' or 1=1; drop table usuaris; -- lala | ||
+ | |||
+ | |||
+ | |||
+ | == Protecció == | ||
+ | En aquest exemple amb PDO es pot veure [https://www.php.net/manual/es/pdostatement.bindparam.php#refsect1-pdostatement.bindparam-examples com protegir la query PDO] perquè no sigui vulnerable a SQL injection. | ||
− | + | Es tracta d'utilitzar les sentències '''prepare''' i '''bindParam''' abans de l'execute. |
Revisió de 18:13, 12 nov 2021
SQL injection és una forma d'atac cibernètic per manipular la base de dades remota a través dels formularis.
#FpInfor #Daw #DawMp07 #DawMp07Uf3 #DawMp07Uf03 #Ceti #Ciber #CetiMp03 #CiberMp03
Introducció[modifica]
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 aquests articles també per veure solucions:
http://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php?rq=1 https://diego.com.es/tutorial-de-pdo
Coneixements previs[modifica]
Cal que coneixem el llenguatge de programació PHP i el llenguatge de manipulació de dades SQL.
- Curs de PHP
- Curs de SQL
- Partirem d'aquests exemples:
- Utilitzant PDO
- Utilitzant mysqli PHP MySQL select
Un petit exemple amb LOGIN[modifica]
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ó.
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:
...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).
Llibreries[modifica]
Hi ha 2 llibreries per accedir MySQL des de PHP. Ambdúes se suposa que NO permeten fer 2 queries seguides (per seguretat).
- PDO
- mysql original (obsoleta)
- mysqli : mysql millorada
Si es permetés això (en anteriors versions sí que passava), què creus que passaria si introdueixo això com a nom d'usuari?
enric' or 1=1; drop table usuaris; -- lala
Protecció[modifica]
En aquest exemple amb PDO es pot veure com protegir la query PDO perquè no sigui vulnerable a SQL injection.
Es tracta d'utilitzar les sentències prepare i bindParam abans de l'execute.