探讨PHP SQL注入的解决思路 为什么SQL语句都用双引号呢?因为在PHP写SQL语句都是有变量的,所以在PHP是用双引号表示字符串,如果SQL也用双的话就要转义了。这样比用单引号麻烦多了。 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 不好意思,是SQL语句中的变量能用2个引号闭合的就用2个引号闭合(比如任何简单的变量),非双引号;--想法宗旨是不能让多余的SQL执行.1 sql中的变量如果是指定字符型,时间日期,等等非数值型,加上转义函数(下面的convertStr()),随便变量里面输入什么字符,包括#,--(转义函数并不转义这2个字符,mysql中用于注释);总归还是一个字符串,不会有意想不到的执行结果;2 sql中的变量如果是数值型和数学运算,调用convertNum(),判断是否是数字,同时非数字的情况返回一个默认值(2个功能,1 不会让数据库报错;2 阻止sql注入);3 其他情况,如IN($a,$b),视情况调用下面的函数,或预先判断;function convertStr($string){ if (!get_magic_quotes_gpc()) { return addslashes($string); } return $string;}function convertNum($num,$val=0){//参数$val用于输入非数值的时候返回值,默认是0;//其他可根据实际情况,自己赋值; if(is_numeric($num)){ return $num; }else{ return $val; }} 此处有sql注入的形形色色的方法,有兴趣的不妨研究一下有没有漏洞http://blog.csdn.net/MPU/archive/2006/10/13/1333104.aspx 1 所有非数值运算(如字符,简单数值型等等)的SQL变量都加引号;这是必须的,并非是解决SQL注入的需要。否则将不能通过sql的语法检查注意一个事实:mysql5已默认关闭自动类型转换,即向数值型字段写入串时(比如'100')将产生语法错误2 所有非数值运算的SQL变量的值都采用magic_quotes_gpc或者addslashes转义;这也是必须的,也并非是解决SQL注入的需要。sql中用单引号“'”做为串的边界,所以串中的单引号必须进行转义3 对需要数值运算的变量和其他不能加引号的SQL(如IN语句),预先判断变量类型.莫明奇妙!向字段赋予正确的值是起码的条件“不能加引号的SQL(如IN语句)”不知何意?4 关闭php.ini的disply_error.(可选,如不能关闭,需自己手动让SQL语句不能执行报错)这还差不多 http://blog.csdn.net/MPU/archive/2006/10/13/1333104.aspx 1 所有字符串变量全用单引号关闭边界。2 所有数值型变量全用intval()转化。 对于 xuzuning(唠叨) 的第三点,我觉得说的有点不够恰当。LZ说的“对需要数值运算的变量,预先判断变量类型”是非常有道理的。因为在很多情况下,SQL文中的值都是从表单过来的,你并不能限制用户输入什么,但是做必要的判断是必须的。 突然发现一个问题。如果所有的SQL查询被写成存储过程的话。所有的注入都会失效。也就是说不存在注入的情况。 楼上的 marse(阿彪) 兄弟, 用户输入什么我们管不着,这对,但是,数据库总是你设计的吧, 向里面插入什么类型的值你总是必须要知道的吧?MySQL已经取消了自动变量类型转换,那么你就在也不能把数值数据朝字符串字段中插入了!比如我的数值字段 testid=$testid如果你非要输入'30' 或者 abdf 或者 'sjdf'那我只能@mysql_query() or die()了, 我还能有什么办法? to marse(阿彪) 不错,LZ说的“对需要数值运算的变量,预先判断变量类型”是非常有道理的。但是这是对数据库操作的基本要求,而不是什么防止sql注入的手段 to xuzuning(唠叨) :LZ说的“对需要数值运算的变量,预先判断变量类型”是对数据库操作的基本要求,但是在某种程度上的确是可以防止sql注入的手段。(现在好像不是在讨论技术,好像在讨论语文了。赫赫)to:PleaseDoTellMeWhy(沉默坚持) **********************************比如我的数值字段 testid=$testid如果你非要输入'30' 或者 abdf 或者 'sjdf'那我只能@mysql_query() or die()了, 我还能有什么办法?******************************************************你要是先判断一下,然后给出一个提示“ID只能输入数字”的错误。是不是比die()更人性化一点呢? “探讨PHP SQL注入的解决思路”不要离题太远!!! LZ, 借个地方啊!唠叨老大,我想问问您我的这个方法是否可行?@extract( alladdslashes($_GET) );@extract( alladdslashes($_POST) );@extract( alladdslashes($_COOKIE) );function alladdslashes($mixvar) { if ( !get_magic_quotes_gpc() ) { $mixvar = is_array($mixvar) ? array_map('alladdslashes', $mixvar) : addslashes($mixvar); } return $mixvar;}我现在也遇到了个问题, 上面的代码向数据库中插入的时候我还没发现啥!但是从数据库中读出数据显示到<input>表单的文本框中就出现了问题!比如数据库中有个数据 是'"\读出来到<input value="'"\"这个问题如何解决,我目前的解决方法就是function dealwith($string) { $string = str_replace( '&', '&', $string ); $string = str_replace( '"', '"', $string ); $string = str_replace( "'", ''', $string ); $string = str_replace( '\\', '\\\\', $string ); return $string;}您又什么好的方法吗? 能详细的说说吗? 谢了...大家都说说........ 你用这个函数htmlentities应该就可以了阿<?$value=htmlentities("'\"\\");?><input type="text" value="<?=$value?>"> 楼上的兄弟说的意思我明白! 但是INSERT 的时候数据库中的值是 '"\UPDATE 的时候数据库中的值是 '"\\如果有的值没有 UPDATE 呢, 意思是 UPDATE 之前还要把那些字符实体转过来? <input type="text" name="test" value="'"\">这样子的表单post得到的$_POST["test"]不会是[ '"\ ],而是[ \'\"\\ ](考虑到你的函数@extract( alladdslashes($_POST));所以有转义) "mysql5已默认关闭自动类型转换,即向数值型字段写入串时(比如'100')将产生语法错误"-------------------------------------------- 这个设定在哪里? 没找着. 我的mysql5似乎没问题. 我的mysql5也不产生这个语法错误 关于“mysql5已默认关闭自动类型转换”的问题:我没有深入了解过,但本论坛确实有几个帖子讨论过此事最近新装mysql5.0.24,确实有此现象关于出入库数据转义的问题:1、通过判断 magic_quotes_gpc 开关状态来决定外部数据是否要做转义处理是正确的2、送往输入控件 input、textarea 的内容要用 htmlspecialchars 函数做html编码处理,以防引号不配对和html格式错误关于sql注入的问题:1、由于php本身的保护,查询指令已不可能被拆分成多句。2、你只需检查放在过滤条件中的外部数据是否符合要求 非常感谢唠叨老大和各位兄弟!原来是我没明白 input textarea 控件中提交时候值的转换问题!我刚写了个程序测试了,这个问题是弄明白了!再次感谢大家! 还是来点sql injection的技巧探讨吧,毕竟这是一种比较有技术含量的攻击方式之一,比那些用tool攻击网站的方式有趣多了。 mysql_escape_string() 和 mysql_real_escape_string() 这两个函数呢?大家都有什么看法? blue009(云飞扬) 1 所有字符串变量全用单引号关闭边界。2 所有数值型变量全用intval()转化。----------------------------------------第2不同意,小于最大整数的整数是可以用intval(),超过边界的整数或者小数,浮点数要注意这些情况不过我用的64位机,最大整数到了千亿亿,一般整数都够用了 我的处理方法:魔术引号就是个鸡肋对于新手来说可能有点用但addslashes是有漏洞的(google一下就知道了)我现在是先判断是否有magic_quotes_gpc,如果有的话还要把数据还原(stripslashes)在sql查询时用mysql_real_escape_string(),这个函数是根据当前连接字符集来转义的,比addslashes安全其他的就是所有的数据都确定类型 借地方问个相关的问题mysql5+,下面的语句会出错吗?$sql = "INSERT INTO table_name (test_id, test_name) VALUES ('11', 'my_name')";test_id是int类型这样会出错? 奇怪的Warning: Invalid argument supplied for foreach() 字符串转义 论坛中的转到功能 远程mysql连接问题 [求]字符串截取函数,要求见贴 制作一个新闻发布板,请赐教! 如何实现把*.sql 的文件到入到mysql里面? ezpublish(可以在www.ez.no下载) phpteam请进,在线~~~~~ ubunut12.04安装apache mod speling 这几天写的php树类. 有人用过cakephp框架吗,进来帮帮我!
是SQL语句中的变量能用2个引号闭合的就用2个引号闭合(比如任何简单的变量),非双引号;
--想法宗旨是不能让多余的SQL执行.1 sql中的变量如果是指定字符型,时间日期,等等非数值型,加上转义函数(下面的convertStr()),随便变量里面输入什么字符,包括#,--(转义函数并不转义这2个字符,mysql中用于注释);总归还是一个字符串,不会有意想不到的执行结果;2 sql中的变量如果是数值型和数学运算,调用convertNum(),判断是否是数字,同时非数字的情况返回一个默认值(2个功能,1 不会让数据库报错;2 阻止sql注入);3 其他情况,如IN($a,$b),视情况调用下面的函数,或预先判断;
function convertStr($string)
{
if (!get_magic_quotes_gpc()) {
return addslashes($string);
}
return $string;
}function convertNum($num,$val=0){
//参数$val用于输入非数值的时候返回值,默认是0;
//其他可根据实际情况,自己赋值;
if(is_numeric($num)){
return $num;
}else{
return $val;
}
}
http://blog.csdn.net/MPU/archive/2006/10/13/1333104.aspx
这是必须的,并非是解决SQL注入的需要。否则将不能通过sql的语法检查
注意一个事实:mysql5已默认关闭自动类型转换,即向数值型字段写入串时(比如'100')将产生语法错误2 所有非数值运算的SQL变量的值都采用magic_quotes_gpc或者addslashes转义;
这也是必须的,也并非是解决SQL注入的需要。sql中用单引号“'”做为串的边界,所以串中的单引号必须进行转义3 对需要数值运算的变量和其他不能加引号的SQL(如IN语句),预先判断变量类型.
莫明奇妙!向字段赋予正确的值是起码的条件
“不能加引号的SQL(如IN语句)”不知何意?4 关闭php.ini的disply_error.(可选,如不能关闭,需自己手动让SQL语句不能执行报错)
这还差不多
2 所有数值型变量全用intval()转化。
LZ说的“对需要数值运算的变量,预先判断变量类型”是非常有道理的。因为在很多情况下,
SQL文中的值都是从表单过来的,你并不能限制用户输入什么,但是做必要的判断是必须的。
但是,数据库总是你设计的吧, 向里面插入什么类型的值你总是必须要知道的吧?
MySQL已经取消了自动变量类型转换,那么你就在也不能把数值数据朝字符串字段中插入了!
比如我的数值字段 testid=$testid
如果你非要输入'30' 或者 abdf 或者 'sjdf'
那我只能@mysql_query() or die()了, 我还能有什么办法?
不错,LZ说的“对需要数值运算的变量,预先判断变量类型”是非常有道理的。
但是这是对数据库操作的基本要求,而不是什么防止sql注入的手段
LZ说的“对需要数值运算的变量,预先判断变量类型”是对数据库操作的基本要求,但是在某种程度上的确是可以防止sql注入的手段。(现在好像不是在讨论技术,好像在讨论语文了。赫赫)to:PleaseDoTellMeWhy(沉默坚持)
**********************************
比如我的数值字段 testid=$testid
如果你非要输入'30' 或者 abdf 或者 'sjdf'
那我只能@mysql_query() or die()了, 我还能有什么办法?
******************************************************
你要是先判断一下,然后给出一个提示“ID只能输入数字”的错误。是不是比die()更人性化一点呢?
不要离题太远!!!
@extract( alladdslashes($_POST) );
@extract( alladdslashes($_COOKIE) );function alladdslashes($mixvar) {
if ( !get_magic_quotes_gpc() ) {
$mixvar = is_array($mixvar) ? array_map('alladdslashes', $mixvar) : addslashes($mixvar);
}
return $mixvar;
}
我现在也遇到了个问题, 上面的代码向数据库中插入的时候我还没发现啥!
但是从数据库中读出数据显示到<input>表单的文本框中就出现了问题!
比如数据库中有个数据 是'"\
读出来到<input value="'"\"这个问题如何解决,
我目前的解决方法就是
function dealwith($string) {
$string = str_replace( '&', '&', $string );
$string = str_replace( '"', '"', $string );
$string = str_replace( "'", ''', $string );
$string = str_replace( '\\', '\\\\', $string );
return $string;
}
您又什么好的方法吗? 能详细的说说吗? 谢了...
大家都说说........
<?
$value=htmlentities("'\"\\");
?>
<input type="text" value="<?=$value?>">
INSERT 的时候数据库中的值是 '"\
UPDATE 的时候数据库中的值是 '"\\
如果有的值没有 UPDATE 呢, 意思是 UPDATE 之前还要把那些字符实体转过来?
这样子的表单post得到的$_POST["test"]不会是[ '"\ ],而是[ \'\"\\ ](考虑到你的函数@extract( alladdslashes($_POST));所以有转义)
这个设定在哪里? 没找着.
我的mysql5似乎没问题.
我没有深入了解过,但本论坛确实有几个帖子讨论过此事
最近新装mysql5.0.24,确实有此现象关于出入库数据转义的问题:
1、通过判断 magic_quotes_gpc 开关状态来决定外部数据是否要做转义处理是正确的
2、送往输入控件 input、textarea 的内容要用 htmlspecialchars 函数做html编码处理,以防引号不配对和html格式错误关于sql注入的问题:
1、由于php本身的保护,查询指令已不可能被拆分成多句。
2、你只需检查放在过滤条件中的外部数据是否符合要求
原来是我没明白 input textarea 控件中提交时候值的转换问题!
我刚写了个程序测试了,这个问题是弄明白了!
再次感谢大家!
1 所有字符串变量全用单引号关闭边界。
2 所有数值型变量全用intval()转化。
----------------------------------------
第2不同意,小于最大整数的整数是可以用intval(),超过边界的整数或者小数,浮点数要注意这些情况
不过我用的64位机,最大整数到了千亿亿,一般整数都够用了
对于新手来说可能有点用
但addslashes是有漏洞的(google一下就知道了)我现在是先判断是否有magic_quotes_gpc,如果有的话还要把数据还原(stripslashes)在sql查询时用mysql_real_escape_string(),这个函数是根据当前连接字符集来转义的,比addslashes安全其他的就是所有的数据都确定类型