如果插入用户输入而不修改SQL查询,则应用程序容易受到SQL注入的攻击,如下例所示:
$unsafe_variable = $_POST['user_input'];
mysql_query("INSERT INTO `table` (`column`) VALUES ('$unsafe_variable')");
Run Code Online (Sandbox Code Playgroud)
这是因为用户可以输入类似的内容value'); DROP TABLE table;--
,查询变为:
INSERT INTO `table` (`column`) VALUES('value'); DROP TABLE table;--')
Run Code Online (Sandbox Code Playgroud)
可以采取哪些措施来防止这种情况发生?
即使使用mysql_real_escape_string()
函数,是否存在SQL注入的可能性?
考虑这个示例情况.SQL是用PHP构造的,如下所示:
$login = mysql_real_escape_string(GetFromPost('login'));
$password = mysql_real_escape_string(GetFromPost('password'));
$sql = "SELECT * FROM table WHERE login='$login' AND password='$password'";
Run Code Online (Sandbox Code Playgroud)
我听过很多人对我说,这样的代码仍然很危险,即使使用了mysql_real_escape_string()
函数也可以破解.但我想不出任何可能的漏洞?
像这样的经典注射:
aaa' OR 1=1 --
Run Code Online (Sandbox Code Playgroud)
不工作.
你知道任何可能通过上面的PHP代码注入的注入吗?
我配置了PHP,以便启用魔术引号并关闭注册全局变量.
我会尽力为我输出的任何来自用户输入的内容调用htmlentities().
我偶尔也会搜索我的数据库,以获取xss附带的常用内容,例如......
<script
Run Code Online (Sandbox Code Playgroud)
我还应该做些什么,以及如何确保我要做的事情总是完成.
我熟悉一些基础知识,但我想知道更多关于何时以及为什么错误处理(包括抛出异常)应该在PHP中使用,尤其是在实时网站或Web应用程序上.是否可以过度使用,如果是这样,过度使用会是什么样的?是否有不应该使用的情况?此外,有关错误处理的一些常见安全问题是什么?
我正在使用MySQL API的功能
mysql_real_escape_string()
Run Code Online (Sandbox Code Playgroud)
根据文档,它会转义以下字符:
\0
\n
\r
\
'
"
\Z
Run Code Online (Sandbox Code Playgroud)
现在,我查看了OWASP.org的ESAPI安全库,在Python端口中,它有以下代码(http://code.google.com/p/owasp-esapi-python/source/browse/esapi/codecs/mysql. py):
"""
Encodes a character for MySQL.
"""
lookup = {
0x00 : "\\0",
0x08 : "\\b",
0x09 : "\\t",
0x0a : "\\n",
0x0d : "\\r",
0x1a : "\\Z",
0x22 : '\\"',
0x25 : "\\%",
0x27 : "\\'",
0x5c : "\\\\",
0x5f : "\\_",
}
Run Code Online (Sandbox Code Playgroud)
现在,我想知道是否真的需要转义所有这些角色.我理解为什么%和_在那里,它们是LIKE运算符中的元字符,但我不能简单地理解他们为什么添加退格和制表符字符(\ b\t)?如果您执行查询,是否存在安全问题:
SELECT a FROM b WHERE c = '...user input ...';
Run Code Online (Sandbox Code Playgroud)
用户输入包含制表符或退格符的位置?
我的问题是:为什么它们在ESAPI安全库中包含\ b\t?在任何情况下你可能需要逃避这些角色吗?
我试图想出一种方法,用一个函数有效地轻松清理所有POST和GET变量.这是函数本身:
//clean the user's input
function cleanInput($value, $link = '')
{
//if the variable is an array, recurse into it
if(is_array($value))
{
//for each element in the array...
foreach($value as $key => $val)
{
//...clean the content of each variable in the array
$value[$key] = cleanInput($val);
}
//return clean array
return $value;
}
else
{
return mysql_real_escape_string(strip_tags(trim($value)), $link);
}
}
Run Code Online (Sandbox Code Playgroud)
以下是可以称之为的代码:
//This stops SQL Injection in POST vars
foreach ($_POST as $key => $value)
{
$_POST[$key] = cleanInput($value, $link);
} …
Run Code Online (Sandbox Code Playgroud) 我听过有人说(关于C#/ SQL Server,但也与PHP/MySql有关):不要手动转义字符串 - 而是使用存储过程.
好的,我可以接受这个建议,但为什么呢?很多人说(包括SO)mysql_real_escape_string()
就足够了,mysql_real_escape_string()
很好,mysql_real_escape_string()
是第一种保护方式.
为什么?有mysql_real_escape_string()
可能失败的情况吗?至少一个......我不需要很多:)
我刚开始在网上开发东西.到目前为止,我花了很多时间(50%左右)来尝试阻止坏人将sql注入等内容放入我的输入表单并验证服务器端.这是正常的吗?
问题:
什么是最好的safe1(),safe2(),safe3()和safe4()函数来避免UTS8编码页面的XSS?它在所有浏览器(特别是IE6)中也是安全的吗?
<body><?php echo safe1($xss)?></body>
<body id="<?php echo safe2($xss)?>"></body>
<script type="text/javascript">
var a = "<?php echo safe3($xss)?>";
</script>
<style type="text/css">
.myclass {width:<?php echo safe4($xss)?>}
</style>
Run Code Online (Sandbox Code Playgroud)
.
很多人说可以做的绝对最好的是:
// safe1 & safe2
$s = htmlentities($s, ENT_QUOTES, "UTF-8");
// But how would you compare the above to:
// https://github.com/shadowhand/purifier
// OR http://kohanaframework.org/3.0/guide/api/Security#xss_clean
// OR is there an even better if not perfect solution?
Run Code Online (Sandbox Code Playgroud)
.
// safe3
$s = mb_convert_encoding($s, "UTF-8", "UTF-8");
$s = htmlentities($s, ENT_QUOTES, "UTF-8");
// How would you compare this …
Run Code Online (Sandbox Code Playgroud) 这是参考这个(优秀的)答案.他指出,在PHP中逃脱输入最好的解决方法是调用mb_convert_encoding随后html_entities.
但是为什么你会使用相同的to和from参数(UTF8)调用mb_convert_encoding?
摘自原始答案:
即使您在HTML标记之外使用htmlspecialchars($ string),您仍然容易受到多字节字符集攻击向量的攻击.
最有效的方法是使用mb_convert_encoding和htmlentities的组合,如下所示.
Run Code Online (Sandbox Code Playgroud)$str = mb_convert_encoding($str, 'UTF-8', 'UTF-8'); $str = htmlentities($str, ENT_QUOTES, 'UTF-8');
这有什么好处我不见了?
php ×8
security ×7
mysql ×4
xss ×3
sql ×2
character ×1
escaping ×1
javascript ×1
post ×1
sanitization ×1
user-input ×1
variables ×1