更具安全性的addslashes_deep函数-by Sodoit

2016-07-07 15:00 来源:www.chinab4c.com 作者:ecshop专家

我们知道,ecshop的很多漏洞都是因为对变量的过滤不严格而导致mysql注入的,虽然在init.php文件里有对$_GET,$_GET,$_COOKIE,$_REQUEST用addslashes_deep进行处理,但是,分析addslashes_deep函数后我们就可以发现,该函数只处理数组的值,对数组的key是完全不作任何过滤的,这直接导致了漏洞。例如:
http://bbs.honkwin.com/read-htm-tid-6174.html
http://sebug.net/vulndb/20188/

为此,我们应该重写addslashes_deep函数,下面是我的代码:


  1. function addslashes_deep($value,$htmlspecialchars=false)
  2. {
  3. if (empty($value))
  4. {
  5. return $value;
  6. }
  7. else
  8. {
  9. if(is_array($value))
  10. {
  11. foreach($value as $key => $v)
  12. {
  13. unset($value[$key]);

  14. if($htmlspecialchars==true)
  15. {
  16. $key=addslashes(htmlspecialchars($key));
  17. }
  18. else{
  19. $key=addslashes($key);
  20. }

  21. if(is_array($v))
  22. {
  23. $value[$key]=addslashes_deep($v);
  24. }
  25. else{
  26. if($htmlspecialchars==true)
  27. {
  28. $value[$key]=addslashes(htmlspecialchars($v));
  29. }
  30. else{
  31. $value[$key]=addslashes($v);
  32. }
  33. }
  34. }
  35. }
  36. else{
  37. if($htmlspecialchars==true)
  38. {
  39. $value=addslashes(htmlspecialchars($value));
  40. }
  41. else{
  42. $value=addslashes($value);
  43. }
  44. }

  45. return $value;
  46. }
  47. }
复制代码


该函数对数组的值和key都进行了addslashes处理,并且根据需要,还可以进行htmlspecialchars过滤。在init.php文件里,应该这样调用:
$_GET= addslashes_deep($_GET,true);
$_POST = addslashes_deep($_POST,true);
$_COOKIE= addslashes_deep($_COOKIE,true);
$_REQUEST= addslashes_deep($_REQUEST,true);

回答:
沙发顶一下

可以缓解缓解
不过很对还是EC的程序员们大意了 很多细节没有注意到!

刚才发现上面的函数在使用json的时候会有问题,因为htmlspecialchars函数会对引号进行替换,导致json格式错误,修正如下:

  1. function addslashes_deep($value,$htmlspecialchars=false)
  2. {
  3. if (empty($value))
  4. {
  5. return $value;
  6. }
  7. else
  8. {
  9. if(is_array($value))
  10. {
  11. foreach($value as $key => $v)
  12. {
  13. unset($value[$key]);

  14. if($htmlspecialchars==true)
  15. {
  16. $key=get_magic_quotes_gpc()? addslashes(stripslashes(htmlspecialchars($key,ENT_NOQUOTES))) : addslashes(htmlspecialchars($key,ENT_NOQUOTES));
  17. }
  18. else{
  19. $key=get_magic_quotes_gpc()? addslashes(stripslashes($key)) : addslashes($key);
  20. }

  21. if(is_array($v))
  22. {
  23. $value[$key]=addslashes_deep($v);
  24. }
  25. else{
  26. if($htmlspecialchars==true)
  27. {
  28. $value[$key]=get_magic_quotes_gpc()? addslashes(stripslashes(htmlspecialchars($v,ENT_NOQUOTES))) : addslashes(htmlspecialchars($v,ENT_NOQUOTES));
  29. }
  30. else{
  31. $value[$key]=get_magic_quotes_gpc()? addslashes(stripslashes($v)) : addslashes($v);
  32. }
  33. }
  34. }
  35. }
  36. else{
  37. if($htmlspecialchars==true)
  38. {
  39. $value=get_magic_quotes_gpc()? addslashes(stripslashes(htmlspecialchars($value,ENT_NOQUOTES))) : addslashes(htmlspecialchars($value,ENT_NOQUOTES));
  40. }
  41. else{
  42. $value=get_magic_quotes_gpc()? addslashes(stripslashes($value)) : addslashes($value);
  43. }
  44. }

  45. return $value;
  46. }
  47. }
复制代码

有几个地方不明白希望楼主指教 我的QQ283123640

赞一个,


有不明白的地方呀,原本的函数function addslashes_deep($value)只有一个参数,楼主重写的时候怎么变成两个参数呢?我不懂php啊,但我想如果其他文件里有函数调用这个addslashes_deep,会不会因为参数问题报错?

楼主,想请教你啊,看过你写过的另一帖,说是修改cls_mysql.php文件的ErrorMsg函数的,我照你的方法该了,那现在我想试下注入攻击,然后查看那个data/sql_log文件,该怎么操作呢?

太复杂了吧

看这样的效果
  1. function addslashes_deep($value)
  2. {
  3. if (empty($value))
  4. {
  5. return $value;
  6. }
  7. else
  8. {
  9. if(is_string($value))
  10. {
  11. $value = trim(htmlspecialchars($value));//防止被挂马,跨站攻击
  12. if(!get_magic_quotes_gpc())
  13. {
  14. $value = addslashes($value);//防止sql注入
  15. }
  16. /*觉得还不安全可以再加上下面2个
  17. $value = str_replace("_", "\_", $value);
  18. $value = str_replace("%", "\%", $value);
  19. */
  20. return$value;
  21. }
  22. else if(is_array($value))//如果是数组采用递归过滤
  23. {
  24. foreach($value as $key => $vl)
  25. {
  26. $value[$key] = addslashes_deep($vl);
  27. }
  28. return $value;
  29. }
  30. else
  31. {
  32. return $value;
  33. }
  34. //return is_array($value) ? array_map('addslashes_deep', $value) : addslashes($value);
  35. }
  36. }
复制代码

安全无小事,支持分亨

这么久的帖子被顶出来了,我自己就再顶下吧。

看这样的效果
zatxm 发表于 2011-12-21 18:45

你这个仍旧没有对数组的key做处理,和ecshop自带的就没啥区别了。

再对数组的key作下addslashes_deep()操作不就有了,也没多大麻烦