Fixing a sql injection

Σε αυτή την περιοχή μπορείτε να βρείτε ή να αναζητήσετε πληροφορίες σχετικές με την PHP

Συντονιστές: WebDev Moderators, Super-Moderators, PHP Moderators

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Fixing a sql injection

Δημοσίευση από Apostolis_38 » 10 Μαρ 2009 12:26

Το παράδειγμα το κατάλαβα :)
Για τα prepared statements είναι η απορία.

Αλλά τώρα μου δημιουργήθηκε καινούργια απορία.
Αν φτιάξεις ένα file, στο οποίο να ορίζεις με αυτό τον τρόπο κάθε μεταβλητή που χρησιμοποιείς στο site π.χ.

Κώδικας: Επιλογή όλων

$id = (int)$_GET['id']
με όλα τα καλούδια (addslashes/mysql_real_escape_string κ.λ.π. κ.λ.π.) όπου χρειάζεται,
τότε αυτόματα δεν περιορίζεις τα πιθανά sql_injections;

Απο άποψη επιβάρυνσης του server (επειδή συνέχεια θα κάνεις require το αρχείο αυτό) πιθανώς να μην πολυ συμφέρει, αλλά για την ασφάλεια νομίζω θα έχει τα ίδια αποτελέσματα με τα prepared statements.

Άβαταρ μέλους
cpulse
Script Master
Δημοσιεύσεις: 1527
Εγγραφή: 21 Μαρ 2006 19:30
Τοποθεσία: Αθήνα village
Επικοινωνία:

Fixing a sql injection

Δημοσίευση από cpulse » 11 Μαρ 2009 17:16

Αποστόλη πες οτι έχεις ένα απλό sql statement

Κώδικας: Επιλογή όλων

$name = "abc";
SELECT * FROM table WHERE name = '$name'
Η PHP θα κάνει την απαραίτητη αντικατάσταση και θα το στείλει στην MySQL σαν

Κώδικας: Επιλογή όλων

SELECT * FROM table WHERE name = 'abc'
Σε περίπτωση SQL injection υπάρχει το πρόβλημα οτι μπορεί κάποιος να στείλει για μεταβλητή κάτι σαν κι αυτό

Κώδικας: Επιλογή όλων

$name = "abc' AND id IN (INSERT INTO table VALUES ('def')) AND name = 'abc";
SELECT * FROM table WHERE name = '$name'
Η PHP θα κάνει την απαραίτητη αντικατάσταση και θα το στείλει στην MySQL σαν

Κώδικας: Επιλογή όλων

SELECT * FROM table WHERE name = 'abc' AND id IN (INSERT INTO table VALUES ('def')) AND name = 'abc'
Δηλαδή η PHP θα στείλει ένα προβληματικό query στην MySQL.

Αν έκανες το ίδιο με prepared statement θα έστελνες πρώτα στην MySQL το statement για να κάνει το parse της

Κώδικας: Επιλογή όλων

SELECT * FROM table WHERE name = ?
Και στην συνέχεια θα στείλεις και την παράμετρο για να γίνει το execution. Η διαφορά είναι οτι το parse έχει ήδη γίνει. Ό,τι και να στείλεις για παράμετρο η MySQL θα το βάλει μέσα στην παράμετρο, δεν θα το λάβει σαν νέα εντολή SQL.

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Fixing a sql injection

Δημοσίευση από Apostolis_38 » 11 Μαρ 2009 17:37

face control και στις μεταβλητές λοιπόν :D

Δηλαδή, αν κατάλαβα σωστά, με το prepared statement το οποιοδήποτε insert,delete ή ότι άλλο θα περάσει σαν χαρακτήρες αναζήτησης κι όχι σαν εντολή.
Οπότε απλώς θα επιστρέψει λάθος στην αναζήτηση.
Σωστά;

Άβαταρ μέλους
cpulse
Script Master
Δημοσιεύσεις: 1527
Εγγραφή: 21 Μαρ 2006 19:30
Τοποθεσία: Αθήνα village
Επικοινωνία:

Fixing a sql injection

Δημοσίευση από cpulse » 11 Μαρ 2009 18:06

Η επίσημη απάντηση θα ήταν.. θα επιστρέψει απρόβλεπτα αποτελέσματα :)

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Fixing a sql injection

Δημοσίευση από Apostolis_38 » 20 Μαρ 2009 18:09

Με τσακίσατε με τους εκσυγχρονισμούς σας :D

Μερικές ερωτησούλες για αρχή, γιατί όσο κι αν έψαξα δεν βρήκα άκρη:

MySQL version = Mysql Server 4.1.22
PHP = PHP 5.2.6

Κάπου διάβασα οτι δεν μπορεί τρέξει μόνιμο connect (mysql_pconnect) με mysqli. Αληθεύει; Υπάρχει κάποια εναλλακτική, δεν βρήκα τίποτα στο γούγλη.

Αρκεί να δηλωθεί στο php.ini το extension=mysqli ή πρέπει να γίνει και κάποια άλλη ρυθμιση;
Για να τρέχουν σωστά τα prepared statements πρέπει να ενεργοποιηθούν και τα PDO extensions; Δοκίμασα το παράδειγμα του dva_dev και μου βγάζει "Unknown column 'comp' in 'order clause' " σε query που δεν έχει καν order by :evil:

To DEALLOCATE είναι το ίδιο με το mysql_free_result;

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Fixing a sql injection

Δημοσίευση από dva_dev » 20 Μαρ 2009 19:58

Αντί του mysqli_pconnect δοκιμασε το mysqli_connect

Πρέπει να δηλωθεί στο php.ini και φυσικά να έχεις/να κατεβάσεις τις αντίστοιχες βιβλιοθήκες.

Τα prepared statements υποστηρίζονται από την mysql 4.1 και μετά δεν χρειάζονται ούτε mysqli ούτε pdo ούτε τίποτα. Στο παράδειγμα που είχα δώσει όπως μπορείς να δείς χρησιμοποιώ mysql απλές κλήσεις, ούτε καν mysqli.
Πρίν κάνεις δοκιμές στην php, κάνε δοκιμές κατευθείαν στη mysql, θα καταλάβεις καλύτερα τι παίζει. Δες και το http://dev.mysql.com/tech-resources/art ... ments.html και κάνε τα παραδείγματα. Πειραματίσου!

Το deallocate είναι διαφορετικό.
Κάνεις prepare ένα sql statement που χρησιμοποιεί παραμέτρους. Αυτό το prepared statement πρέπει να το κάνεις deallocate είτε το τρέξεις είτε όχι. (Θα δείς ότι πέρα από την ασφάλεια σε sql injections έχει μεγαλύτερη αξία όταν επαναχρησιμοποιείται το sql statement).

Τρέχεις το prepared statement με τιμή Α στις παραμέτρους. Οταν τελειώσεις με το συγκεκριμένο result set κάνεις mysql_free_result.
Ξανατρέχεις το prepared statement με τιμή Β στις παραμέτρους. Οταν τελειώσεις ... mysql_free_result.
Ξανατρέχεις άλλες 500 φορές με διαφορετικές παραμέτρους. Κάθε φορά που τελειώνεις με το result set κάνεις mysql_free_result.

(Κάθε φορά που χρησιμοποιείς το query, γίνεται απλώς αντικατάσταση των παραμέτρων από την mysql, και τρέχει το query, δεν γίνεται κάθε φορά parse για να δεί αν το query είναι έγκυρο ή όχι. Αυτό έγινε μια φορά στην αρχή όταν το έκανες prepare.)

Αφού τελειώσεις εντελώς κάνεις deallocate το prepared statement. (Ούτως ή άλλως θα το κάνει η mysql όταν κλείσεις το connection, αλλά όσο πιο γρήγορα το κάνεις τόσο καλύτερα, ελευθερώνεις τα resources που δεν χρειάζεσαι. Μην περιμένεις πότε θα θυμηθεί η mysql να το κάνει).

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Fixing a sql injection

Δημοσίευση από Apostolis_38 » 21 Μαρ 2009 12:41

Ok, θα το ψάξω.

Ελπίζω να μην χρειαστεί να σας ξαναζαλίσω :)

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Fixing a sql injection

Δημοσίευση από Apostolis_38 » 21 Μαρ 2009 18:45

Ωραία, me gusta τα prepared :D

Προέκυψαν όμως δύο δυσκολίες:

1ον. Χρησιμοποιώ το pagination του panosru (http://www.freestuff.gr/forums/viewtopic.php?t=28203) όπου χρειάζονται δύο select:

Κώδικας: Επιλογή όλων

$qp1 = "SELECT * FROM `data`"; 
$qp2 = sprintf("%s ORDER BY `id` DESC LIMIT %d,%d",$qp1,$start,$lpr); 
όπου στο δεύτερο query περνάνε τα αποτελέσματα απο το πρώτο.

Πώς θα δηλώσω το

Κώδικας: Επιλογή όλων

$qp1 = mysql_query('SET @test_param='.mysql_escape_string($_GET['id']),$conn); 
Δεν παίζει με τίποτα.


2ον. Οταν ο χρήστης κάνει αναζήτηση με κείμενο το

Κώδικας: Επιλογή όλων

'SET @test_param='
δεν έχει νόημα.
Χρειάζεται test_param like "%" κείμενο"%"
Ούτε κι αυτό όμως παίζει.

Καμμιά ιδέα;

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Fixing a sql injection

Δημοσίευση από Apostolis_38 » 23 Μαρ 2009 12:54

Apostolis_38 έγραψε: Χρειάζεται test_param like "%" κείμενο"%"
Σε περίπτωση που το χρειαστεί κάποιος:

Κώδικας: Επιλογή όλων

PREPARE test FROM "SELECT * FROM *** where '.$_GET[***].' like ?";
SET @test_param= "%'.$_GET[***].'%"

Άβαταρ μέλους
cpulse
Script Master
Δημοσιεύσεις: 1527
Εγγραφή: 21 Μαρ 2006 19:30
Τοποθεσία: Αθήνα village
Επικοινωνία:

Fixing a sql injection

Δημοσίευση από cpulse » 23 Μαρ 2009 22:04

Αποστόλη σε αυτό που έγραψες βάζεις το $_GET κατευθείαν μέσα στο statement. Αν πριν δεν το χεις περάσει από κάποιο validation τότε πάλι κινδυνεύεις από sql injection.

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Fixing a sql injection

Δημοσίευση από Apostolis_38 » 24 Μαρ 2009 11:03

Οταν λες validation εννοείς κάποιο mysql_escape_string - addslashes - (int)$_GET[''] κ.λ.π.;
Αν ναι, αυτά γίνονται στην προηγούμενη σελίδα που στέλνει τις τιμές.

Με την ευκαιρία, είναι καλύτερα τα prepared statements να εκτελούνται μέσα στη σελίδα που τρέχει το script; Γιατί εγώ τα χρησιμοποιώ με require.

Και κάτι τελευταίο. sql injection μπορεί να τρέξει απο την γραμμή τίτλου του browser;

Άβαταρ μέλους
cpulse
Script Master
Δημοσιεύσεις: 1527
Εγγραφή: 21 Μαρ 2006 19:30
Τοποθεσία: Αθήνα village
Επικοινωνία:

Fixing a sql injection

Δημοσίευση από cpulse » 24 Μαρ 2009 17:08

Η επιβάρυνση σε χρόνο ενός require() ή include() είναι μηδαμινή, άρα δεν έχεις περιορισμό. Τα βάζεις όπου βολεύει καλύτερα, και ισώς καλύτερα, όπου μπορείς να κάνεις ευκολότερη συντήρηση.

Όταν λες γραμμή τίτλου εννοείς γραμμή διεύθυνησης (address bar); SQL Injection είναι κάτι που γίνεται με string concatenation. Μια πηγή string, η ποιο επίφοβη, είναι τα $_GET variables, άρα ναι μπορεί να τρέξει από το address bar.

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Fixing a sql injection

Δημοσίευση από Apostolis_38 » 24 Μαρ 2009 17:25

Ναι, address bar. To ίδιο είναι :lol: :lol:
Με δεδομένο οτι δεν μπορείς απο εκεί να ελένξεις τι θα κάνει ο άλλος τότε τα prepared ή τα validations είναι sos.


Υ.Γ. για την προήγουμενη υπόδειξή σου έχεις δίκιο. Είχα postάρει τον παλιό κώδικα.
Το σωστό (ελπίζω δηλαδή :-? )είναι:

Κώδικας: Επιλογή όλων

$searchtype = $_GET['searchtype'];
$searchterm = $_GET['searchterm'];

mysql_query ('PREPARE test FROM "SELECT * FROM πίνακας where '.$searchtype.' like ?";');
mysql_query ('SET @test_param= "%'.$searchterm.'%" '); 
$result = mysql_query ('EXECUTE test USING @test_param;');
Αμα postάρεις και σκέφτεσαι το Πάσχα...

Άβαταρ μέλους
cpulse
Script Master
Δημοσιεύσεις: 1527
Εγγραφή: 21 Μαρ 2006 19:30
Τοποθεσία: Αθήνα village
Επικοινωνία:

Fixing a sql injection

Δημοσίευση από cpulse » 24 Μαρ 2009 20:13

Κώδικας: Επιλογή όλων

$searchtype = $_GET['searchtype'];
$searchterm = $_GET['searchterm'];

if (!ctype_alnum($searchtype))
    die('Invalid search type');

mysql_query ('PREPARE test FROM "SELECT * FROM πίνακας where '.$searchtype.' like ?";');
mysql_query ('SET @test_param= "%'.$searchterm.'%" '); 
$result = mysql_query ('EXECUTE test USING @test_param;');

Apostolis_38
Δημοσιεύσεις: 1969
Εγγραφή: 14 Φεβ 2008 16:20
Τοποθεσία: ΠΕΙΡΑΙΑΣ

Fixing a sql injection

Δημοσίευση από Apostolis_38 » 25 Μαρ 2009 20:47

Σωστός!

Απάντηση

Επιστροφή στο “PHP Προγραμματισμός”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 1 επισκέπτης