搜索
首页后端开发php教程php安全 - PHP如何安全地使用$_GET

本人新手,在《PHP安全编码》中提到“不要直接使用$_GET”,同时又提到“可以尝试在php.ini中开启magic_quotes_gpc,这样对于所有由用户GET、POST、COOKIE中传入的特殊字符都会转义”,我很纠结,是否开启magic_quotes_gpc就可以直接使用$_GET?

如下面例子中的代码本人感觉很不安全,因为没有做验证,但又不知道如何改进,希望大神能帮忙,谢谢。

<code><?php $name = $_GET["name"];
    $user = $_GET["user"];
    mysql_query("SELECT $name FROM $user");
</code></code>

回复内容:

本人新手,在《PHP安全编码》中提到“不要直接使用$_GET”,同时又提到“可以尝试在php.ini中开启magic_quotes_gpc,这样对于所有由用户GET、POST、COOKIE中传入的特殊字符都会转义”,我很纠结,是否开启magic_quotes_gpc就可以直接使用$_GET?

如下面例子中的代码本人感觉很不安全,因为没有做验证,但又不知道如何改进,希望大神能帮忙,谢谢。

<code><?php $name = $_GET["name"];
    $user = $_GET["user"];
    mysql_query("SELECT $name FROM $user");
</code></code>

你是想要filter_input函数,多看手册:

http://www.w3school.com.cn/php/func_filter_input.asp

<code>纯数字的参数intval强制取整
其他参数值进行过滤或者转义

    protected function zaddslashes($string, $force = 0, $strip = FALSE)
    {   
        if (!defined('MAGIC_QUOTES_GPC'))
        {   
         define('MAGIC_QUOTES_GPC', '');
        }   
        if (!MAGIC_QUOTES_GPC || $force)
        {   
         if (is_array($string)) {
             foreach ($string as $key => $val)
             {   
                 $string[$key] = $this->zaddslashes($val, $force, $strip);
             }   
         }   
         else
         {   
             $string = ($strip ? stripslashes($string) : $string);
             $string = htmlspecialchars($string);
         }   
        }   
        return $string;
     }

</code>

我一般都对$_POST $_GET都使用zaddslashes,然后整数的参数值进行取整,防止XSS和SQL注入

HTTP头信息:IP、浏览器信息、等也进行转义过滤防止HTTP头注入

magic_quotes_gpc开启后会影响图片上传等,自动将内容引号转义

注意PHP5.5包括之后已经将magic_quotes_gpc配置废弃

除此之外,最好在服务器方面也做关键词过滤,Mysql为业务使用到的库创建用户和赋权

可以把自己应用放服务器上,装个sqlmap注入下自己试试,以上几点做到一般情况下不会被搞,至少不会被getshell

乌云白帽子路过...

1. 像用户名这种有格式的东西,应该取到之后马上用正则表达式验证,比如preg_match('/\A\w{6,14}\z/', $user)就验证了它是不是6~14位的数字字母下划线。不要使用系统自带的filter,那个管不了什么用。

2. 不要使用mysql开头的函数,要使用mysqli,而且最好进行参数化查询而不是addslashes,后者会有编码问题。

3. 输出html的时候,默认使用htmlspecialchars,这个函数可以指定编码。或者你可以用现成的模板引擎。

4. 比较字符串的时候,强制使用strcmp,不要使用双等号。

5. 不要使用$_REQUEST

这样可以防掉95%。至于magic_quotes_gpc,应该早就废了吧。

现在市面上这些书真的害人不浅,随便下结论或者是楼主没有仔细读。为什么直接使用 $_GET $_POST 不安全?

看了楼主的例子,应该是直接将$_GET 用在拼接SQL上,这样肯定是不安全的,所以核心信息应该是:直接将 $_GET/$_POST等用户输入的内容用于SQL拼接是不安全的,如何避免?

例如:

<code>sql</code><code>select * from user where username= "$_GET['username']"
</code>

如果用户提交的username 为

<code>sql</code><code>" 0 or true or username ="
</code>

那么就会变成这样:

<code>sql</code><code>select * from user where username = "0" or true  or username=""
</code>

那么会返回所有的用户记录。当然这里只是粗暴的举了一个例子。实际上要做XSS要熟知代码或者猜测到运行的逻辑等了解很多东西。

最简单的过滤方法是使用 mysql_real_escape_string 函数

至于 magic_quotes,是php最失败的一个改进,现已废弃,就算是低版本的PHP也一定要关闭它。

如果 $_GET
首先判断是否为空
然后对值进行判断
举个例子:
只接受数字 那就使用 php自带函数 is_numeric

一般 GET 也只是传递某个标识
总之在数据库或其他操作之前 先验证 传过来的变量 是否为自己预期的值

可以先对post或者get请求过滤,php有内置函数进行过滤,然后在使用

同意二楼的要有一个过滤,不过只是系统自带的肯定不行,最好自己再根据情况做一个过滤等之类的处理。

防止XSS攻击,最简单粗暴的做法就是用htmlspecialchars把特殊字符(&,",',)转换为HTML实体(&"'<>)后输出.

<code><?php echo htmlspecialchars($html, ENT_QUOTES, 'UTF-8');
</code></code>

防止XSS攻击,最复杂的就是自己写正则过滤,不过还好有HTMLPurifier库,除了能过滤XSS代码,还能把不完整的标签补全或者去掉.Yii框架也用到了这个XSS过滤库.
http://htmlpurifier.org/download

<code><?php require dirname(__FILE__).'/htmlpurifier/library/HTMLPurifier.auto.php';
$purifier = new HTMLPurifier();
echo $purifier->purify($html);
</code>

上面说的是防御XSS,下面说防御SQL注入:
PDO和MySQLi等都提供有绑定参数查询的功能,而绑定参数的目的就是防止SQL注入.
http://php.net/manual/zh/pdo.prepared-statements.php

很多更成熟的数据库都支持预处理语句的概念.
什么是预处理语句?可以把它看作是想要运行的SQL的一种编译过的模板,它可以使用变量参数进行定制.
预处理语句可以带来两大好处:
1.查询仅需解析(或预处理)一次,但可以用相同或不同的参数执行多次.
当查询准备好后,数据库将分析/编译/优化执行该查询的计划.
对于复杂的查询,此过程要花费较长的时间,如果需要以不同参数多次重复相同的查询,那么该过程将大大降低应用程序的速度.
通过使用预处理语句,可以避免重复分析/编译/优化周期.
简言之,预处理语句占用更少的资源,因而运行得更快.
2.提供给预处理语句的参数不需要用引号括起来,驱动程序会自动处理.
如果应用程序只使用预处理语句,可以确保不会发生SQL注入.
然而,如果查询的其他部分是由未转义的输入来构建的,则仍存在SQL注入的风险.

预处理语句如此有用,以至于它们唯一的特性是在驱动程序不支持的时候,PDO将模拟处理.
这样可以确保不管数据库是否具有这样的功能,都可以确保应用程序可以用相同的数据访问模式.

<code><?php $sth = $dbh->prepare('SELECT name, colour, calories FROM fruit WHERE calories bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
</code>

上面参与查询的变量$calories被绑定为整型,$colour被绑定为长度为12个字符的字符串型.
MySQLi里同样提供有像PDO bindParam一样的bind_param,这时就不需要用addslashes,mysqli_real_escape_string之类的函数了,也不需要依赖magic_quotes_gpc配置了(该配置从PHP5.4开始已经被移除).
用PDO操作MySQL时注意禁用模拟预处理,这样才会使用真正的预处理,这样才能确保程序先发送SQL模板给MySQL编译,然后再传参数过去执行,这样可以确保这些参数不被SQL注入.MySQLi扩展的预处理默认就是真正的预处理.

<code>$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
</code>

这些都可以通过MySQL的general_log日志或者WireShark观察到.
php安全 - PHP如何安全地使用$_GET

<code><?php $stmt = $mysqli->prepare('SELECT * FROM users WHERE username = ?');
$stmt->bind_param('s', $_GET['username']); //s表示用户名被绑定为字符串型,整型用i.
$stmt->execute();
</code>

对于一些要求是整型的参数,其实还可以直接用intval($calories)拿到整型值.

如果你要验证和过滤一些用户输入的数据,又不想自己写正则表达式,那就可以用filter_input/filter_var函数,比如验证邮箱,IP等:
http://php.net/manual/zh/filter.filters.php

我来回答个无关的:
Are PDO prepared statements sufficient to prevent SQL injection?

PDO是否可以防住SQL注入。

建议你先看看
joomla-framework的input类库,地址在这里
或者先把joomla-framework的input类库在你的代码中使用(前期就不要考虑性能之类的问题),先搞明白对于$_GET(包括$_POST、$_FILES、$_COOKIE等)要进行怎样的处理,然后在以后的使用过程中自己选择是否实现简单版本。

为什么这么普遍的问题,php不能做一个统一的控制呢 :(

为什么不用PDO?

防止注入的话PDO就可以了,防止XSS的话建议使用安全厂商提供的一些XSS过滤脚本在输出时过滤.

我觉得数据类型要控制好,另外就是防止SQL注入攻击了。
还有就是最好用Session保存,别一样的内容总提交做SQL。

什么是$_GET? $_GET是一类通过 URL 参数传递给当前脚本的变量的数组。而$HTTP_GET_VARS 包含相同的信息, 但它不是一个超全局变量。 (注意 $HTTP_GET_VARS 和 $_GET 是不同的变量,PHP 处理它们的方式不同).

那么$_GET()的安全考虑主要是在获取值的时候进行的安全考虑的,在进行数据的过滤时防止XSS攻击,PDO攻击中的SQL注入等安全问题,这些都是通过$_GET()传递值来威胁到系统安全的,还有敏感数据最好进行加密处理,不要太过于明显的暴露,以防被劫持利用等危险。

那么一些简单的数据过滤的方式有:

对于XXS攻击(跨站脚本攻击)都是由于对用户的输入没有进行严格的过滤造成的,所以我们必须在所有数据进入我们的网站和数据库之前把可能的危险拦截。针对非法的HTML代码包括单双引号等,可以使用htmlentities()来进行数据过滤。 但是要注意一点,htmlentities()默认编码为 ISO-8859-1,如果你的非法脚本编码为其它,那么可能无法过滤掉,同时浏览器却可以识别和执行。

对于PDO攻击中的SQL注入,在php编写程序中,我们可以使用类似如下的PDO预处理绑定语句来有效的防止sql注入问题:

<code>$stmt  =  $dbh -> prepare ( "INSERT INTO REGISTRY (name, value) VALUES (:name, :value)" );
$stmt -> bindParam ( ':name' ,  $name );
$stmt -> bindParam ( ':value' ,  $value );
$name  =  'one' ;
$value  =  1 ;
$stmt -> execute ();
</code>

或者使用?号占位符来达到相同的效果:

<code>$stmt  =  $dbh -> prepare ( "INSERT INTO REGISTRY (name, value) VALUES (?, ?)" );
</code>

防不住xss。这个说的是$_GET这个方法,你要是封装好了了那还说这个干嘛?

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
1 个月前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具