这篇文章主要介绍了 php 防止 sql 注入漏洞代码和分析, 最近提供了几种常见攻击的正则表达式, 大家参考使用吧
注入漏洞代码和分析
代码如下:
- function customError($errno, $errstr, $errfile, $errline)
- {
- echo "Error number: [$errno],error on line $errline in $errfile";
- die();
- }
- set_error_handler("customError",E_ERROR);
- $getfilter="'|(and|or)\\b.+?(>|<|=|in|like)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
- $postfilter="\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
- $cookiefilter="\\b(and|or)\\b.{1,6}?(=|>|<|\\bin\\b|\\blike\\b)|\\/\\*.+?\\*\\/|<\\s*script\\b|\\bEXEC\\b|UNION.+?SELECT|UPDATE.+?SET|INSERT\\s+INTO.+?VALUES|(SELECT|DELETE).+?FROM|(CREATE|ALTER|DROP|TRUNCATE)\\s+(TABLE|DATABASE)";
- function StopAttack($StrFiltKey,$StrFiltValue,$ArrFiltReq)
- {
- if(is_array($StrFiltValue))
- {
- $StrFiltValue=implode($StrFiltValue);
- }
- if (preg_match("/".$ArrFiltReq."/is",$StrFiltValue)==1&&!isset($_REQUEST['securityToken']))
- {
- slog("操作 IP:".$_SERVER["REMOTE_ADDR"]."操作时间:".strftime("%Y-%m-%d %H:%M:%S")."操作页面:".$_SERVER["PHP_SELF"]."提交方式:".$_SERVER["REQUEST_METHOD"]."提交参数:".$StrFiltKey."提交数据:".$StrFiltValue);
- print "result notice:Illegal operation!";
- exit();
- }
- }
- foreach($_GET as $key=>$value)
- {
- StopAttack($key,$value,$getfilter);
- }
- foreach($_POST as $key=>$value)
- {
- StopAttack($key,$value,$postfilter);
- }
- foreach($_COOKIE as $key=>$value)
- {
- StopAttack($key,$value,$cookiefilter);
- }
- function slog($logs)
- {
- $toppath="log.htm";
- $Ts=fopen($toppath,"a+");
- fputs($Ts,$logs."\r\n");
- fclose($Ts);
- }
- ?>
- sql
分析
如果使用这个函数的话, 这个函数会绕开 PHP 的标准出错处理, 所以说得自己定义报错处理程序(die())
其次, 如果代码执行前就发生了错误, 那个时候用户自定义的程序还没有执行, 所以就不会用到用户自己写的报错处理程序
那么, PHP 里有一套错误处理机制, 可以使用 set_error_handler()接管 PHP 错误处理, 也可以使用 trigger_error()函数主动抛出一个错误
set_error_handler()函数设置用户自定义的错误处理函数函数用于创建运行期间的用户自己的错误处理方法它需要先创建一个错误处理函数, 然后设置错误级别
关于的用法:
代码如下:
- function customError($errno, $errstr, $errfile, $errline)
- {
- echo "错误代码: [${errno}] ${errstr}\r\n";
- echo "错误所在的代码行: {$errline} 文件{$errfile}\r\n";
- echo "PHP 版本",PHP_VERSION, "(" , PHP_OS, ")\r\n";
- // die();
- }
- set_error_handler("customError",E_ALL| E_STRICT);
在这个函数里, 可以做任何要做的事情, 包括对错误的详情进行格式化输出, 记入 log 文件
代码如下:
- function slog($logs)
- {
- $toppath="log.htm";
- $Ts=fopen($toppath,"a+");
- fputs($Ts,$logs."\r\n");
- fclose($Ts);
- }
自定义的错误处理函数一定要有这四个输入变量 $errno$errstr$errfile$errline
errno 是一组常量, 代表错误的等级, 同时也有一组整数和其对应, 但一般使用其字符串值表示, 这样语义更好一点比如 E_WARNING, 其二进制掩码为 4, 表示警告信息
接下来, 就是将这个函数作为回调参数传递给 set_error_handler 这样就能接管 PHP 原生的错误处理函数了要注意的是, 这种托管方式并不能托管所有种类的错误, 如 E_ERRORE_PARSEE_CORE_ERRORE_CORE_WARNINGE_COMPILE_ERRORE_COMPILE_WARNING, 以及 E_STRICT 中的部分这些错误会以最原始的方式显示, 或者不显示
StopAttack()函数是将传递过来的 POSTGETCOOKIE 进行正则表达式和调用 slog()写入 log 文件
代码如下:
- $Exec_Commond = "( \\s|\\S)*(exec(\\s|\\+)+(s|x)p\\w+)(\\s|\\S)*";
- $Simple_XSS = "( \\s|\\S)*((%3C)|<)((%2F)|/)*[a-z0-9%]+((%3E)|>)(\\s|\\S)*";
- $Eval_XSS = "( \\s|\\S)*((%65)|e)(\\s)*((%76)|v)(\\s)*((%61)|a)(\\s)*((%6C)|l)(\\s|\\S)*";
- $Image_XSS = "( \\s|\\S)*((%3C)|<)((%69)|i|I|(%49))((%6D)|m|M|(%4D))((%67)|g|G|(%47))[^\\n]+((%3E)|>)(\\s|\\S)*" ;
- $Script_XSS = "( \\s|\\S)*((%73)|s)(\\s)*((%63)|c)(\\s)*((%72)|r)(\\s)*((%69)|i)(\\s)*((%70)|p)(\\s)*((%74)|t)(\\s|\\S)*";
- $SQL_Injection = "( \\s|\\S)*((%27)|(')|(%3D)|(=)|(/)|(%2F)|(\")|((%22)|(-|%2D){2})|(%23)|(%3B)|(;))+(\\s|\\S)*";
HP 遇到错误时, 就会给出出错脚本的位置行数和原因, 有很多人说, 这并没有什么大不了但泄露了实际路径的后果是不堪设想的, 对于某些入侵者, 这个信息可是非常重要, 而事实上现在有很多的服务器都存在这个问题 有些网管干脆把 PHP 配置文件中的 display_errors 设置为 Off 来解决, 但本人认为这个方法过于消极有些时候, 我们的确需要 PHP 返回错误的信息以便调试而且在出错时也可能需要给用户一个交待, 甚至导航到另一页面但是有了 set_error_handler()之后, 这些矛盾也都可以解决掉了
来源: https://www.php1.cn/detail/php-bcdb3fd483.html