php r n单引,完美起航

本文仅介绍PHP中的一些转义函数的使用。

互联网中一切的输入都不可信,有用户可以自由输入的地方就可能存在着安全漏洞。转义函数的使用就是为了提高系统的安全性,防止潜在的攻击,如SQL注入,XSS攻击等。本文介绍六个函数,分别是:

addcslashes();

addslashes();

mysql_real_escape_string();(mysqli_real_escape_string();)

htmlspecialchars();

htmlentities();

strip_tags();

1.addcslashes()函数及addslashes()函数

addcslashes() 函数返回在指定字符前添加反斜杠的字符串,且addcslashes() 函数对大小写敏感。

需要注意:对以下字符应用 addcslashes() 时请小心:0(NULL), r(回车), n(换行), f 换页)、t(制表符)以及 v(垂直制表符)。在 PHP 中,\0, \r, \n, \t, \f 以及 \v 是预定义的转义序列。 (实验说明,PHP7.4不再处理这些内容)

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。预定义字符是:

单引号(’)双引号(")反斜杠(\)NULL

默认地,PHP 对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。所以您不应对已转义过的字符串使用 addslashes(),因为这样会导致双层转义(就目前实验来看,本人PHP版本为7.4,PHP5.4版本以上已经不会默认对特殊字符转义,特殊字符的处理已经完全交给用户自己处理了)

可实验如下,创建index.php文件:

$str = "He's a young student, and has many interests.";

echo "

".$str."

";

echo "

".addcslashes($str,'a')."

";

echo "

".addcslashes($str,'H')."

";

echo "

".addcslashes($str,' ')."

";

echo "

".addcslashes($str,'\'')."

";

echo "

".addcslashes($str,'a..z')."

";

$s = '"There Are Heroisms All Round Us "\n.

Mr. Hungerton, her father, really was the most tactless person upon earth,—a fluffy, feathery, untidy cockatoo of a man, perfectly good-natured, but absolutely centered upon his own silly self. If anything could have driven me from Gladys, it would have been the thought of such a father-in-law. \t

---Doyle,Arthur Conan. (The Lost World) \r';

echo "

".$s."

";

echo "

".addcslashes($s,'\n')."

";

echo "

".addcslashes($s,'\\n')."

";

echo "

".addcslashes($s,'n')."

";

echo "

".addslashes($s)."

";

?>

开启apache后,浏览器中输入地址:https://127.0.0.1/index.php,首先对$str= "He’s a young student, and has many interests."分析,可获得下列结果:

74f28e256d6fe50aae3d8abe2ce2397b.png

(1)为原输入输出,单引号并没有被转义。经实验,通过GET获得的数据也不会被转义;

(2)对所有a进行转义,变为“\a”;

(3)对H进行转义,区分大小写;

(4)对空格进行转义;

(5)对单引号进行转义,当然该语句也可以写作:

echo "

".addcslashes($str,"'")."

";

(6)对范围内的每个字符均进行转义,a…z表示从a到z的所有字母;

以上的语句均是对一般字符的使用,下面考虑一些特殊字符:

ca24320afbfe30bcb8701062e1c71fc3.png

按顺序分析:

(1)仅打印出原输入,作为对比;

(2)对字符串“\n”进行转义,这里千万不要将其看做c语言中的换行符,它就是单斜杠“\”和字符n,就是对字符串中的单斜杠“\”和字符n分别进行转义;

(3)这里对字符“\n”进行转义,结果和(2)一样。这里重复了一个单斜杠,并不影响结果,仍旧对单斜杠和字母n进行转义;

(4)正常转义,仅对字母n进行转义;

(5)所使用的是addslashes()函数,对预定义符号进行转义;

总的来说,由于SQL注入中一般需要闭合单引号(除了数字型的注入,极少使用),使用addslashes()即可对单引号转义,只能说从一定程度上减小注入的风险,并不能真正避免。对于addcslashes()函数,可以自定义转义哪些字符,使用不当容易出错。对于XSS攻击,可以对""

进行转义,但基本没用,可以通过编码的方式绕过。

2.mysql_real_escape_string()函数(PHP7中已移除,不推荐)

该函数于PHP 4.3.0,引入,在PHP 5.5.0开始废弃,PHP 7.0.0 开始被移除。可以使用MYSQLi函数mysqli_real_escape_string()替换,二者功能上没有区别,但是在参数位置顺序上有所不同。关于mysql与mysqli的区别见参考资料3:mysql与mysqli的区别,请不要使用此函数,PHP7已经不支持此库。

该部分由于已舍弃,这里仅作记录,实际中请使用 mysqli_real_escape_string(),mysqli_real_escape_string()函数参数顺序与此相反!

mysql_real_escape_string () 转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集。它会调用mysql库的函数 mysql_real_escape_string, 在以下字符前添加反斜杠: \x00, \n, \r, , ', " 和 \x1a。为了安全起见,在向MySQL传送查询前,必须调用这个函数(除了少数例外情况)。

格式:

mysql_real_escape_string ( string $unescaped_string [, resource $link_identifier = NULL ] ) : string

参数说明:

$unescaped_string必须存在的参数,规定要转义的字符串。$link_identifier可选的参数,MySQL 连接。如不指定连接标识,则使用由 mysql_connect() 最近打开的连接。如果没有找到该连接,会尝试不带参数调用 mysql_connect() 来创建。如没有找到连接或无法建立连接,则会生成 E_WARNING 级别的错误。

返回值转义后的字符串,或者错误信息。

由于此函数已舍弃,这里给出一个不使用转义函数可能导致注入风险的例子:

在文件夹/var/www/html/下建立文件 SQLIjection.php,内容如下:

$serve = 'localhost:3306';

$user = 'lee';

$psd = '123';

$dbname = 'kali';

$link = mysqli_connect($serve,$user,$psd,$dbname);

// 检测连接

if (!$link) {

die("Connection failed: " . mysqli_connect_error());

}

$query = 'select * from users where id = '.$_GET['id'].' and password = '.$_GET['password'];

//$query = 'select * from users where id = 1';

echo 'THE query is :'. $query;

echo "

";

mysqli_set_charset($link,'UTF-8'); // 设置数据库字符集

$result = mysqli_query($link,$query);

$data = mysqli_fetch_all($result); // 从结果集中获取所有数据

print_r($data);

?>

关于建立PHP与mysql交互过程的具体细节,见另一篇文章:PHP 7.4 与mysql(mariaDB)连接。数据库内容相应的有所变化:

8bb2b3bd6e206ffb3f261a9e93af577c.png

浏览器中输入:http://localhost/SQLInjection.php?id=1&password=1234,有如下结果:

b4f92f3278e038040e2c10f6b14dda38.png

对于数字型的输入,加不加引号都行,http://localhost/SQLInjection.php?id=‘1’&password=‘1234’,也是对的。但是含有字母则必须带引号。由于没有任何的过滤措施,存在注入风险。再次强调,一定要遵循 数据与代码分离原则!,浏览器输入:http://localhost/SQLInjection.phpid=1&password=’ 'or 1

10d470b95c2e3c202591481499035939.png

可以发现,数据库所有内容都被显示出来。

3.mysqli_real_escape_string()函数

mysqli库提供了面向对象和面向过程两种书写方式,根据个人习惯自由选择。所以该函数也可以写作:mysqli::real_escape_string;这里本人采用面向过程的方式。

过程化风格mysqli_real_escape_string ( mysqli $link , string $escapestr ) : string用来对字符串中的特殊字符进行转义, 以使得这个字符串是一个合法的 SQL 语句。 传入的字符串会根据当前连接的字符集进行转义,得到一个编码后的合法的 SQL 语句。

$link仅以过程化样式:由mysqli_connect() 或 mysqli_init() 返回的链接标识。

$escapestr需要进行转义的字符串。会被进行转义的字符包括: NUL (ASCII 0),\n,\r,\,’," 和 Control-Z.

该函数用来转义输入的字符,可以简单验证如下:文件夹下创建mres.php文件,

$serve = 'localhost:3306';

$user = 'lee';

$psd = '123';

$dbname = 'kali';

$link = mysqli_connect($serve,$user,$psd,$dbname);

// 检测连接

if (!$link) {

die("Connection failed: " . mysqli_connect_error());

}

mysqli_query($link, "CREATE TABLE Users LIKE users");

$username = "'lee's";

// 由于未对 $username 进行转义,此次查询会失败

if (!mysqli_query($link, "INSERT into Users (username) VALUES ('$username')")) {

printf("Error: %s\n", mysqli_sqlstate($link));

}

/*

$username = mysqli_real_escape_string($link, $username);

// 对 $username 进行转义之后,查询可以正常执行

if (mysqli_query($link, "INSERT into Users (username) VALUES ('$username')")) {

printf("%d Row inserted.\n", mysqli_affected_rows($link));

}

*/

mysqli_close($link);

?>

由于$username = “'lee’s”;输入为 'lee’s ,单引号的存在会产生语法错误:

2ab8ec9233bd6bf7247e18e6280ffc10.png

使用函数转义可以解决这一问题:

dc9e7d23601dabac8b4b8455d1ae0c32.png

查询数据库可以看到数据已经插入:

fe75a9665d05920a481c257d97af8bd3.png

4.html string函数

除了Mysqli库函数之外,PHP也自带了一些字符串处理函数:htmlspecialchars(); htmlentities(); strip_tags();这些函数主要针对XSS攻击。

htmlspecialchars()函数

htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。

预定义的字符是:

& (和号)成为 &

" (双引号)成为 "

’ (单引号)成为 '

< (小于)成为 <

> (大于)成为 >

语法htmlspecialchars(string,flags,character-set,double_encode)string必需。规定要转换的字符串。

flags可选。规定如何处理引号、无效的编码以及使用哪种文档类型。可用的引号类型:ENT_COMPAT - 默认。仅编码双引号。ENT_QUOTES - 编码双引号和单引号。ENT_NOQUOTES - 不编码任何引号。

character-set可选。一个规定了要使用的字符集的字符串。

double_encode可选。布尔值,规定了是否编码已存在的 HTML 实体。TRUE - 默认。将对每个实体进行转换。FALSE - 不会对已存在的 HTML 实体进行编码。

htmlentities()函数

htmlentities转换所有的html标记,htmlspecialchars只格式化& 、’、"、 这几个特殊符号。

使用htmlentities不指定编码的话遇到中文会乱码(指定htmlentities为UTF-8编码,可以正常转义)。

其参数格式与htmlspecialchars()函数一样。

$str="";

echo htmlentities($str, ENT_QUOTES);

//ENT_COMPAT - 默认。仅编码双引号。

//ENT_QUOTES - 编码双引号和单引号。

//ENT_NOQUOTES - 不编码任何引号。

//输出结果为gt;

//页面展示:

strip_tags()函数

strip_tags() 函数剥去字符串中的 HTML、XML 以及 PHP 的标签。该函数始终会剥离 HTML 注释。这点无法通过 allow 参数改变。该函数是二进制安全的。

语法strip_tags(string,allow)string必需。规定要检查的字符串。

allow可选。规定允许的标签。这些标签不会被删除。

echo strip_tags("Hello world!","");

?>

516540fe2dcba0b7f58495a8c329c17f.png

参考资料:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值