2016-03-02 89 views
0

我想知道如果我的代碼實際上是免受SQL注入的保護。我的網站已經注入過,我從來沒有真正理解如何防止它。這裏是我的代碼插入評論:這是SQL注入嗎?

if ($_POST['comment']) { 
    $comment = strip_tags(nl2br(mysql_real_escape_string($_POST['comment']))); 
    $conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); 
    // set the PDO error mode to exception 
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
    $sql = "INSERT INTO posts (comment, authorid) 
    VALUES ('$comment', '$uid')"; 
    // use exec() because no results are returned 
    $conn->exec($sql); 
    echo '<div style="width: 98%; max-width: 98%; border: 1px solid white; background-color: green; color: white; vertical-align: text-top; text-align: center;">Your comment was added to the wall!</div><br>'; 
} 
+0

我建立他們的樂趣。我只是一名高中生 –

+1

mysql_real_escape_string和PDO?!? – 2016-03-02 23:24:57

+0

是的,這是可能的。看到這:http://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string – Harsh

回答

2

是的,它可能會被注入:你似乎並沒有保護你的$uid變量。另外,堆棧nl2brstrip_tags之後轉義是一個壞主意 - 您想離開mysql_real_escape_string作爲上一次操作以避免任何過濾器交互作用。

更一般地說,您應該使用準備好的語句而不是字符串插值來構建SQL查詢。它更簡單,更高效,更安全並且需要更少的代碼。您可以使用$conn->prepare創建一個準備好的語句,並與任意參數執行:

$stmt = $conn->prepare("INSERT INTO posts (comment, authorid) VALUES (?, ?)"); 
$stmt->execute(array($comment, $uid)); 

沒有逃脫必需的。

+0

準備好的語句還有一個額外的好處,即準備的語句不允許包含多個SQL語句,這對於大多數SQL注入攻擊都是必需的成功。 –

+1

@DarwinvonCorax:實際上,在許多使用*嵌套查詢的上下文中只有一條SQL語句的情況下,SQL注入是完全可行的 - 有時您只需要從數據庫中讀取敏感數據。 – nneonneo

+0

好的。那麼更新呢?我會怎麼做呢? –