PDA

View Full Version : [PHP] SQL-INJECTION


bio n3t
04-08-2009, 18:48
Ciao a tutti, premetto che programmo in PHP da pochissimo. Ho sentito parlare di SQL-Injection dal mio prof e mi sono informato su cos'è. Ho capito il funzionamento, ma per prevenire questi attacchi non ho le idee chiarissime... però mi è venuta in mente una soluzione (che probabilmente esiste già) cioè controllare col javascript ogni singolo carattere inserito nel form (ad esempio dando un range dei caratteri ASCII validi) e se qualche carattere può risultare pericoloso il login fallisce, altrimenti si procede con lo script di login. Può essere un idea fattibile? Ce ne sono altre molto più semplici da implementare? La mia idea è facilmente bypassabile? Grazie a tutti quelli che risponderanno in anticipo ;)

vizzz
04-08-2009, 20:49
Ciao a tutti, premetto che programmo in PHP da pochissimo. Ho sentito parlare di SQL-Injection dal mio prof e mi sono informato su cos'è. Ho capito il funzionamento, ma per prevenire questi attacchi non ho le idee chiarissime... però mi è venuta in mente una soluzione (che probabilmente esiste già) cioè controllare col javascript ogni singolo carattere inserito nel form (ad esempio dando un range dei caratteri ASCII validi) e se qualche carattere può risultare pericoloso il login fallisce, altrimenti si procede con lo script di login. Può essere un idea fattibile? Ce ne sono altre molto più semplici da implementare? La mia idea è facilmente bypassabile? Grazie a tutti quelli che risponderanno in anticipo ;)

http://it.wikipedia.org/wiki/SQL_injection

queste sono le idee di base, conta che esistono funzioni specifiche di php proprio per queste necessità e anche funzioni specifiche per il motore sql (ad esempio per mysql)

amedeoviscido
04-08-2009, 20:58
Utilizzare solo javascript non è abbastanza, basta infatti avere un tool specifico per disabilitarlo, così la tua protezione cadrebbe.

La prima cosa da fare è vietare l'utilizzo del carattere di apice nei campi username e password, se li utilizzi tu all'interno delle query sql; questo però non è abbastanza, in quanto potrebbero utilizzare dei valori che fanno inceppare l'engine sql. Bisogna fare uno studio approfondito che, come già suggerito, dipende dal motore sql che utilizzi.

Una veloce ricerca ha tirato fuori questo esempio:

<?php
// Quote variable to make safe
function quote_smart($value)
{
// Stripslashes
if (get_magic_quotes_gpc()) {
$value = stripslashes($value);
}
// Quote if not a number or a numeric string
if (!is_numeric($value)) {
$value = "'" . mysql_real_escape_string($value) . "'";
}
return $value;
}

// Connect
$link = mysql_connect('mysql_host', 'mysql_user', 'mysql_password')
OR die(mysql_error());
// Make a safe query
$query = sprintf("SELECT * FROM users WHERE user=%s AND password=%s",
quote_smart($_POST['username']),
quote_smart($_POST['password']));

mysql_query($query);
?>

nuovoUtente86
04-08-2009, 22:01
Javascript non serve a nulla in questi casi, perchè la richiesta può essere inviata bypassando il js stesso.

Barbalbero
04-08-2009, 22:10
L'utilizzo di JEE invece di PHP è un buon rimedio

nuovoUtente86
04-08-2009, 22:31
L'utilizzo di JEE invece di PHP è un buon rimedio

Non vuol dire assolutamente nulla. Tutti i linguaggi server side forniscono gli strumenti necessari, a patto che il programmatore sia in grado di saperli far fruttare.
Per quanto nn mi piaccia il PHP non è in questa circostanza che si può mettere in evidenza la superiorità di altri linguaggi come J2EE.

Barbalbero
04-08-2009, 22:42
io parlo per esperienza personale. Non conosco molto php, ma conosco bene il problema della injection. In JEE l'injection è difficile che funzioni persino se il progettista si impegna a fare in modo che funzioni.

Esempio:

public boolean login(String username, String password) {
Query q=em.createQuery("FROM Utente u WHERE u.username=:PARAM");
q.setParameter("PARAM", username);
Utente u =(Utente)q.getSingleResult();
if(u.getPassword().equals(password)) return true;
else return false;
}


Il controllo della password viene fatto tramite codice java, pertanto non è soggetto al tipico "or username=username" nel WHERE (per fare un esempio, non ricordo la sintassi).
Inoltre ho provato anche a inserire injection con DROP TABLE ecc, prese da siti qua e là e non hanno mai funzionato, senza che io progettista nemmeno ci pensassi ad evitare che funzionassero.
Infine utilizzando JPQL invece di SQL puro si rende la vita ancora più difficile all'aspirante hacker

tomminno
04-08-2009, 23:29
io parlo per esperienza personale. Non conosco molto php, ma conosco bene il problema della injection. In JEE l'injection è difficile che funzioni persino se il progettista si impegna a fare in modo che funzioni.

Esempio:

public boolean login(String username, String password) {
Query q=em.createQuery("FROM Utente u WHERE u.username=:PARAM");
q.setParameter("PARAM", username);
Utente u =(Utente)q.getSingleResult();
if(u.getPassword().equals(password)) return true;
else return false;
}


Il controllo della password viene fatto tramite codice java, pertanto non è soggetto al tipico "or username=username" nel WHERE (per fare un esempio, non ricordo la sintassi).
Inoltre ho provato anche a inserire injection con DROP TABLE ecc, prese da siti qua e là e non hanno mai funzionato, senza che io progettista nemmeno ci pensassi ad evitare che funzionassero.
Infine utilizzando JPQL invece di SQL puro si rende la vita ancora più difficile all'aspirante hacker

Beh stai attribuendo al linguaggio JEE una caratteristica del DBMS che sono i prepared statement.
Che mi dici di questo?

$dbConnection = new mysqli("localhost", "user", "pass", "db");
$statement = $dbConnection->prepare("SELECT * FROM Utente u WHERE u.username = ?");
$statement->bind_param("s", $username);
$statement->execute();

Fa esattamente quello che hai scritto te in Java (nel mio caso verso MySQL).
Come vedi in questo caso il linguaggio non c'entra niente.

demos88
04-08-2009, 23:40
se usi il php, penso che una funzione addslashes() possa prevenire la maggior parte dei tentativi (banali) di injection.
Eventualmente la funzione dedicata per il mysql è mysql_real_escape_string.
In pratica non fa altro che aggiungere dei caratteri di escape prima dei caratteri speciali. Rimangono fuori alcuni caratteri quali % che viene usato nella sintassi del LIKE, eventualmente lo correggi a mano, sempre via php.

bio n3t
05-08-2009, 00:20
ok alcune cose le ho capite cioè quello che mi interessava.. alcuni di voi sono troppo tecnici non mi sforzo nemmeno a cercare di capire :D:D
comunque il link di wikipedia è molto esaustivo grazie.
quindi ci sono gli strumenti apposta lato server è inutile che provo altri metodi.
vi ringrazio! ciao! :)

nuovoUtente86
05-08-2009, 00:38
Beh stai attribuendo al linguaggio JEE una caratteristica del DBMS che sono i prepared statement.
Che mi dici di questo?

$dbConnection = new mysqli("localhost", "user", "pass", "db");
$statement = $dbConnection->prepare("SELECT * FROM Utente u WHERE u.username = ?");
$statement->bind_param("s", $username);
$statement->execute();

Fa esattamente quello che hai scritto te in Java (nel mio caso verso MySQL).
Come vedi in questo caso il linguaggio non c'entra niente.
Lui non ha utilizzato utilizzato gli statement, ma ha sfruttato le potenzialità lato container attraverso gli ejb session ed entity. Ma concordo pienamente con il fatto che i controlli siano fattibili con qualsiasi linguaggio, anche se devo dire che il tuo codice non mi sembra del tutto immune, ma bisognerebbe vederlo tutto.

tomminno
05-08-2009, 12:27
Lui non ha utilizzato utilizzato gli statement, ma ha sfruttato le potenzialità lato container attraverso gli ejb session ed entity. Ma concordo pienamente con il fatto che i controlli siano fattibili con qualsiasi linguaggio,


Quello però non ha niente a che vedere con la protezione da sql injection, è solo un livello di astrazione in più dovuto all'ORM che mappa la tabella su un oggetto.
Scrivere:

"FROM Utente u WHERE u.username=:PARAM"
q.setParameter("PARAM", username);

Indica una query parametrica a cui viene fatto il bind con la variabile username allo stesso identico modo di questo:

"SELECT * FROM Utente u WHERE u.username = ?"
$statement->bind_param("s", $username);//s indica che la variabile username è di tipo stringa

Linguaggio diverso ma la sostanza non cambia, il livello di protezione da sql injection è il medesimo.
Con questo codice posso benissimo evitare i controlli per i classici casi di inserimento/ricerca per cognomi contenenti il carattere ' è il dbms che sa che tutto quello che gli sto passando sono dati e non dati con istruzioni.


anche se devo dire che il tuo codice non mi sembra del tutto immune, ma bisognerebbe vederlo tutto.

I difetti che puoi riscontrare sono gli stessi dell'equivalente in Java o qualunque altro linguaggio.
Senza ulteriori controlli a monte gli attacchi injection che possono andare a segno sono quelli che fanno schiantare il dbms con sequenze particolari di dati, ma questo rientrerebbe più nei bug di sicurezza del dbms che non del codice utente.
Chiaramente il mio era solo un codice di esempio che traduceva il codice java di cui sopra per quanto riguarda la parte di sql injection.

ckingpin
05-08-2009, 14:40
ciao, ti passo la funzione che ho creato anni fà per l'esame di php


// controlla i valori nell'array $_POST
function SQL_Injection(){
foreach ($_POST as $chiave => $elemento) {
// elimino i caratteri _ e % sensibili per le query sql con LIKE
$_POST["$chiave"] = str_replace("_", "", $_POST["$chiave"]);
$_POST["$chiave"] = str_replace("%", "", $_POST["$chiave"]);
//sostituisco le parentesi angolari, onde evitare la creazione di codice html
$_POST["$chiave"] = str_replace("<", "&lt;", $_POST["$chiave"]);
$_POST["$chiave"] = str_replace(">", "&gt;", $_POST["$chiave"]);
//rimuovo gli spazi all'inizio e alla fine
$_POST["$chiave"] = trim($_POST["$chiave"]);
// se magic_quotes_gpc è disattivo, mi appoggio a mysql_real_escape_string() contro attacco di tipo SQL Injection
if ( !get_magic_quotes_gpc() ) {
// e quoto i caratteri \ " ' sensibili per php
$_POST["$chiave"] = mysql_real_escape_string($_POST["$chiave"]);
}
}
}


ti basta invocarla ogni volta che c'è un post di dati da una form, questa funzione si spazzola tutto l'array POST e previene sia l'injection di sql sia di html sia di php (e trimma anche gli spazi e fà anche il caffè...giacchè ci si trova :D )

bio n3t
05-08-2009, 14:53
ciao, ti passo la funzione che ho creato anni fà per l'esame di php


// controlla i valori nell'array $_POST
function SQL_Injection(){
foreach ($_POST as $chiave => $elemento) {
// elimino i caratteri _ e % sensibili per le query sql con LIKE
$_POST["$chiave"] = str_replace("_", "", $_POST["$chiave"]);
$_POST["$chiave"] = str_replace("%", "", $_POST["$chiave"]);
//sostituisco le parentesi angolari, onde evitare la creazione di codice html
$_POST["$chiave"] = str_replace("<", "&lt;", $_POST["$chiave"]);
$_POST["$chiave"] = str_replace(">", "&gt;", $_POST["$chiave"]);
//rimuovo gli spazi all'inizio e alla fine
$_POST["$chiave"] = trim($_POST["$chiave"]);
// se magic_quotes_gpc è disattivo, mi appoggio a mysql_real_escape_string() contro attacco di tipo SQL Injection
if ( !get_magic_quotes_gpc() ) {
// e quoto i caratteri \ " ' sensibili per php
$_POST["$chiave"] = mysql_real_escape_string($_POST["$chiave"]);
}
}
}


ti basta invocarla ogni volta che c'è un post di dati da una form, questa funzione si spazzola tutto l'array POST e previene sia l'injection di sql sia di html sia di php (e trimma anche gli spazi e fà anche il caffè...giacchè ci si trova :D )

hehehe perfetto mi sei stato utilissimo per capire... soprattutto perchè è molto semplice grazie ai commenti... grazie!! :D

ckingpin
05-08-2009, 14:55
hehehe perfetto mi sei stato utilissimo per capire... soprattutto perchè è molto semplice grazie ai commenti... grazie!! :D

all'epoca ero diligente e commentavo tutto (grazie al c.... scrivevo 10 righe di codice al giorno... :D)

malocchio
06-08-2009, 11:02
ciao, ti passo la funzione che ho creato anni fà per l'esame di php


// controlla i valori nell'array $_POST
function SQL_Injection(){
foreach ($_POST as $chiave => $elemento) {
// elimino i caratteri _ e % sensibili per le query sql con LIKE
$_POST["$chiave"] = str_replace("_", "", $_POST["$chiave"]);
$_POST["$chiave"] = str_replace("%", "", $_POST["$chiave"]);
//sostituisco le parentesi angolari, onde evitare la creazione di codice html
$_POST["$chiave"] = str_replace("<", "&lt;", $_POST["$chiave"]);
$_POST["$chiave"] = str_replace(">", "&gt;", $_POST["$chiave"]);
//rimuovo gli spazi all'inizio e alla fine
$_POST["$chiave"] = trim($_POST["$chiave"]);
// se magic_quotes_gpc è disattivo, mi appoggio a mysql_real_escape_string() contro attacco di tipo SQL Injection
if ( !get_magic_quotes_gpc() ) {
// e quoto i caratteri \ " ' sensibili per php
$_POST["$chiave"] = mysql_real_escape_string($_POST["$chiave"]);
}
}
}


ti basta invocarla ogni volta che c'è un post di dati da una form, questa funzione si spazzola tutto l'array POST e previene sia l'injection di sql sia di html sia di php (e trimma anche gli spazi e fà anche il caffè...giacchè ci si trova :D )
Per queste cose molto delicate non ci si può affidare a soluzioni self-made. Non puoi mai sapere che non ti scappi qualche possibile exploit, e comunque devi essere molto preparato nei dettagli.
Secondo me è meglio usare funzioni dedicate specificatamente allo scopo, come la mysql_escape_string().
In PHP io ho utilizzato SEMPRE i prepared statements. Sono comodi e sicuri (non posso dirlo al 100%, però...).

all'epoca ero diligente e commentavo tutto (grazie al c.... scrivevo 10 righe di codice al giorno... :D)

Il 90% dei commenti che vedo in quel codice non ci vanno. Sarai messo alla gogna :O
:D :D

bio n3t
06-08-2009, 11:20
volevo chiedervi un'altra cosa dato che mi sembrate preparatissimi in materia:
avete presente il codice che genera adobe dreamweaver automaticamente se si crea un recordset? ecco... quel codice mi sembra incomprensibile in alcuni punti che vi farò vedere... (cioè solo la parte iniziale dove effettua la connessione (quindi non parlo del ciclo che scrive i dati)). due domande:
1_ vi sembra buono come codice a livello di sicurezza e ottimizzazione? (a parte la query che ho fatto ora: SELECT * FROM tblUtenti)
2_ potreste descrivermi brevemente cosa fa codice? perchè vista così mi crea molta confusione... ve lo riporto qui.
GRAZIE!! :D


<?php require_once('configurazione_connessione.php'); ?>
<?php
if (!function_exists("GetSQLValueString")) { // non capisco
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") // non capisco
{
$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue; // non capisco

$theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue); // non capisco

switch ($theType) { // non capisco proprio nulla XD
case "text":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "long":
case "int":
$theValue = ($theValue != "") ? intval($theValue) : "NULL";
break;
case "double":
$theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL";
break;
case "date":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "defined":
$theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
break;
}
return $theValue;
}
}

// da qui in poi ci arrivo da solo più o meno ;)
mysql_select_db($database_my_bion3t, $my_bion3t);
$query_Recordset1 = "SELECT * FROM tblUtenti";
$Recordset1 = mysql_query($query_Recordset1, $my_bion3t) or die(mysql_error());
$row_Recordset1 = mysql_fetch_assoc($Recordset1);
$totalRows_Recordset1 = mysql_num_rows($Recordset1);
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Documento senza titolo</title>
</head>

<body>
</body>
</html>
<?php
mysql_free_result($Recordset1); // non capisco
?>

ckingpin
06-08-2009, 11:39
Per queste cose molto delicate non ci si può affidare a soluzioni self-made. Non puoi mai sapere che non ti scappi qualche possibile exploit, e comunque devi essere molto preparato nei dettagli.
Secondo me è meglio usare funzioni dedicate specificatamente allo scopo, come la mysql_escape_string().
In PHP io ho utilizzato SEMPRE i prepared statements. Sono comodi e sicuri (non posso dirlo al 100%, però...).

infatti c'è la escape string :D



Il 90% dei commenti che vedo in quel codice non ci vanno. Sarai messo alla gogna :O
:D :D


...vedi che ho fatto bene allora a togliermi il vizio di commentare? quei commenti erano didattici e servivano a far capire al prof che avevo capito......

malocchio
06-08-2009, 11:42
volevo chiedervi un'altra cosa dato che mi sembrate preparatissimi in materia:
avete presente il codice che genera adobe dreamweaver automaticamente se si crea un recordset? ecco... quel codice mi sembra incomprensibile in alcuni punti che vi farò vedere... (cioè solo la parte iniziale dove effettua la connessione (quindi non parlo del ciclo che scrive i dati)). due domande:
1_ vi sembra buono come codice a livello di sicurezza e ottimizzazione? (a parte la query che ho fatto ora: SELECT * FROM tblUtenti)
2_ potreste descrivermi brevemente cosa fa codice? perchè vista così mi crea molta confusione... ve lo riporto qui.
GRAZIE!! :D


<?php require_once('configurazione_connessione.php'); ?>
<?php
if (!function_exists("GetSQLValueString")) { // non capisco
function GetSQLValueString($theValue, $theType, $theDefinedValue = "", $theNotDefinedValue = "") // non capisco
{
$theValue = get_magic_quotes_gpc() ? stripslashes($theValue) : $theValue; // non capisco

$theValue = function_exists("mysql_real_escape_string") ? mysql_real_escape_string($theValue) : mysql_escape_string($theValue); // non capisco

switch ($theType) { // non capisco proprio nulla XD
case "text":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "long":
case "int":
$theValue = ($theValue != "") ? intval($theValue) : "NULL";
break;
case "double":
$theValue = ($theValue != "") ? "'" . doubleval($theValue) . "'" : "NULL";
break;
case "date":
$theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
break;
case "defined":
$theValue = ($theValue != "") ? $theDefinedValue : $theNotDefinedValue;
break;
}
return $theValue;
}
}

// da qui in poi ci arrivo da solo più o meno ;)
mysql_select_db($database_my_bion3t, $my_bion3t);
$query_Recordset1 = "SELECT * FROM tblUtenti";
$Recordset1 = mysql_query($query_Recordset1, $my_bion3t) or die(mysql_error());
$row_Recordset1 = mysql_fetch_assoc($Recordset1);
$totalRows_Recordset1 = mysql_num_rows($Recordset1);
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Documento senza titolo</title>
</head>

<body>
</body>
</html>
<?php
mysql_free_result($Recordset1); // non capisco
?>


1) Non ha una vera e propria utilità: significa che non crea la funzione se già è stata creata. Considera che è codice auto-creato.

2) get_magic_quotes_gpc() (http://it.php.net/manual/en/function.get-magic-quotes-gpc.php) ritorna true o false in base all'impostazione magic_quotes dell'installazione di php, che è una funzionalità intergrata che si occupa di fare l'escape dei dati specificati negli array $_GET e $_POST.
Qui un bel link: LINK (http://it.php.net/manual/en/security.magicquotes.php) (è deprecata)
Se php fa l'escape di suo, viene eseguita la fuzione stripslashes() (http://it.php.net/manual/en/function.stripslashes.php) che annulla l'escape, altrimenti non fa niente ($theValue = $theValue).

3) $theValue è un dato di cui non conosciamo il tipo (sto parlando di tipi del Php). Tramite $theType si specifica il tipo di $theValue che ci si aspetta di avere e si fa la conversione esplita. Sempre che sia questo il tuo dubbio... conosci il costrutto switch...case vero?

4) mysql_free_result() (http://it.php.net/manual/en/function.mysql-free-result.php) è una funzione usata per chiudere il recordset e liberare la memoria occupata da esso; questo lo rende inutilizzabile.

Lo so che non mi sono spiegato benissimo e in caso chiedi, come sempre ;)

malocchio
06-08-2009, 11:44
infatti c'è la escape string :D





...vedi che ho fatto bene allora a togliermi il vizio di commentare? quei commenti erano didattici e servivano a far capire al prof che avevo capito......

Ah sì scusa, ho letto le prime righe e mi sono prevenuto, come sempre :ave:

maledetti prof :doh:

bio n3t
06-08-2009, 12:09
1) Non ha una vera e propria utilità: significa che non crea la funzione se già è stata creata. Considera che è codice auto-creato.

2) get_magic_quotes_gpc() (http://it.php.net/manual/en/function.get-magic-quotes-gpc.php) ritorna true o false in base all'impostazione magic_quotes dell'installazione di php, che è una funzionalità intergrata che si occupa di fare l'escape dei dati specificati negli array $_GET e $_POST.
Qui un bel link: LINK (http://it.php.net/manual/en/security.magicquotes.php) (è deprecata)
Se php fa l'escape di suo, viene eseguita la fuzione stripslashes() (http://it.php.net/manual/en/function.stripslashes.php) che annulla l'escape, altrimenti non fa niente ($theValue = $theValue).

3) $theValue è un dato di cui non conosciamo il tipo (sto parlando di tipi del Php). Tramite $theType si specifica il tipo di $theValue che ci si aspetta di avere e si fa la conversione esplita. Sempre che sia questo il tuo dubbio... conosci il costrutto switch...case vero?

4) mysql_free_result() (http://it.php.net/manual/en/function.mysql-free-result.php) è una funzione usata per chiudere il recordset e liberare la memoria occupata da esso; questo lo rende inutilizzabile.

Lo so che non mi sono spiegato benissimo e in caso chiedi, come sempre ;)

no no figurati sei stato più che bravo a spiegare... il fatto è che io sono noob perciò non capisco subito.. il problema sono io non te :D

1) ok ho capito ;)

2) mi sembra di avere capito leggendo un pò su internet... che converte la stringa in una innoqua mettendo gli slash?

3) si conosco lo switch, in pratica in base al tipo di variabile mette gli apici se è testo.. oppure lo converte in integer o in double a seconda dei casi e così via.. giusto? però qui ho due domande:
_ non capisco cosa sia questo $TheValue
_ non capisco cosa fa questo codice (mi sembra di capire che è una forma abbreviata dell'IF?) $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";

alla fine tutto sto pòpòdiroba serve per mettere i simboli giusti per il $TheValue? ma serve solo nel caso in cui i dati siano presi da una form o anche se si fa un semplice SELECT *?

4) ok questo l'ho capito... in alcuni tutorial usano my_sql_close($connessione) o una cosa del genere..? in ogni caso chiude la connessione ok...

un ultima cosa: quindi se si usa questo codice va bene? cioè non ci sono problemi di sql-injection?

ti ringrazio!!! :D

tomminno
06-08-2009, 12:09
infatti c'è la escape string :D


Si ma è sempre a carico del programmatore, sia mai che ti dimentichi il controllo su qualche campo o ti arriva un dato da qualche flusso non controllato.
Usando i prepared statement, intanto puoi evitare un sacco di controlli pressochè inutili e poi per lo meno sei sicuro che non ti sfugge niente.
Il codice infine diventa molto più chiaro.
Oltretutto anche in PHP realizzare una struttura a 3 livelli non guasterebbe.
Che fai replichi i controlli anti injection ad ogni passo?

ckingpin
06-08-2009, 13:55
Si ma è sempre a carico del programmatore, sia mai che ti dimentichi il controllo su qualche campo o ti arriva un dato da qualche flusso non controllato.
Usando i prepared statement, intanto puoi evitare un sacco di controlli pressochè inutili e poi per lo meno sei sicuro che non ti sfugge niente.
Il codice infine diventa molto più chiaro.
Oltretutto anche in PHP realizzare una struttura a 3 livelli non guasterebbe.
Che fai replichi i controlli anti injection ad ogni passo?

io ho fatto quella funzione per invocarla ogni volta che l'array POST è pieno :) certo si può migliorare sia la gestione che l'invocazione, ma intanto il 30 e lode per il progetto lo presi! :D

malocchio
06-08-2009, 14:48
no no figurati sei stato più che bravo a spiegare... il fatto è che io sono noob perciò non capisco subito.. il problema sono io non te :D

1) ok ho capito ;)

2) mi sembra di avere capito leggendo un pò su internet... che converte la stringa in una innoqua mettendo gli slash?

3) si conosco lo switch, in pratica in base al tipo di variabile mette gli apici se è testo.. oppure lo converte in integer o in double a seconda dei casi e così via.. giusto? però qui ho due domande:
_ non capisco cosa sia questo $TheValue
_ non capisco cosa fa questo codice (mi sembra di capire che è una forma abbreviata dell'IF?) $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";

alla fine tutto sto pòpòdiroba serve per mettere i simboli giusti per il $TheValue? ma serve solo nel caso in cui i dati siano presi da una form o anche se si fa un semplice SELECT *?

4) ok questo l'ho capito... in alcuni tutorial usano my_sql_close($connessione) o una cosa del genere..? in ogni caso chiude la connessione ok...

un ultima cosa: quindi se si usa questo codice va bene? cioè non ci sono problemi di sql-injection?

ti ringrazio!!! :D

Prima di tutto ti serve sapere precisamente cos'è quel var = (expr1 ? expr2 : expr3). L'hai praticamente già detto, è un if abbreviato. Si chiama operatore ternario. La differenza con l'if è che invece di specificare delle istruzioni all'interno specifichi dei valori. Poi in base alla condizione espr1, l'operatore restituisce expr2 se expr1 è true oppure expr3 se expr1 è false. Il codice sopra si traduce così:
if (expr2) {
var = expr2;
} else {
var = expr3;
}
Può essere inserito in una qualsiasi espressione da valutare.

Allora, diciamocela tutta, quella funzione serve per preparare i dati da inserire all'interno di una query. Quindi se devo inserire un intero, questa funzione viene richiamata, per ESEMPIO
getSQLValueString('1', 'int');
come vedi l'1 è sì un 1, ma è un dato inserito in una stringa. Tramite stripshalshes() si sbarazza di eventuali apici o caratteri di escape inseriti dai magic_quotes. Tramite mysql_escape_string() fa l'escape appropriato, rendendo innoquo il dato.
Lo switch sotto l'hai capito, prende il valore specifico (quindi se deve essere un intero estrae tramite intval() il valore intero e così via) e lo inserisce in una stringa alla quale aggiunge gli apici all'inizio e fine (visto che all'interno della query conviene inserire i dati tra apici).

Nel mio post precedente ho fatto un po' di confusione perché ho saltato il punto su mysql_escape_string()...

Nel tuo post precedente, il punto 2 è corretto se riferito a mysql_escape_string. stripslashes ha una funzione in un certo modo "contraria" a mysql_escape_string, in quanto rimuove l'eventuale escape effettuato dai magic_quotes.

Sì, questa funzione serve per inserire in sicurezza all'interno di una query dei dati che provengono dall'input dell'utente. Se la query è sempre fissa ovvero non ha parametri variabili, la funzione non ha scopo perché la query la scrivi tu, dall'inizio fino alla fine.

Punto 4) mysql_close è leggermente diversa: serve per chiudere la connessione al database. Dopo la chiamata a mysql_close non puoi più effettuare query. mysql_free_result invece libera la memoria occupata dal resultset, ma puoi ancora fare tutte le query che vuoi sulla connessione.

Non possiamo dirlo con una certezza del 100%, ma questa funzione sembra efficace per proteggersi dall'injection. La chiamata a mysql_escape_string è la parte che fa il più del lavoro.

bio n3t
06-08-2009, 15:04
grazie mille malocchio!!! mi hai scritto un tutorial in tempo reale... non potevi fare di meglio per farmi capire come funzionasse!!! :D:D
ti offro una birretta per sdebitarmi :cincin: :D :D e grazie ancora!

malocchio
06-08-2009, 15:13
grazie mille malocchio!!! mi hai scritto un tutorial in tempo reale... non potevi fare di meglio per farmi capire come funzionasse!!! :D:D
ti offro una birretta per sdebitarmi :cincin: :D :D e grazie ancora!

Eheh figurati... ogni tanto faccio un salto anche nella sezione modding, quindi potrei trovarti lì in giro...

Ciao :D

bio n3t
06-08-2009, 15:48
Eheh figurati... ogni tanto faccio un salto anche nella sezione modding, quindi potrei trovarti lì in giro...

Ciao :D

hehe ok allora in caso avrai bisogno tu riguardo il modding... ti darò una mano per quel poco che so :D

tomminno
06-08-2009, 22:38
io ho fatto quella funzione per invocarla ogni volta che l'array POST è pieno :) certo si può migliorare sia la gestione che l'invocazione, ma intanto il 30 e lode per il progetto lo presi! :D

Ciò non toglie che sia un metodo sbagliato per affrontare il problema realmente.
Oltretutto in quel modo vai a modificare tutti i dati in post che magari non riguardano il database e che non dovrebbero essere modificati.
Infine per trasformare caratteri speciali potevi usare htmlentities, senza reinventare la ruota per l'ennesima volta ;)