Προς το περιεχόμενο

php prepared statement


Προτεινόμενες αναρτήσεις

Δημοσ. (επεξεργασμένο)

Hello guys, δοκιμάζω να κάνω με ένα prepared statement το παρακάτω:
 

 $gconsole='ps4';
 $result=$link->prepare("SELECT ? FROM gamesconsole WHERE id=?");
 $result->bind_param('si',$gconsole,$id);
 $result->execute();
 $result->store_result();
 $result->bind_result($games);
 $result->fetch();
 if($result->num_rows>0) echo $games;
 $result->close();

Το θέμα είναι ότι αυτό επιστρέφει πάντα ότι τιμή έχει η $gconsole, γιατί γίνεται αυτό? Δε μπορώ να δηλώσω το ' ? ' στο select? To αντίστοιχο query

SELECT ps4 FROM gamesconsole WHERE id=?

δουλεύει κανονικά (αν περάσω δηλαδή κατευθείαν την τιμή του select).

Επεξ/σία από ALLisCHAOS
Δημοσ.

Το select που παραθέτεις δεν είναι το "αντίστοιχο query". Αφού κάνεις bind σαν string, το αντίστοιχο query θα είναι:

SELECT 'ps4' FROM gamesconsole WHERE id=?

Η διαφορά είναι ότι, ενώ το ps4 είναι field name, το 'ps4' είναι constant.

 

Εγώ θα το έκανα έτσι:

$result=$link->prepare("SELECT $gconsole FROM gamesconsole WHERE id=?");
$result->bind_param('i',$id);
Δημοσ.

1. Κανονικά αυτό που πρέπει να κάνεις είναι "escape identifier" και όχι value. Δεν υπάρχει τέτοια ενσωματωμένη δυνατότητα, θα πρέπει να το κάνεις manually.

2. Είσαι σίγουρος ότι χρειάζεται να το κάνεις αυτό; Θα μπορούσες απλά π.χ. να κάνεις SELECT * και να πάρεις μετά μόνο αυτό που σ' ενδιαφέρει. Δεν είναι και το καλύτερο αλλά στην περίπτωσή σου δε θα έχει σημασία.

3. Έτσι που είναι γραμμένο τώρα εν δυνάμει υπάρχει πρόβλημα, αλλά τουλάχιστον ελπίζω πως η τιμή του $gconsole δεν έρχεται "απ έξω" άμεσσα ή έμμεσα; Διαφορετικά έκανες μια τρύπα στο νερό.

Δημοσ.

#defacer σχετικά με το 3 το εν δυνάμει πρόβλημα που λες είναι σχετικά με το αν έρχεται 'απ έξω' η τιμή της $gconsole? Γιατί ναι τη πέρνω μέσα απο  $_POST, αλλά γιατί έχει γίνει μια τρύπα στο νέρο? απο άποψη ασφαλείας εννοείς?

Σχετικά με το 2, δεν την είχα σκεφτεί αυτή τη περίπτωση. Αν τη χρησιμοποιήσω σε συνδυασμό με τη $gconsole που έρχεται απ έξω?
Δηλαδή να πέρνω με SELECT * τα πάντα και μετά ανάλογα τη τιμή της $gconsole να επιστρέφω και το κατάλληλο πεδίο. Καπώς καλύτερα έτσι τα πράγματα?

Δημοσ.

#defacer σχετικά με το 3 το εν δυνάμει πρόβλημα που λες είναι σχετικά με το αν έρχεται 'απ έξω' η τιμή της $gconsole? Γιατί ναι τη πέρνω μέσα απο  $_POST, αλλά γιατί έχει γίνει μια τρύπα στο νέρο? απο άποψη ασφαλείας εννοείς?

Ναι. Βασικά τώρα είναι ξεκάθαρο ότι πας να χρησιμοποιήσεις prepared statement χωρίς να ξέρεις γιατί το κάνουμε αυτό, με το όχι αναπάντεχο αποτέλεσμα ότι τελικά κάνεις κάτι που έχει τα στραβά και των δύο περιπτώσεων (και παραπάνω κώδικα γράφεις, και προστασία δεν παίρνεις).

 

Προφανώς μπορεί ο άλλος να πάει για $gconsole να δώσει π.χ το κλασικό.

CONCAT(username, password) FROM users WHERE is_admin = 1 --

 

με αποτέλεσμα το query σου να γίνει

 

SELECT CONCAT(username, password) FROM users WHERE is_admin = 1 -- FROM gamesconsole WHERE id=?

 

και γειά σας.

 

Οπωσδήποτε πίσω στη μελέτη να καταλάβεις τι πας να κάνεις και για ποιό λόγο. Θέλεις κανα link?

 

Σχετικά με το 2, δεν την είχα σκεφτεί αυτή τη περίπτωση. Αν τη χρησιμοποιήσω σε συνδυασμό με τη $gconsole που έρχεται απ έξω?

Δηλαδή να πέρνω με SELECT * τα πάντα και μετά ανάλογα τη τιμή της $gconsole να επιστρέφω και το κατάλληλο πεδίο. Καπώς καλύτερα έτσι τα πράγματα?

Κάπως καλύτερα από πλευράς ασφάλειας γιατί τουλάχιστον μ' αυτόν τον τρόπο το περισσότερο που θα μπορεί να κάνει ο κακός είναι να δει όποιο πεδίο του αρέσει από τον πίνακα gameconsole.

 

Το καλύτερο όλων θα ήταν να ελέγχεις την τιμή βάσει μιας whitelist επιτρεπόμενων τιμών (όλες οι άλλες απαγορεύονται) οπότε problem solved.

if (!in_array($gconsole, ['ps4', 'xbone'])) {
    die('Invalid parameter');
}

// εφόσον φτάσαμε εδώ είσαι σίγουρος πως η τιμή της $gconsole είναι ακίνδυνη
Δημοσ.
Θέλεις κανα link?

 

Υeap! Δώσε link στο λαό!  :D

 

 

 

Κάπως καλύτερα από πλευράς ασφάλειας γιατί τουλάχιστον μ' αυτόν τον τρόπο το περισσότερο που θα μπορεί να κάνει ο κακός είναι να δει όποιο πεδίο του αρέσει από τον πίνακα gameconsole.

Το καλύτερο όλων θα ήταν να ελέγχεις την τιμή βάσει μιας whitelist επιτρεπόμενων τιμών (όλες οι άλλες απαγορεύονται) οπότε problem solved.

if (!in_array($gconsole, ['ps4', 'xbone'])) {
    die('Invalid parameter');
}

// εφόσον φτάσαμε εδώ είσαι σίγουρος πως η τιμή της $gconsole είναι ακίνδυνη

Τhank u και για το τελευταίο, αν και στη προκυμένη περίπτωση δε θα με πείραζε να δει τα πεδία απο το gameconsole

Δημοσ.

Το sanitization θα πρεπει να θεωρειται δεδομενο σε καθε περιπτωση. Δεν νοειται να θελεις να φτιαξεις οποιαδηποτε εφαρμογη (οχι μονο web) χωρις να ελεγχεις τα inputs σου (και οχι μονο).

 

Αν και υπαρχουν πολυ πιο sophosticated μεθοδοι, στην περιπτωση σου φαινεται οτι μια whitelist θα σε καλυψει παραπανω απο οσο θα χρειαστεις ποτε.

 

Μετα απο ολα αυτα, εχεις ολα τα keywords που θα χρειαστεις ποτε, ωστε να φτιαχνεις εφαρμογες με τη στοιχειωδη ασφαλεια που θα επρεπε να θωρειται δεδομενη.

Δημοσ.

Το sanitization θα πρεπει να θεωρειται δεδομενο σε καθε περιπτωση. Δεν νοειται να θελεις να φτιαξεις οποιαδηποτε εφαρμογη (οχι μονο web) χωρις να ελεγχεις τα inputs σου (και οχι μονο).

 

Αν και υπαρχουν πολυ πιο sophosticated μεθοδοι, στην περιπτωση σου φαινεται οτι μια whitelist θα σε καλυψει παραπανω απο οσο θα χρειαστεις ποτε.

 

Μετα απο ολα αυτα, εχεις ολα τα keywords που θα χρειαστεις ποτε, ωστε να φτιαχνεις εφαρμογες με τη στοιχειωδη ασφαλεια που θα επρεπε να θωρειται δεδομενη.

 

Δεν υπάρχει έννοια που έχει υποστεί μεγαλύτερο βιασμό από τη λέξη "sanitization". Θα έφτανα μέχρι το σημείο να πω ότι στο 99% των περιπτώσεων που ακούμε αυτή τη λέξη, ακούμε αρλούμπες.

 

Παράδειγμα υπερφανταστικού μπασταρδέματος taken by none other than the WP docs:

 

Πρώτα απ' όλα μιλάνε για validation (αυτό είναι το σχεδόν δεδομένο) και δίνουν αυτό

 

if ( strlen( $safe_zipcode ) > 5 )
    $safe_zipcode = substr( $safe_zipcode, 0, 5 );

Since the `maxlength` attribute is only enforced by the browser, we still need to validate the length of the input on the server. If we don't, an attacker could manually submit a form with a longer value.

 

Στο χωριό μου λένε ότι validation σημαίνει: αν το μήκος είναι πάνω από 5, η είσοδος δεν γίνεται αποδεκτή με μήνυμα "λάθος ταχυδρομικός κώδικας". Εδώ κάνουν sanitization (άχρηστο really) και το βαφτίζουν validation. Δε μπορώ να καταλάβω σε ποιό σύμπαν έχει νόημα να δεχτείς ταχυδρομικό κώδικα με περισσότερα από 5 ψηφία και να τον αποθηκεύσεις κόβοντας τα παραπάνω περιμένοντας προφανώς ότι αυτό που έμεινε είναι κάτι χρήσιμο.

 

Και στη συνέχεια περνάμε στο "sanitization", όπου λένε τα εξής φανταστικά:

 

Behinds the scenes, the function does the following:

  • Checks for invalid UTF-8 (uses wp_check_invalid_utf8())
  • Converts single < characters to entity
  • Strips all tags
  • Remove line breaks, tabs and extra white space
  • Strip octets

 

Checks for invalid UTF-8: κι αν βρει λοιπόν τι κάνει; Αφαιρεί τα invalid sequences, μετατρέποντας την είσοδο σε κάτι απρόβλεπτο. Με ποιό τρόπο αυτό είναι καλύτερο από το να μη δεχτεί την είσοδο εξαρχής (validation)? Δε θα μάθουμε ποτέ.

 

Converts single < to entity: εγκληματική άγνοια; Κάνοντάς το (HTML) entity μετατρέπεις την είσοδο από format-agnostic σε κάτι που έχει νόημα μόνο όταν χρησιμοποιηθεί σαν HTML. Θέλεις π.χ. να κάνεις ένα SELECT με το χέρι στη βάση να δεις κάτι; Θέλεις να κάνεις π.χ. export σε CSV; Συγχαρητήρια, πάρε και τα entities μαζί να σου χαλάνε τα δεδομένα. Παρομοίως για το strips all tags.

 

Τα υπόλοιπα δύο τουλάχιστον μπορώ να τα δεχτώ σα λογική.

 

In their defense υποθέτω ότι αν ήθελαν να κάνουν τα πάντα "μόνο σωστά" θα έπρεπε να εμπιστεύονται τον κάθε συγγραφέα plugin ότι τα κάνει επίσης όλα σωστά, πράγμα που προφανώς δε μπορεί να ισχύει οπότε αναγκαστικά καταλήγουμε σ' αυτή τη λύση.

 

Ποιό είναι το point μου: αυτοί που γράφουν το WP προφανώς τα ξέρουν όλα αυτά. Αλλά το κοινό τους δεν τα ξέρει, κι επειδή δε μπορούν να τα βάλουν στο κεφάλι του maximum developer "γράφω και plugin" έχουμε αυτού του είδους το βιασμό και τη διαιώνισή του. Validation? Ναι, σχεδόν πάντα. Escaping? Ναι, πάντα (αυτό είναι που πετυχαίνει κανείς με το prepared statement). Sanitization? 99% bullshit.

Υeap! Δώσε link στο λαό!  :D

Θα ψάξω να βρω κάτι καλό και θα επανέλθω. 

 

Τhank u και για το τελευταίο, αν και στη προκυμένη περίπτωση δε θα με πείραζε να δει τα πεδία απο το gameconsole

Δεν έχει σημασία. Κάντο σωστά κι εκεί που δε χρειάζεται, για να το κάνεις σίγουρα σωστά εκεί που χρειάζεται.

  • Like 1
Δημοσ.

Το sanitization είναι sanitization, μία έννοια πολύ συγκεκριμένη που δεν επιδέχεται (από μόνη της) παρερμηνείες όσο και να προσπαθεί κανείς. Άσχετα πόσες αρλούμπες λέει ο καθένας* σε προτάσεις που η λέξη συμπεριλαμβάνεται, για διάφορους λόγους (SEO και μη ;) ).

 

Ή κάνεις sanitize τα δεδομένα σου (σκοπίμως λέω δεδομένα και όχι input) ή δεν τα κάνεις. Είναι τόσο απλό, και οποιοδήποτε μακρύτερο rand από αυτό φτάνει στα όρια του κουτσομπολιού.

 

Τhank u και για το τελευταίο, αν και στη προκυμένη περίπτωση δε θα με πείραζε να δει τα πεδία απο το gameconsole

 

Σε ένα και μόνο θα συμφωνήσω:

 

Δεν έχει σημασία. Κάντο σωστά κι εκεί που δε χρειάζεται, για να το κάνεις σίγουρα σωστά εκεί που χρειάζεται.

 

* συμπ. όλοι μας

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...