PHP获取IP地址的方法,防止伪造IP地址注入攻击
PHP获取IP地址的方法
/** * 获取客户端IP地址 * <br />来源:ThinkPHP * <br />"X-FORWARDED-FOR" 是代理服务器通过 HTTP Headers 提供的客户端IP。代理服务器可以伪造任何IP。 * <br />要防止伪造,不要读这个IP即可(同时告诉用户不要用HTTP 代理)。 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字 * @param boolean $adv 是否进行高级模式获取(有可能被伪装) * @return mixed */ function get_client_ip($type = 0, $adv = false) { $type = $type ? 1 : 0; static $ip = NULL; if ($ip !== NULL) return $ip[$type]; if ($adv) { if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); $pos = array_search('unknown', $arr); if (false !== $pos) unset($arr[$pos]); $ip = trim($arr[0]); }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } } elseif (isset($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } // IP地址合法验证, 防止通过IP注入攻击 $long = sprintf("%u", ip2long($ip)); $ip = $long ? array($ip, $long) : array('0.0.0.0', 0); return $ip[$type]; } /** * 获得用户的真实IP地址 * <br />来源:ecshop * <br />$_SERVER和getenv的区别,getenv不支持IIS的isapi方式运行的php * @access public * @return string */ function real_ip() { static $realip = NULL; if ($realip !== NULL) { return $realip; } if (isset($_SERVER)) { if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']); /* 取X-Forwarded-For中第一个非unknown的有效IP字符串 */ foreach ($arr AS $ip) { $ip = trim($ip); if ($ip != 'unknown') { $realip = $ip; break; } } } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) { $realip = $_SERVER['HTTP_CLIENT_IP']; } else { if (isset($_SERVER['REMOTE_ADDR'])) { $realip = $_SERVER['REMOTE_ADDR']; } else { $realip = '0.0.0.0'; } } } else { if (getenv('HTTP_X_FORWARDED_FOR')) { $realip = getenv('HTTP_X_FORWARDED_FOR'); } elseif (getenv('HTTP_CLIENT_IP')) { $realip = getenv('HTTP_CLIENT_IP'); } else { $realip = getenv('REMOTE_ADDR'); } } // 使用正则验证IP地址的有效性,防止伪造IP地址进行SQL注入攻击 preg_match("/[\d\.]{7,15}/", $realip, $onlineip); $realip = !empty($onlineip[0]) ? $onlineip[0] : '0.0.0.0'; return $realip; }
X-Forwarded-For地址形式列举:
unkonwn, unknown, 211.100.22.30
172.16.20.110, 202.116.64.196, 203.81.21.61
10.194.75.83, 10.194.73.11, 10.194.71.11, unknown
192.168.120.57, unknown, unknown, 211.10.10.195
unknown, 210.75.1.181
155.161.59.47, unknown
伪造IP地址进行注入攻击:
IP伪造有几种途径,一种是通过是修改IP数据包,有兴趣的可以去看看IP数据包的结构,还有一种就是利用修改http头信息来实现IP伪造。涉及到“客户端”IP的通常使用3个环境变量:$_SERVER['HTTP_CLIENT_IP']和$_SERVER['X_FORWARDED_FOR']还有$_SERVER['REMOTE_ADDR']实际上,这3个环境变量都有局限性。前两个是可以随意伪造。只要在发送的http头里设置相应值就可以,任意字符都可以,而第3个环境变量,如果用户使用了匿名代理,那这个变量显示的就是代理IP。
一般获取IP后更新到数据库代码如:$sql="update t_users set login_ip='".get_client_ip()."' where ...",而如果接收到的ip地址是:xxx.xxx.xxx.xxx';delete from t_users;-- ,代入参数SQL语句就变成了:"update t_users set login_ip='xxx.xxx.xxx.xxx';delete from t_users;-- where ...
所以获取IP地址后,务必使用正则等对IP地址的有效性进行验证,另外一定要使用参数化SQL命令!
总结:
"X-FORWARDED-FOR" 是代理服务器通过 HTTP Headers 提供的客户端IP。代理服务器可以伪造任何IP。
要防止伪造,不要读这个IP即可(同时告诉用户不要用HTTP 代理)。
如果是PHP,$_SERVER['REMOTE_ADDR'] 就是跟你服务器直接连接的IP,用这个就可以了。
获取服务器IP地址:
/** * 获取服务端IP地址 * @return string * @since 1.0 2016-7-1 SoChishun Added. */ function get_host_ip() { return isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''); }
参考文章:
http://www.cnblogs.com/skiplow/archive/2011/07/20/2111751.html (伪造IP地址进行SYN洪水攻击)
http://www.feifeiboke.com/pcjishu/3391.html (你所不懂的火狐浏览器妙用之伪造IP地址)
https://segmentfault.com/q/1010000000095850#a-1020000000098537 (如何避免用户访问请求伪造ip)
http://blog.csdn.net/clh604/article/details/9234473 (PHP使用curl伪造IP地址和header信息)
http://www.cnblogs.com/lmule/archive/2010/10/15/1852020.html (REMOTE_ADDR,HTTP_CLIENT_IP,HTTP_X_FORWARDED_FOR)
版权声明:本文采用署名-非商业性使用-相同方式共享(CC BY-NC-SA 3.0 CN)国际许可协议进行许可,转载请注明作者及出处。 |
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
解析Java代码,自动生成文档工具使用说明
页面布局 左侧为菜单,菜单分为两级,一级表示模块,二级表示接口信息 右侧为接口详细信息,主要包括:模拟测试功能,接口详细信息说明,请求参数说明,响应参数说明,自动一个演示的例子表明接口的使用方式 如下图(图片拼接左侧菜单可能模糊或重影,凑合看): 演示页面布局 页面操作 左侧二级菜单可以双击修改,失去焦点时自动保存 image.png 左侧一级,二级菜单可以拖拽排序 所有带 “编辑”按钮的地方都可以编辑保存,textarea编辑时可以带回车换行,自动记录你的文本格式 请求参数和响应参数,本身是一个树结构,所有编辑的时候跟普通的编辑树一样操做,包括添加一级数据,添加子数据,修改,删除,保存等等,鼠标移入会有提示,如下图 5.如果需要给接口提供默认值,修改参数的默认值后,会自动重构json参数,方便测试 代码使用 在你的controller类上增加注解@Api("这里写模块名称"),这里一个@Api对应页面的一个一级菜单,即模块,模块可以由多个类组成,只需设置每个类的模块名称一样,程序会自动把模块名称一样的class组装成同一模块。
- 下一篇
年薪30w+的软件开发工程师需要掌握的技能
现在,有这样一种主流观念,压垮了很多新手软件开发者,那就是你需要学习很多东西才能成为软件开发人员,并且很多人不知道从哪里开始起步。如今新手进入软件开发的程序员月薪大约是1w左右,新手在成长为成熟的开发工程师的路上,要学习和提升的技能是非常之多。工作经验或许能成为你拿高薪的一个指标,但是,技能才是最终的标准。 这里我会尝试着具体说明那些在你追求成为软件开发人员的路上将让你受益的必要技术技能,年薪30w+的程序员需要掌握哪些技能。 一篇文章当然不能详尽说明作为软件开发者,你可能需要掌握的所有技术技能,但是我会列出最关键的一些技术技能。 编程语言 我认为从这一条开始说起是最合适的。 不懂编程语言,怎么能成为一个真正的程序员? 不过,关于选择哪种编程语言去学习可能并没有我们想得那么重要这一点,请允许我一笔带过。 相反,让我们谈一谈为什么我们要从一种编程语言开始,而不是试图去学习所有的东西。 许多新手程序员会试图一次性或在第一份工作之前学习几种编程语言,以便于有备无患。 虽然我认为你最终应该学会一种以上编程语言,但我不建议提前这样做,因为这只会导致混乱,并且会分散你需要学习的其他技能的精力。 相...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS关闭SELinux安全模块
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Hadoop3单机部署,实现最简伪集群
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7安装Docker,走上虚拟化容器引擎之路