`

php网站如何防止sql注入?

    博客分类:
  • php5
阅读更多

php网站如何防止sql注入?

网站的运行安全肯定是每个站长必须考虑的问题,大家知道,大多数黑客攻击网站都是采用sql注入,这就是我们常说的为什么最原始的静态的网站反而是最安全的。 今天我们讲讲PHP注入的安全规范,防止自己的网站被sql注入。

如今主流的网站开发语言还是php,那我们就从php网站如何防止sql注入开始说起:

Php注入的安全防范通过上面的过程,我们可以了解到php注入的原理和手法,当然我们也同样可以制定出相应该的防范方法:
首先是对服务器的安全设置,这里主要是php+mysql的安全设置和linux主机的安全设置。对php+mysql注射的防范,首先将magic_quotes_gpc设置为On,display_errors设置为Off,如果id型,我们利用intval()将其转换成整数类型,如代码:
$id=intval($id);
mysql_query=”select *from example where articieid=’$id’”;或者这样写:mysql_query(”SELECT * FROM article WHERE articleid=”.intval($id).”")

如果是字符型就用addslashes()过滤一下,然后再过滤”%”和”_”如:
$search=addslashes($search);
$search=str_replace(“_”,”\_”,$search);
$search=str_replace(“%”,”\%”,$search);
当然也可以加php通用防注入代码:
/*************************
PHP通用防注入安全代码
说明:
判断传递的变量中是否含有非法字符
如$_POST、$_GET
功能:
防注入
**************************/
//要过滤的非法字符
$ArrFiltrate=array(”‘”,”;”,”union”);
//出错后要跳转的url,不填则默认前一页
$StrGoUrl=”";
//是否存在数组中的值
function FunStringExist($StrFiltrate,$ArrFiltrate){
foreach ($ArrFiltrate as $key=>$value){
if (eregi($value,$StrFiltrate)){
return true;
}
}
return false;
}
//合并$_POST 和 $_GET
if(function_exists(array_merge)){
$ArrPostAndGet=array_merge($HTTP_POST_VARS,$HTTP_GET_VARS);
}else{
foreach($HTTP_POST_VARS as $key=>$value){
$ArrPostAndGet[]=$value;
}
foreach($HTTP_GET_VARS as $key=>$value){
$ArrPostAndGet[]=$value;
}
}
//验证开始
foreach($ArrPostAndGet as $key=>$value){
if (FunStringExist($value,$ArrFiltrate)){
echo “alert(/”Neeao提示,非法字符/”);”;
if (empty($StrGoUrl)){
echo “history.go(-1);”;
}else{
echo “window.location=/”".$StrGoUrl.”/”;”;
}
exit;
}
}
?>
/*************************
保存为checkpostandget.php
然后在每个php文件前加include(“checkpostandget.php“);即可
**************************/

另外将管理员用户名和密码都采取md5加密,这样就能有效地防止了php的注入。
还有服务器和mysql也要加强一些安全防范。
对于linux服务器的安全设置:
加密口令,使用“/usr/sbin/authconfig”工具打开密码的shadow功能,对password进行加密。
禁止访问重要文件,进入linux命令界面,在提示符下输入:
#chmod 600 /etc/inetd.conf //改变文件属性为600
#chattr +I   /etc/inetd.conf     //保证文件属主为root
#chattr –I   /etc/inetd.conf     // 对该文件的改变做限制
禁止任何用户通过su命令改变为root用户
在su配置文件即/etc/pam.d/目录下的开头添加下面两行:
Auth   sufficient   /lib/security/pam_rootok.so debug
Auth   required   /lib/security/pam_whell.so group=wheel
删除所有的特殊帐户
#userdel   lp等等 删除用户
#groupdel lp等等 删除组
禁止不使用的suid/sgid程序
#find / -type f \(-perm -04000   - o –perm -02000 \) \-execls –lg {} \;

 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

一直搞.net ,最近研究PHP,也涉及到防注入的安全措施,和.net的大同小异,从网上摘回一篇,作为备注,以供自己需要时查阅。

介绍两种方法吧,首先请把以下代码保存为safe.php放在网站根目录下,然后在每个php文件前加include(“/safe.php“);即可 :

php防注入代码方法一:

<?php
//要过滤的非法字符
$ArrFiltrate=array(”‘”,”;”,”union”);
//出错后要跳转的url,不填则默认前一页
$StrGoUrl=””;
//是否存在数组中的值
function FunStringExist($StrFiltrate,$ArrFiltrate){
foreach ($ArrFiltrate as $key=>$value){
if (eregi($value,$StrFiltrate)){
return true;
}
}
return false;
}
//合并$_POST 和 $_GET
if(function_exists(array_merge)){
$ArrPostAndGet=array_merge($HTTP_POST_VARS,$HTTP_GET_VARS);
}else{
foreach($HTTP_POST_VARS as $key=>$value){
$ArrPostAndGet[]=$value;
}
foreach($HTTP_GET_VARS as $key=>$value){
$ArrPostAndGet[]=$value;
}
}
//验证开始
foreach($ArrPostAndGet as $key=>$value){
if (FunStringExist($value,$ArrFiltrate)){
echo “<script language=\”javascript\”>alert(\”非法字符\”);</script>”;
if (emptyempty($StrGoUrl)){
echo “<script language=\”javascript\”>history.go(-1);</script>”;
}else{
echo “<script language=\”javascript\”>window.location=\””.$StrGoUrl.”\”;</script>”;
}
exit;
}
}
?>

php防注入代码方法二:

/* 过滤所有GET过来变量 */
foreach ($_GET as $get_key=>$get_var)
{
if (is_numeric($get_var)) {
$get[strtolower($get_key)] = get_int($get_var);
} else {
$get[strtolower($get_key)] = get_str($get_var);
}
}
/* 过滤所有POST过来的变量 */
foreach ($_POST as $post_key=>$post_var)
{
if (is_numeric($post_var)) {
$post[strtolower($post_key)] = get_int($post_var);
} else {
$post[strtolower($post_key)] = get_str($post_var);
}
}
/* 过滤函数 */
//整型过滤函数
function get_int($number)
{
return intval($number);
}
//字符串型过滤函数
function get_str($string)
{
if (!get_magic_quotes_gpc()) {
return addslashes($string);
}
return $string;
}

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

在现在各种黑客横行的时候,如何实现自己php代码安全,保证程序和服务器的安全是一个很重要的问题,我随便看了下关于php安全的资料,并不是很多,至少比asp少多了,呵呵,于是就想写点东西,来防止这些可能出现的情况。这里没有太深的技术含量,我只是比较简单的谈了谈。(以下操作如无具体说明,都是基于PHP+MySQL+Apache的情况)

    先来说说安全问题,我们首先看一下两篇文章:
http://www.xfocus.net/articles/200107/227.html    
http://www.xfocus.net/articles/200107/228.html

    上面文章是安全焦点上的关于PHP安全的文章,基本上比较全面的介绍了关于PHP的一些安全问题。

    在PHP编码的时候,如果考虑到一些比较基本的安全问题,首先一点:
1. 初始化你的变量

    为什么这么说呢?我们看下面的代码
if ($admin)
{
    echo '登陆成功!';
    include('admin.php');
}
else
{
    echo '你不是管理员,无法进行管理!';
}

    好,我们看上面的代码好像是能正常运行,没有问题,那么加入我提交一个非法的参数过去呢,那么效果会如何呢?比如我们的这个页是 http://www.traget.com/login.php,那么我们提交:http://www.target.com/login.php?admin=1,呵呵,你想一些,我们是不是直接就是管理员了,直接进行管理。
    当然,可能我们不会犯这么简单错的错误,那么一些很隐秘的错误也可能导致这个问题,比如最近暴出来的phpwind 1.3.6论坛有个漏洞,导致能够直接拿到管理员权限,就是因为有个$skin变量没有初始化,导致了后面一系列问题。

    那么我们如何避免上面的问题呢?首先,从php.ini入手,把php.ini里面的register_global = off,就是不是所有的注册变量为全局,那么就能避免了。但是,我们不是服务器管理员,只能从代码上改进了,那么我们如何改进上面的代码呢?我们改写如下:
$admin = 0;      // 初始化变量
if ($_POST['admin_user'] && $_POST['admin_pass'])
{
    // 判断提交的管理员用户名和密码是不是对的相应的处理代码
    // ...
    $admin = 1;
}
else
{
    $admin = 0;
}

if ($admin)
{
    echo '登陆成功!';
    include('admin.php');
}
else
{
    echo '你不是管理员,无法进行管理!';
}

    那么这时候你再提交 http://www.target.com/login.php?admin=1 就不好使了,因为我们在一开始就把变量初始化为 $admin = 0 了,那么你就无法通过这个漏洞获取管理员权限。


2. 防止SQL Injection (sql注射)

    SQL 注射应该是目前程序危害最大的了,包括最早从asp到php,基本上都是国内这两年流行的技术,基本原理就是通过对提交变量的不过滤形成注入点然后使恶意用户能够提交一些sql查询语句,导致重要数据被窃取、数据丢失或者损坏,或者被入侵到后台管理。
基本原理我就不说了,我们看看下面两篇文章就很明白了:
http://www.4ngel.net/article/36.htm
http://www.4ngel.net/article/30.htm

    那么我们既然了解了基本的注射入侵的方式,那么我们如何去防范呢?这个就应该我们从代码去入手了。

    我们知道Web上提交数据有两种方式,一种是get、一种是post,那么很多常见的sql注射就是从get方式入手的,而且注射的语句里面一定是包含一些sql语句的,因为没有sql语句,那么如何进行,sql语句有四大句:
    select 、update、delete、insert,那么我们如果在我们提交的数据中进行过滤是不是能够避免这些问题呢?
    于是我们使用正则就构建如下函数:

/*
函数名称:inject_check()
函数作用:检测提交的值是不是含有SQL注射的字符,防止注射,保护服务器安全
参        数:$sql_str: 提交的变量
返 回 值:返回检测结果,ture or false
函数作者:heiyeluren
*/
function inject_check($sql_str)
{
     return eregi('select|insert|update|delete|'|/*|*|../|./|union|into|load_file|outfile', $sql_str);    // 进行过滤
 }

    我们函数里把 select,insert,update,delete, union, into, load_file, outfile /*, ./ , ../ , ' 等等危险的参数字符串全部过滤掉,那么就能够控制提交的参数了,程序可以这么构建:

<?php
if (inject_check($_GET['id']))
{
     exit('你提交的数据非法,请检查后重新提交!');
}
else
{
    $id = $_GET['id'];
    echo '提交的数据合法,请继续!';
}
?>
    假设我们提交URL为:http://www.target.com/a.php?id=1,那么就会提示:
    "提交的数据合法,请继续!"
    如果我们提交 http://www.target.com/a.php?id=1%27 select * from tb_name
    就会出现提示:"你提交的数据非法,请检查后重新提交!"

    那么就达到了我们的要求。

    但是,问题还没有解决,假如我们提交的是 http://www.target.com/a.php?id=1asdfasdfasdf 呢,我们这个是符合上面的规则的,但是呢,它是不符合要求的,于是我们为了可能其他的情况,我们再构建一个函数来进行检查:

/*
函数名称:verify_id()
函数作用:校验提交的ID类值是否合法
参        数:$id: 提交的ID值
返 回 值:返回处理后的ID
函数作者:heiyeluren
*/
function verify_id($id=null)
{
   if (!$id) { exit('没有提交参数!'); }    // 是否为空判断
   elseif (inject_check($id)) { exit('提交的参数非法!'); }    // 注射判断
   elseif (!is_numeric($id)) { exit('提交的参数非法!'); }    // 数字判断
   $id = intval($id);    // 整型化
 
   return  $id;
}

    呵呵,那么我们就能够进行校验了,于是我们上面的程序代码就变成了下面的:

<?php
if (inject_check($_GET['id']))
{
     exit('你提交的数据非法,请检查后重新提交!');
}
else
{
    $id = verify_id($_GET['id']);    // 这里引用了我们的过滤函数,对$id进行过滤
    echo '提交的数据合法,请继续!';
}
?>

    好,问题到这里似乎都解决了,但是我们有没有考虑过post提交的数据,大批量的数据呢?
    比如一些字符可能会对数据库造成危害,比如 ' _ ', ' % ',这些字符都有特殊意义,那么我们如果进行控制呢?还有一点,就是当我们的php.ini里面的magic_quotes_gpc = off 的时候,那么提交的不符合数据库规则的数据都是不会自动在前面加' '的,那么我们要控制这些问题,于是构建如下函数:

/*
函数名称:str_check()
函数作用:对提交的字符串进行过滤
参    数:$var: 要处理的字符串
返 回 值:返回过滤后的字符串
函数作者:heiyeluren
*/
function str_check( $str )
{
   if (!get_magic_quotes_gpc())    // 判断magic_quotes_gpc是否打开
   {
      $str = addslashes($str);    // 进行过滤
 }
     $str = str_replace("_", "\_", $str);    // 把 '_'过滤掉
     $str = str_replace("%", "\%", $str);    // 把' % '过滤掉
  
   return $str;
}

OK,我们又一次的避免了服务器被沦陷的危险。

    最后,再考虑提交一些大批量数据的情况,比如发贴,或者写文章、新闻,我们需要一些函数来帮我们过滤和进行转换,再上面函数的基础上,我们构建如下函数:

/*
函数名称:post_check()
函数作用:对提交的编辑内容进行处理
参    数:$post: 要提交的内容
返 回 值:$post: 返回过滤后的内容
函数作者:heiyeluren
*/
function post_check($post)
{
   if (!get_magic_quotes_gpc())    // 判断magic_quotes_gpc是否为打开
   {
      $post = addslashes($post);    // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤
   }
   $post = str_replace("_", "\_", $post);    // 把 '_'过滤掉
   $post = str_replace("%", "\%", $post);    // 把' % '过滤掉
   $post = nl2br($post);    // 回车转换
   $post= htmlspecialchars($post);    // html标记转换
 
   return $post;
}

    呵呵,基本到这里,我们把一些情况都说了一遍,其实我觉得自己讲的东西还很少,至少我才只讲了两方面,再整个安全中是很少的内容了,考虑下一次讲更多,包括php安全配置,apache安全等等,让我们的安全正的是一个整体,作到最安全。

    最后在告诉你上面表达的:1. 初始化你的变量  2. 一定记得要过滤你的变量

 

+++++++++++++++++++++++++++++++++++++++++++++

对POST或GET数据过滤

$_POST = sql_injection($_POST);
$_GET = sql_injection($_GET);

function sql_injection($content)
{
if (!get_magic_quotes_gpc()) {
if (is_array($content)) {
foreach ($content as $key=>$value) {
$content[$key= addslashes($value);
}
else {
addslashes($content);
}
}
return $content;
}

/* 
函数名称:inject_check() 
函数作用:检测提交的值是不是含有SQL注射的字符,防止注射,保护服务器安全 
参  数:$sql_str: 提交的变量 
返 回 值:返回检测结果,ture or false 
*/ 
function inject_check($sql_str) { 
return eregi('select|insert|update|delete|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile', $sql_str); // 进行过滤 


/* 
函数名称:verify_id() 
函数作用:校验提交的ID类值是否合法 
参  数:$id: 提交的ID值 
返 回 值:返回处理后的ID 
*/ 
function verify_id($id=null) { 
if (!$id) { exit(
'没有提交参数!'); } // 是否为空判断 
elseif (inject_check($id)) { exit(
'提交的参数非法!'); } // 注射判断 
elseif (!is_numeric($id)) { exit(
'提交的参数非法!'); } // 数字判断 
$id = intval($id); // 整型化 

return $id; 


/* 
函数名称:str_check() 
函数作用:对提交的字符串进行过滤 
参  数:$var: 要处理的字符串 
返 回 值:返回过滤后的字符串 
*/ 
function str_check( $str ) { 
if (!get_magic_quotes_gpc()) { // 判断magic_quotes_gpc是否打开 
$str = addslashes($str); // 进行过滤 

$str = str_replace("_", "\_", $str); // 把 
'_'过滤掉 
$str = str_replace("%", "\%", $str); // 把 
'%'过滤掉 

return $str; 


/* 
函数名称:post_check() 
函数作用:对提交的编辑内容进行处理 
参  数:$post: 要提交的内容 
返 回 值:$post: 返回过滤后的内容 
*/ 
function post_check($post) { 
if (!get_magic_quotes_gpc()) { // 判断magic_quotes_gpc是否为打开 
$post = addslashes($post); // 进行magic_quotes_gpc没有打开的情况对提交数据的过滤 

$post = str_replace("_", "\_", $post); // 把 
'_'过滤掉 
$post = str_replace("%", "\%", $post); // 把 
'%'过滤掉 
$post = nl2br($post); // 回车转换 
$post = htmlspecialchars($post); // html标记转换 

return $post; 

分享到:
评论

相关推荐

    防止sql注入工具类l

    3. **使用安全库或工具类**:这里提到的“防止SQL注入工具类”可能是指一个专门用于处理SQL注入的PHP库。这个工具类可能提供了自动转义或参数化查询的功能,比如`mysqli_real_escape_string`函数,或者更高级的ORM...

    JS代码防止SQL注入的方法(超简单)

    本文主要介绍了如何使用JavaScript代码来防止SQL注入,这是为了保证Web应用的安全性,防止恶意用户通过输入特定的SQL语句来破坏数据库。文章从两个方面进行了说明,包括URL地址防注入和输入文本框防注入。 首先,...

    php中防止SQL注入的方法

    php中防止SQL注入的方法,安全,PHP代码编写是一方面,PHP的配置更是非常关键。

    PHP+Mysql 带SQL注入源码 下载

    在IT行业中,数据库的安全性是...综上所述,理解SQL注入的原理并掌握防止它的方法对于任何使用PHP和MySQL的开发者来说都是至关重要的。在部署任何包含用户输入的项目时,应始终优先考虑安全性,避免遭受SQL注入等攻击。

    寻找sql注入的网站的方法(必看)

    方法一:利用google高级搜索,比如搜索url如.asp?... 您可能感兴趣的文章:Java面试题解析之判断以及防止SQL注入SQL注入原理与解决方法代码示例通过ibatis解决sql注入问题Win2003服务器防SQL注入神器–D盾_IIS防火墙

    php168sql注入漏洞

    ### PHP168 SQL注入漏洞分析与利用 #### 背景介绍 PHP168是一款基于PHP语言开发的内容管理系统,被广泛应用于政府网站、企业官网等场景中。然而,在某些版本中,PHP168存在着严重的SQL注入漏洞,攻击者可以利用此...

    360提供的php防sql注入代码修改类

    SQL注入是一种利用网站应用程序的漏洞,通过输入恶意SQL语句来控制数据库的攻击手段。攻击者可以获取、修改、删除数据库中的敏感信息,甚至完全控制整个系统。为了防止SQL注入,我们需要遵循以下原则: 1. 使用...

    sql注入讲解ppt.pptx

    2. Prepared Statement:使用 Prepared Statement 来防止 SQL 注入攻击。 3. LIMIT 和 OFFSET:使用 LIMIT 和 OFFSET 限制查询结果,防止敏感数据泄露。 4.Least Privilege:使用最小权限原则,限制数据库用户的权限...

    使用PHP实现防止sql注入功能

    使用PHP实现防止sql注入功能 一、 开发环境 1、环境搭建:Windows 7+Apache 2.4.18+MySQL 5.7.11+PHP 7.1.0。 2、文本编辑器:Sublime 3。 二、主要技术 本案例主要在PHP中分别使用PDO的quote()方法和prepare()...

    SQL 注入天书.pdf

    SQL注入是一种常见的网络安全漏洞,发生在应用程序使用用户输入的SQL代码直接构建数据库查询时。当攻击者能够通过输入恶意SQL语句来控制或篡改...通过深入学习和实践,可以有效地防止SQL注入攻击,保障系统的安全。

    PHPSQL注入漏洞学习

    在网络安全领域,SQL注入是一种常见的攻击手段,尤其在PHP编程中更为常见。本文将深入探讨PHP SQL注入漏洞的原理、类型、影响以及防范措施,旨在帮助开发者更好地理解并避免此类安全问题。 一、SQL注入漏洞概述 SQL...

    php和asp防止sql注入类

    在提供的压缩包中,"phpsql防注入类.txt"和"asp防止sql注入.txt"可能包含了具体的类或函数实现,用于帮助开发者更方便地实现上述防护措施。这些类通常会包含输入验证、自动转义等功能,简化了代码中防止SQL注入的...

    SQL注入与防止SQL注入

    但最好的防御策略不是依赖这些设置,而是采用参数化查询或预编译语句,如PHP的PDO或MySQLi的预处理语句,这些方法能确保用户输入被正确地隔离,从而防止SQL注入。 例如,下面的PHP代码展示了如何使用预编译语句防止...

    SQL注入全面讲解技术文档

    PHP应用同样面临SQL注入问题,开发者应使用预处理语句(如PDO或MySQLi的prepare/execute)来防止注入,并避免使用`eval()`等危险函数。 5. 检测和防御SQL注入和跨站脚本攻击: - 使用自动化工具进行扫描,如...

    CmsEasy crossall_act.php SQL注入漏洞.md

    SQL注入攻击者可以通过这个漏洞在数据库中执行恶意的SQL语句,从而对网站数据库进行非授权的操作。 ### SQL注入漏洞知识点 1. **SQL注入概念** SQL注入(SQL Injection)是一种攻击技术,攻击者通过在Web表单输入...

    JavaScript过滤SQL注入字符

    JavaScript作为客户端脚本语言,虽然主要负责与用户交互,但也可以在防止SQL注入方面发挥作用。本文将深入探讨如何利用JavaScript进行SQL注入的过滤。 一、理解SQL注入 SQL注入是指攻击者在用户输入的数据中插入...

    PHP中全面阻止SQL注入式攻击

    - **安全性**:通过避免将用户输入直接拼接到SQL语句中,可以有效防止SQL注入攻击。 - **性能提升**:预处理语句可以减少数据库的解析时间,提高查询效率。 2. **输入验证与清理** - **定义**:在处理用户输入...

    metinfo 后台sql注入1

    可以使用预编译的SQL语句(如PHP的PDO或MySQLi的预处理语句),或者对用户输入进行转义处理,以防止SQL注入的发生。 总的来说,MetInfo的这个SQL注入漏洞提醒我们,无论使用何种内容管理系统,都必须时刻关注安全...

    web安全性测试之sql注入入门篇

    * 使用参数化查询来防止注入 * 对用户输入数据进行严格的验证和过滤 * 限制数据库的访问权限和权限 * 使用 WEB 应用防火墙来防御攻击 ASP SQL 注入 ASP SQL 注入是指在 ASP 应用程序中使用的 SQL 注入攻击。ASP ...

Global site tag (gtag.js) - Google Analytics