PHP 代码容易受到 SQL 注入:如何使用“mysql_real_escape_string()”?

发布于 2024-11-29 01:51:14 字数 765 浏览 0 评论 0原文

当我从几年前的教程中学习时,我最终得到了以下容易受到 SQL 注入攻击的代码。

有人可以向我解释如何使用 mysql_real_escape_string() 吗? 这是目前的防弹方法吗?

//Function to sanitize values received from the form. Prevents SQL injection
    function clean($str) {
    $str = @trim($str);
    if(get_magic_quotes_gpc()) {
        $str = stripslashes($str);
    }
    return mysql_real_escape_string($str);
}

//Sanitize the POST values
$usr = $_SESSION['usr'];
$live = (isset($_POST['live']))?1:0;
$created = date("F j, Y, g:i a",time()+60*60);
$title= clean($_POST['title']);
$content = clean($_POST['content']);

//Create INSERT query
$qry = "INSERT INTO news( usr, live, created, title, content) VALUES( '$usr', '$live', '$created', '$title', '$content') ";
$result = @mysql_query($qry);

As I was learning from couple of years old tutorials I have end up with following code which IS vulnerable for SQL injections.

Can someone explain to me how to work with mysql_real_escape_string()?
Is this currently bulletproof method?

//Function to sanitize values received from the form. Prevents SQL injection
    function clean($str) {
    $str = @trim($str);
    if(get_magic_quotes_gpc()) {
        $str = stripslashes($str);
    }
    return mysql_real_escape_string($str);
}

//Sanitize the POST values
$usr = $_SESSION['usr'];
$live = (isset($_POST['live']))?1:0;
$created = date("F j, Y, g:i a",time()+60*60);
$title= clean($_POST['title']);
$content = clean($_POST['content']);

//Create INSERT query
$qry = "INSERT INTO news( usr, live, created, title, content) VALUES( '$usr', '$live', '$created', '$title', '$content') ";
$result = @mysql_query($qry);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

像你 2024-12-06 01:51:15

附加到查询字符串的所有内容都应该使用 mysql_real_escape_string 进行转义。它将阻止大多数 SQL 注入。但最好使用准备好的语句

示例:

$pdo = new PDO($dsn,$username,$pass);
$stmt = $pdo->prepare("select * from Table where id=?");
if ($stmt->execute(array(1))){
    $content = $stmt->fetchAll();
}

参见PDO::__construct 供参考

Everything you append to query string you should escape with mysql_real_escape_string. It will prevent most of SQL injections. But better use prepared statements

Example:

$pdo = new PDO($dsn,$username,$pass);
$stmt = $pdo->prepare("select * from Table where id=?");
if ($stmt->execute(array(1))){
    $content = $stmt->fetchAll();
}

See PDO::__construct for reference

面如桃花 2024-12-06 01:51:15

是的。 在这种情况下。

请注意,没有什么比“普遍消毒”更好的了。我们称其为引用,因为这就是它的全部内容。

引用时,总是引用某些特定输出的文本,例如:

  1. mysql 查询的字符串值
  2. like mysql 查询的表达式
  3. html 代码
  4. json
  5. mysql 常规expression
  6. php 正则表达式

对于每种情况,您需要不同的引用,因为每种用法都存在于不同的语法上下文中。这也意味着不应在 PHP 的输入处进行引用,而应在特定的输出处进行引用!这就是像 magic_quotes_gpc 这样的功能被破坏的原因(我建议将其关闭)。

那么,在这些特殊情况下,人们会使用什么方法来引用呢? (请随意纠正我,可能有更现代的方法,但这些对我有用)

  1. mysql_real_escape_string($str)
  2. mysql_real_escape_string(addcslashes($str, "%_"))< /code>
  3. htmlspecialchars($str)
  4. json_encode() - 仅适用于 utf8!我将我的函数用于 iso-8859-2
  5. mysql_real_escape_string(addcslashes($str, '^.[]$()|*+?{}')) - 在这种情况下你不能使用 preg_quote 因为反斜杠将被转义两次!
  6. preg_quote()

Yes, it is. In this case.

Note there is nothing like "universal sanitization". Let's call it just quoting, because that's what its all about.

When quoting, you always quote text for some particular output, like:

  1. string value for mysql query
  2. like expression for mysql query
  3. html code
  4. json
  5. mysql regular expression
  6. php regular expression

For each case, you need different quoting, because each usage is present within different syntax context. This also implies that the quoting shouldn't be made at the input into PHP, but at the particular output! Which is the reason why features like magic_quotes_gpc are broken (I recommend to keep it switched off).

So, what methods would one use for quoting in these particular cases? (Feel free to correct me, there might be more modern methods, but these are working for me)

  1. mysql_real_escape_string($str)
  2. mysql_real_escape_string(addcslashes($str, "%_"))
  3. htmlspecialchars($str)
  4. json_encode() - only for utf8! I use my function for iso-8859-2
  5. mysql_real_escape_string(addcslashes($str, '^.[]$()|*+?{}')) - you cannot use preg_quote in this case because backslash would be escaped two times!
  6. preg_quote()
滴情不沾 2024-12-06 01:51:15

对于黑客攻击来说,没有什么是刀枪不入的。话虽如此,是的.. mysql_real_escape_string() 可以防止 SQL 注入攻击。

Nothing is bulletproof when it comes to hacking; having said that, yes.. mysql_real_escape_string() prevents SQL injection attacks.

不奢求什么 2024-12-06 01:51:15

我认为你的方法是sql注入保存。

I think your method is sql injection save.

聽兲甴掵 2024-12-06 01:51:15

您可以使用 mysql_real_escape_string 来转义危险字符...

$sanitized_query = sprintf("SELECT * FROM table WHERE field='%s', mysql_real_escape_string($value));

you can use mysql_real_escape_string, to escape dangerous characters...

$sanitized_query = sprintf("SELECT * FROM table WHERE field='%s', mysql_real_escape_string($value));
鸠书 2024-12-06 01:51:15

我会做类似的事情

sprintf(" SELECT * from table_name WHERE value = '%s'", mysql_escape_string("$var_value"));

sprintf() 函数中的 %s 表示参数被视为字符串并以字符串形式呈现。

如果发生诸如上一示例中的攻击,则发送的查询将是:
查看源代码
打印?

从 `members` 中选择 *,其中用户名='john' AND 密码='\' OR \'\'=\''

并且将返回一个空结果集。 (来源)

I would do something like

sprintf(" SELECT * from table_name WHERE value = '%s'", mysql_escape_string("$var_value"));

The %s from the sprintf() function indicates that the argument is treated as and presented as a string.

If an attack is made such as the one from the previous example the query sent will be:
view source
print?

SELECT * FROM `members` WHERE username='john' AND password='\' OR \'\'=\''

and will return an empty result set. (source)

握住我的手 2024-12-06 01:51:14

是的,这个很好。 您可以使用准备好的语句,但

不要使用@来隐藏所有错误!

Yes, this one is fine. You can use prepared statements, though

Do not use @ to hide all errors!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文