mysql mysql_set_charset_SQL注入攻击之 mysql_set_charset [转]

本文转载地址:http://hi.baidu.com/cuttinger/blog/item/e9a93901934755147bec2cb0.html

1。老话题,mysql_real_escape_string+单引号,大多数情况下,防止sql注入攻击足够了。

$mysql = mysql_connect("host","user","passwort");

$value = mysql_real_escape_string($value,$mysql);

$sql = "select * from table where col = '$value' ";

mysql_query($sql,$mysql);

2。但是我的数据库是gbk的,我需要使用gbk去连接数据库,我使用set names gbk来告诉服务器我要如何使用编码。

$mysql = mysql_connect("host","user","passwort");

$sql = "set names gbk";

mysql_query($sql,$mysql);

$value = mysql_real_escape_string($value,$mysql);

$sql = "select * from table where col = '$value' ";

mysql_query($sql,$mysql);

3。但是中途使用"set names gbk" 修改了字符集,mysql_real_escape_string函数不会相应的更新字符集。因为set names gbk只是告诉了服务器我要做什么,php的mysql客户端不知道发生了什么,所以mysql_connection认为自己的字符集没有发生变化,这时候使用mysql_client_encoding获取的还是之前的编码。

$mysql = mysql_connect("host","user","passwort");

$encoding = mysql_client_encoding($mysql) ; // => latin1

$sql = "set names gbk";

mysql_query($sql,$mysql);

$encoding = mysql_client_encoding($mysql) ; // => latin1

$value = mysql_real_escape_string($value,$mysql);

$sql = "select * from table where col = '$value' ";

mysql_query($sql,$mysql);

4。在这种情况下,mysql_real_escape_string使用latin1来转义输入参数,但是使用gbk来查询,就存在被SQL注入攻击的风险。

$value = chr(0xbf).chr(0x27)." or col is not null -- ";

$value = mysql_real_escape_string($value,$mysql);

=> $value = chr(0xbf).chr(0x5c).chr(0x27)." or col is not null -- ";

其中,chr(0xbf).chr(0x5f)组成汉字“縗”,0x27就是单引号,被成功注入。

5。因此,需要告诉php,我修改字符集编码了。mysql_set_charset就做到了这一点。它其实更强大,把set names gbk这事一并作了。

mysql_set_charset("gbk",$mysql);

$value = chr(0xbf).chr(0x27)." or col is not null -- ";

$value = mysql_real_escape_string($value,$mysql);

=> $value =chr(0x5c).chr(0xbf).chr(0x5c).chr(0x27)." or col is not null -- ";

注意加粗的地方,也就是第一个chr(0x5c),因为0xbf不是合法的gbk字符,所以前面加了一个反斜杆将其转义。这样,0xbf就不能和0x5c组成汉字了,而是 (0x5c0xbf) (0x5c0x27), SQL注入失败!!

6。很可惜,mysql_set_charset在php5.2.3之后才出现,你必须升级你的php版本了。

同时,也需要mysql的版本在5.0.7或之上,所以也要注意。

wget && tar -xzvf && configure && make && make install

7。有时候,mysql_set_charset("gbk")失败了,返回结果为

$ret = mysql_set_charset("gbk",$mysql);

if($ret == false){

echo mysql_error();

}

=> Can't initialize character set GBK (path: /usr/local/share/mysql/charsets/)

8。悲剧阿!想办法吧。重新编译mysql,把gbk编译进去就行了

./configure --with-extra-charsets=gbk && make clean && make && make install

9。请记住,抛弃set names gbk吧,咱们用mysql_set_charset,安全,很重要。

PHP的手册上也这么讲,所以你还是别坚持了

This is the preferred way to change the charset. Using mysql_query() to execute SET NAMES .. is not recommended.

10。那么,为什么我一开始获得的client_charset是latin1而不是gbk呢?

$encoding = mysql_client_encoding($mysql) ; // => latin1

登陆数据库,察看编码

mysql> show variables like '%set%';

| character_set_client | latin1 |

| character_set_connection | latin1 |

| character_set_database | latin1 |

| character_set_filesystem | binary |

| character_set_results | latin1 |

| character_set_server | latin1 |

| character_set_system | utf8 |

可以看到,character_set_client为latin1,就是它,直接决定了mysql_client_encoding的返回结果。

set names gbk的结果,是同时对该连接修改上面的character_set_client、character_set_connectio、character_set_results

mysql> set names gbk;

Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%set%';

+--------------------------+----------------------------+

| Variable_name | Value |

+--------------------------+----------------------------+

| auto_increment_offset | 1 |

| character_set_client | gbk |

| character_set_connection | gbk |

| character_set_database | latin1 |

| character_set_filesystem | binary |

| character_set_results | gbk |

| character_set_server | latin1 |

| character_set_system | utf8 |

| character_sets_dir | /usr/share/mysql/charsets/ |

+--------------------------+----------------------------+

9 rows in set (0.00 sec)

所以,我们很容易得出这个结论,只要中途没有使用set names gbk将原本非gbk的连接改成gbk的连接,mysql_real_escape_string就是安全的。如果原来也是gbk的,set names gbk没有任何效果,也不会对mysql_real_escape_string的安全造成威胁。

11。分析一下,导致mysql_real_escape_string存在风险的根源是什么呢?

产生风险的根源是单引号被注入;单引号被注入的根源是gbk中,0x27在身为单引号的同时,又是其它有效多字节文字的组成部分;而utf8 中,0x00-0x7F都不是任何其它字符的组成部分,所以不存在被注入单引号的风险;所以,将一个其它字符集的MYSQL连接 SET NAME utf8,并不会带来额外的风险。

12。结论:要避开mysql_real_escape_string可能的风险,有以下策略

1)数据库表使用的编码与数据库变量character_set_client指定的编码相同,这样不需要set names xxx来改变编码。

2)数据库表使用latin1或utf8等字符集,这样set names xxx也不会带来额外的风险。

3)当需要set names gbk时,使用mysql_set_charset来替代。

参考资料:

深入理解SET NAMES和mysql(i)_set_charset的区别

相关资料:

讲讲Mysql 中文乱码是怎么产生的以及该如何处理

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2011-10-13 09:41

浏览 638

评论

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/573757.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

idea导入maven项目依赖报错_解决Maven依赖冲突的好帮手,这款IDEA插件了解一下?

1、何为依赖冲突Maven是个很好用的依赖管理工具,但是再好的东西也不是完美的。Maven的依赖机制会导致Jar包的冲突。举个例子,现在你的项目中,使用了两个Jar包,分别是A和B。现在A需要依赖另一个Jar包C,B也需要依赖C。但…

Xilinx实习一年总结

从去年7月4号来到上海xilinx。转眼间已经一年。这一年学了非常多知识,也长了非常多见识。 去年七月一到公司,马上投入到摄像头-DDR-HDMI图像通路的研发中。就是在ZEDboard板卡上。通过外置摄像头採集图像,在PL部分将採集的像素数据进行拼接&a…

java线程创建方式_Java创建线程安全的方法

原文链接 译者:秦建平 校对:方腾飞首先来看一个问题:下面这个方法是线程安全的吗?如何才能让这个方法变成线程安全的?public class MyCount {private static int counter 0;public static int getCount(){return coun…

win7 能下node什么版本_微软从未公开的win10版本,3GB+极度精简,老爷机有救了

在windows家族中,最好用的就是win7和XP系统。堪称经典,而且还是发展最成功的系统版本。前几天韩博士也发布一篇关于XP系统的文章,评论区引发极大争论。大家众说纷纭,觉得XP系统是顺畅,但是很多软件硬件都不支持&#x…

【Swift学习】Swift编程之旅(一)

学习一门新语言最经典的例子就是输出“Hello World!” print("Hello World!")  swift就是这样来输出的。 如果你使用过其他语言,那么看上去是非常的熟悉吧。但比一些c要简单的多吧 1、不需要导入一些单独的库,比如输入/输出或字符…

孔夫子二手书采集

文章目录 项目演示软件采集单本数据网页搜索数据对比 使用场景概述部分核心逻辑Vb工程图数据导入与读取下拉框选择参数设置线程 使用方法下载软件授权导入文件预览处理后的数据 项目结构附件说明 项目演示 操作视频详见演示视频,以下为图文演示 软件采集单本数据 …

java总结体会_Java课程总结心得体会

不知不觉中以学习Java将近4个月了,在这几个月的学习中我从一开始的迷茫懵逼,到现在的懵逼迷茫中,写下了这篇这个学期课程的Java学习心得体会。首先,我认为作为一个该开始学习Java的小白,在开始学习之前无论你有多大的热…

为什么用redis做缓存而不是mybatis自带的缓存_如何用Java设计一个本地缓存,涨姿势了...

最近在看Mybatis的源码,刚好看到缓存这一块,Mybatis提供了一级缓存和二级缓存;一级缓存相对来说比较简单,功能比较齐全的是二级缓存,基本上满足了一个缓存该有的功能。当然如果拿来和专门的缓存框架如ehcache来对比可能…

process 类 java_编写可执行jar——java的Process类的使用(二)

你知道怎么在控制台使用ping吗?那你知道怎么在java中使用ping吗?1.批处理文件批处理文件大家一定不陌生。接触最多的应该就是tomcat中的start.bat或者start.sh了。bat是在windows环境下运行的批处理文件,sh则是linux的shell脚本。2.adb指令安…

python从爬虫到数据分析项目_零基础学习Python web开发、Python爬虫、Python数据分析,从基础到项目实战!...

随着大数据和人工智能的发展,目前Python语言的上升趋势比较明显,而且由于Python语言简单易学,所以不少初学者往往也会选择Python作为入门语言。Python语言目前是IT行业内应用最为广泛的编程语言之一,尤其是近几年来随着大数据和人…

java filedialog 打开文件_java 用文件对话框打开文件

//文件的打开import java.awt.FileDialog;import java.awt.event.*;import java.io.*;import java.io.File;import java.io.FileReader;public class FileOpen {private FileDialog filedialog_open;private String fileopen null, filename null;// 用于存放打开文件地址 和…

2782: [HNOI2006]最短母串

2782: [HNOI2006]最短母串 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 3 Solved: 2[Submit][Status][Web Board]Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2,„,…

c java 内部类_java程序中能否在内部类当中再定义一个内部类?

展开全部我被你的想62616964757a686964616fe78988e69d8331333363386664法震撼了,哈哈.亏你想的出来...这么弄代码不好理解,Java看起来醒目,也是Java中的一个规范!可以吗?必须可以..看代码演示...声明下,我也第一次,多次嵌套,看你想法后去试验下是可行的我用的两种办法!不多说看…

pythongui做计算器_python 实现简单的计算器(gui界面)

运行效果:完整代码from tkinter import *def click(num):global opopopstr(num)iptext.set(op)def evaluate():global opoutputstr(eval(op))iptext.set(output)def clearDisplay():global opop""iptext.set(op)calcTk()calc.title("TechVidvan Calc…

ios学习笔记——RunTime

Objective—C是面向运行时的语言,就是说它会尽可能的把编译和链接时要执行的逻辑延迟到运行时。这就给你很大的灵活性,你可以按需要把消息重定向给合适的对象,你甚至可以交换方法的实现。最重要的还是消息机制。 C语言使用“静态绑定”&#…

exhaustion java_Java Player.setExhaustion方法代碼示例

import org.bukkit.entity.Player; //導入方法依賴的package包/類/*** Set SamaGamesAPI*/Overridepublic void startGame(){this.getInGamePlayers().forEach(((uuid1, survivalPlayer) -> survivalPlayer.getPlayerIfOnline().closeInventory()));super.startGame();Objec…

python内存池机制_python的内存管理机制

一、python是一个什么样类型的语言1、python是一种动态解释性强类型定义的高级、通用性编程语言。解释型:执行的时候,才一条一条的解释成机器语言给计算机来执行。如:python、js、ruby、PHP等编译型:把源程序的每一条语句都编译成…

MATLAB GUI不同控件函数间变量传递方法

在GUI中一个控件函数结束后,会将在这个函数中使用的变量全部删除,如果想在另一个控件中使用,则必须想办法将这个变量保存传递,方法有以下几种:1、使用globe定义全局变量,这种方法不是很好,一方面…

java变量数据类型_java变量与数据类型

第二章 变量与数据类型变量变量的概述变量是指内存中的一个存储区域,该区域要有自己的名称(变量名)、类型(数据类型),该区域的数据可以在同一数据类型的范围内不断变化值。每个变量都有自己的作用范围,叫作用域变量的注意事项1.Java中的变量必…

python实现推荐系统代码_推荐系统之矩阵分解及其Python代码实现

有如下R(5,4)的打分矩阵:(“-”表示用户没有打分)其中打分矩阵R(n,m)是n行和m列,n表示user个数,m行表示item个数那么,如何根据目前的矩阵R(5,4)如何对未打分的商品进行评分的预测(如何得到分值为0的用户的打分值)?——…