如何清理字符串以避免SQL注入和最常见的攻击类型? (在PHP中)

问题描述:

Is there a way to, in as little code as possible, to filter a string for both SQL injection and the most common forms of attack?

In my scripts I'm using the following, I would like to know whether it's reasonably safe and whether someone else has a suggestion:

$cleanName    = htmlspecialchars(addslashes($dirtyName));

See how I filtered it both for html chars and for quotes and double-quotes.

NOTE: I'm using addslashes() rather than mysql_real_escape_string() because I don't want to hardcode the DB I'm using into my code.

Is this ok?

Thanks in advance

有没有办法以尽可能少的代码过滤SQL注入和最多的字符串 常见的攻击形式? p>

在我的脚本中,我正在使用以下内容,我想知道它是否合理安全以及是否有其他人有建议: p> \ n

  $ cleanName = htmlspecialchars(addslashes($ dirtyName)); 
  code>  pre> 
 
 

看看我是如何为html字符和引号双重过滤的 -quotes。 p>

注意:我正在使用 addslashes() code>而不是 mysql_real_escape_string() code>,因为我不想硬编码 我在我的代码中使用的数据库。 p>

这可以吗? p>

提前致谢 p> div>

Probably not... you need to escape your raw text for each purpose separately for which you are going to use it:

  • For GET requests, use urlencode.
  • For HTML output, use htmlentities.
  • For calling as a command via system, use escapeshellcmd.
  • For passing arguments to a command via system: use escapeshellargs.
  • For passing a database parameter: use mysql_real_escape_string.

There's no "universal" solution for magically escaping text. Keep raw text internally, and escape it for the appropriate purpose.

Not to rain on Kerrek's parade, but there is one, relatively, universal solution. I use the following and it's always worked:

$safe_value = mysql_real_escape_string( strip_tags( trim( $value ) ), $db_connection ); // This is if you aren't storing any html tags

$safe_value = mysql_real_escape_string( html_entities( trim( $value ) ), $db_connection ); // This is if you are storing html tags

Hope this helps.

If you don't mind recoding your connection and a couple extra lines of you code you can't beat PDO for security. It uses the C backend to prepare and execute your mysql queries. So instead of string concatenation you get predefined sections in the query that must be value XYZ. One of the guys here on * explained it like this:

Imagine a hotdog stand. You walk up to the hotdog stand and say I'd like a hot dog with 3 toppings. Ketchup, mustard and we will let the next random stranger tell us the third topping. A sql injector might walk up and say, "ketchup, mustard and 'give me all the money in the drawer'". Standard concat queries have no way of discerning that it is an invalid response and therefore hand over what was requested. A prepared statement will respond with "I dont have a condiment called,"give me all the money in the drawer".

PDO prepared statements are essentially injection proof. You still have other vulnerabilities like cookie/session hijacking etc, but at least injection is off the table.

If you know exactly what kind of input you are expecting, better use preg_replace() If you know that you only expect alpha-numerics:

<?php
if (isset($_GET['page'])) {
 $page = preg_replace('/[^a-z0-9]/', '', $_GET['page']);
 include_once($includeDir.'/'.$page.'.php');
}
?>

The above should prevent all attacks executed via GET or POST too, but it assumes you only expect alphanumeric input. Well, I mostly had in mind directory traversal attack, but if you use the GET variable to query a database or display it as a html entity should prevent any attack. A http://mydomain.tld?index.php?page=../../etc/passwd request won't read your passwd file from your website's /var/www document root but will only try to include a etcpasswd.php file