2009-08-01 24 views
3
<?php 

$id = intval($_GET['id']); 

$sql = mysql_query("SELECT username FROM users WHERE id = $id"); 
$row = mysql_fetch_assoc($sql); 

$user = htmlspecialchars($row['username']); 

?> 

<h1>User:<?php echo $user ?></h1> 

Können Sie alle Bedrohungen in dem oben genannten Code sehen? Muss ich htmlspecialchars für alle Ausgaben verwenden? Und sollte ich is_numeric oder intval verwenden, um zu überprüfen, dass der get numerisch ist?PHP-Sicherheit, intval und htmlspecialchars

Ich baue nur eine minimale Website. Ich frage mich nur, ob der obige Code anfällig für SQL-Injektion, XSS ist?

Antwort

8

Im Allgemeinen wird mysql_real_escape_string() bevorzugt, aber da es eine Nummer ist, ist intval() OK. Also ja, es sieht aus Sicherheitsgründen ok aus.

Eine Sache jedoch, auf vielen Plattformen, sind Ints auf 32 Bits begrenzt, also wenn Sie in Zahlen größer als ~ 2,1 Milliarden handeln wollen, dann wird es nicht funktionieren. Nun, es wird nicht funktionieren, wie Sie es erwarten.

Diese Sicherheitsvorkehrungen gelten für alle Arten von Benutzereingaben, einschließlich Cookies (etwas, das viele vergessen).

+1

Unsigned Ints werden + - 4 Milliarden max. –

+2

PHP-Ints sind signiert. Es gibt keine unsignierten Ints in PHP. – cletus

0

Nun,

Sie übertragen die empfangene ID an ein int; also keine mögliche SQL-Injektion hier.
Und der Rest der DB-Abfrage ist "hart-codiert", also kein Problem.

Wenn id ein String in DB ist, würden Sie mysql_real_escape_string verwenden, sondern für eine ganze Zahl ist intval das richtige Werkzeug :-)


über den Ausgang werden Sie Daten entkommen zu (und, wie Sie HTML ausgeben, ist htmlspecialchars OK); also keine HTML/JS-Injektion.


Also, das kurze Teil des Codes sieht mir :-)


Als Nebenbemerkung OK, wenn Sie beginnen, eine neue Website developping, es ist der Moment, oder nie entweder einen Blick zu nehmen mysqli (anstelle von mysql) und/oder PDO ;-)

Es erlauben würden Sie functionnalities zur Verfügung gestellt von neueren Versionen von MySQL, wie prepared statements, zum Beispiel zu verwenden - das ist eine gute Möglichkeit, sich von SQL-Injection zu schützen !

+0

danke das ist beruhigend zu hören –

5

Ich würde dringend empfehlen, PDO und vorbereitete Anweisungen zu verwenden. Während Ihre obige Aussage sicher aussieht, werden Sie Probleme haben, sobald Sie komplexere Abfragen durchführen.

Anstatt zu rätseln, ob eine bestimmte Abfrage sicher ist, lernen Sie über vorbereitete Anweisungen und Sie müssen sich keine Sorgen machen. Hier ist Ihr Beispiel, neu geschrieben mit PDO:

# Make a database connection 
$db = new PDO('mysql:dbname=your_db;host=your_db_server', 'username', 
    'password'); 

# The placeholder (:id) will be replaced with the actual value 
$sql = 'SELECT username FROM users WHERE id=:id'; 

# Prepare the statement 
$stmt = $db->prepare($sql); 

# Now replace the placeholder (:id) with the actual value. This 
# is called "binding" the value. Note that you don't have to 
# convert it or escape it when you do it this way. 
$stmt->bindValue(':id', $id); 

# Run the query 
$stmt->execute(); 

# Get the results 
$row = $stmt->fetch(); 

# Clean up 
$stmt->closeCursor(); 

# Do your stuff 
$user = htmlspecialchars($row['username']); 

Ich habe eine Menge Kommentare hinzugefügt; es ist nicht so viel Code wie es aussieht. Wenn Sie bindValue verwenden, müssen Sie sich keine Gedanken über SQL-Injection machen.

+0

was ist, wenn es eine Schnur ist? Muss ich mysql_real_escape string es? –

+0

Nein. Wenn Sie 'bindValue()' verwenden, müssen Sie Ihre Strings nicht entfliehen. Funktionen wie 'mysql_real_escape_string' waren wichtig, um SQL-Injection zu verhindern, bevor PHP eine moderne Datenbank-API hatte. Es wird nicht länger mit PDO * benötigt, solange Sie 'bindValue' * verwenden und nicht versuchen, Benutzereingaben manuell in Ihre $ sql-Zeichenfolge zu verketten. Mit anderen Worten, mach es einfach. :-) – Nate

Verwandte Themen