2016-03-02 87 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

好的。那么更新呢?我会怎么做呢? –