当前位置: 首页 > news >正文

php参数特殊字符,PHP中URL中特殊字符引起的问题(+,=) 分析及解决方法

前言,在做一个登录的过程中,发现个别账号验证通不过,仔细排查后发现是接收的参数进行了urldecode处理,使得某些特殊字符如加号’+‘变成了空格,以至于影响到了后面的数据。下面来看看代码。

get 方法代码

function get($key = null, $default = null) {

if (is_null($key)) {

foreach ($_GET as $key => $val) {

$_GET[$key] = trim(urldecode($val));

}

return $_GET;

} else {

$_GET[$key] = (isset($_GET[$key]) && $_GET[$key] != '') ? $_GET[$key] : $default;

return trim(urldecode($_GET[$key]));

}

}

登录验证代码

$input = \Util::get('data');

$data = json_decode(base64_decode($input), TRUE);

if ($this->do_verify($data) != 1){

$output['msg'] = "登陆验证失败!";

return (json_encode($output));

}

上述代码\Util::get(‘data’)接收到的 data 数据:

eyJ1aWQiOiIxMTc5NTIwNDA1MDAwNDI1IiwidWluIjoiQe 8h 8hyDkuIDliIDYgiIsInRva2VuIjoiQDE3MUA5MUAxNjNAODJAMTExQDg4QDExMEAxMDNAMTA1QDE1NkAxMDRAMTEwQDEwNkAxMDhAMTUyQDE0OUA4NkA5NkA4N0AxNzJAMTU5QDE0OUA5MEAxMTRAODNAMTAyQDEwM0AxMDhAMTExQDEwNEAxMDVAMTAzQDEwMEAxMDVAMTAxQDk2QDEwMUAxMDJAMTA3QDEwNEAxMDJAODlAOTdAOTFAMTY5QDE1NkAxNjFAMTUyQDg2QDExMEAxMDRAMTAzQDEwM0A5M0A5MEAxNTVAODNAMTExQDg4QDEwM0AxMDZAODVAMTgwIn0=

可以看到有两处分别有一个空格和两个空格,通过base64_decode和json_decode后,值成了 NULL,因此通不过后面的验证。

要怎么办呢,$data 这里肯定是不能改的,不然会影响绝大部分的登录,通不过验证的毕竟只是小部分,最好的方法就是在 if 里将获取的数据进一步处理,将特殊字符解析出来,既然接收的时候用了urldecode,那就将它用urlencode转回来吧

$input = urlencode($input);

urlencode转换后的数据:

eyJ1aWQiOiIxMTc5NTIwNDA1MDAwNDI1IiwidWluIjoiQe+8h++8hyDkuIDliIDYgiIsInRva2VuIjoiQDE3MUA5MUAxNjNAODJAMTExQDg4QDExMEAxMDNAMTA1QDE1NkAxMDRAMTEwQDEwNkAxMDhAMTUyQDE0OUA4NkA5NkA4N0AxNzJAMTU5QDE0OUA5MEAxMTRAODNAMTAyQDEwM0AxMDhAMTExQDEwNEAxMDVAMTAzQDEwMEAxMDVAMTAxQDk2QDEwMUAxMDJAMTA3QDEwNEAxMDJAODlAOTdAOTFAMTY5QDE1NkAxNjFAMTUyQDg2QDExMEAxMDRAMTAzQDEwM0A5M0A5MEAxNTVAODNAMTExQDg4QDEwM0AxMDZAODVAMTgwIn0%3D

仔细看,加号’+‘出来了

再用json_decode(base64_decode($input)), TRUE)处理$input 后发现还是 NULL,为什么呢,一步步分析,先查看base64_decode($input)是什么

{"uid":"1179520405000425","uin":"A'' 一刀؂","token":"@171@91@163@82@111@88@110@103@105@156@104@110@106@108@152@149@86@96@87@172@159@149@90@114@83@102@103@108@111@104@105@103@100@105@101@96@101@102@107@104@102@89@97@91@169@156@161@152@86@110@104@103@103@93@90@155@83@111@88@103@106@85@180"}7

这个 json 数据后面怎么会单独有个数字呀,一看就不对,怪不得 json_decode 后数据是 NULL,那这个 7 是如何来的呢,数据先是urlencode后再base64_decode,这里可以发现,urlencode后,使得原数据’=‘号变成了’%3D‘,进而造成base64_decode解析错误,所以使用urlencode还是不太正确的,那么究竟用什么来解决这一问题。

这就要讲到rawurldecode了,先来看下它的含义,

(PHP 4, PHP 5, PHP 7)

rawurldecode — 对已编码的 URL 字符串进行解码

说明

rawurldecode ( string $str ) : string

返回字符串,此字符串中百分号(%)后跟两位十六进制数的序列都将被替换成原义字符。

那么就来用下 rawurldecode 吧

$input = rawurldecode(urlencode($input));

再次查看$input 的值:

eyJ1aWQiOiIxMTc5NTIwNDA1MDAwNDI1IiwidWluIjoiQe+8h++8hyDkuIDliIDYgiIsInRva2VuIjoiQDE3MUA5MUAxNjNAODJAMTExQDg4QDExMEAxMDNAMTA1QDE1NkAxMDRAMTEwQDEwNkAxMDhAMTUyQDE0OUA4NkA5NkA4N0AxNzJAMTU5QDE0OUA5MEAxMTRAODNAMTAyQDEwM0AxMDhAMTExQDEwNEAxMDVAMTAzQDEwMEAxMDVAMTAxQDk2QDEwMUAxMDJAMTA3QDEwNEAxMDJAODlAOTdAOTFAMTY5QDE1NkAxNjFAMTUyQDg2QDExMEAxMDRAMTAzQDEwM0A5M0A5MEAxNTVAODNAMTExQDg4QDEwM0AxMDZAODVAMTgwIn0=

真相呼之欲出了,这里已经得到了正确的原数据,那么只要进一步优化验证逻辑,含有特殊字符的登录就走得通了,代码如下

$input = \Util::get('data');

$data = json_decode(base64_decode($input), TRUE);

if ($this->do_verify($data) != 1){

//得到正确的登录数据

$input = rawurldecode(urlencode(urldecode($input)));

//将正确的登录数据再进行一次验证

$data = json_decode(base64_decode($input),TRUE);

if ($this->do_verify($data) != 1) {

$output = "登陆验证失败!";

return (json_encode($output));

}

}

至此,特殊字符造成的解析问题解决完毕。

【声明】:本博客仅为分享信息,不参与任何交易,也非中介,所有内容仅代表个人观点,均不作直接、间接、法定、约定的保证,读者购买风险自担。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。

【关于安全】:任何 IDC 都有倒闭和跑路的可能,备份永远是最佳选择,服务器也是机器,不勤备份是对自己极不负责的表现,请保持良好的备份习惯。

相关文章:

  • php 鼠标点击其他区域下拉框隐藏,jQuery除指定区域外点击任何地方隐藏DIV功能...
  • java 日期转换星期,关于JAVA的小工具(日期转周几)
  • PHP的经典程序,几款经典php分页程序(1/4)
  • java gzip加解秘,vue 基于pako.js实现gzip的压缩和解压功能
  • matlab每一行白点个数,MATLAB 简单的计算白色轮廓中像素点的个数
  • java 类共享变量,Java提供了ThreadLocal(java.lang)类,实现线程内共享变量
  • Java第三方语音包发声,JDK中的包和他们的基本功能
  • python mock数据,python学习开发mock接口
  • php syslog 514,syslog详解及配置远程发送日志和远程日志分类
  • 兰春 MySQL,MySQL中经典的too many connection怎么破
  • php后台处理传来的图片文件,如何处理展示后台程序实时生成的文件?
  • php遍历json键值对,JS实现键值对遍历json数组功能示例
  • php服务器cpu要求,如何分析服务器需要什么样的配置(CPU、内存、带宽等)
  • oracle查看表的字段个数据,oracle逆向查询某个字段内容所存在的数据表名称
  • oracle在procedure调用自己,oracle 在plsql中创建procedure并调用
  • 《网管员必读——网络组建》(第2版)电子课件下载
  • Android 控件背景颜色处理
  • angular组件开发
  • Golang-长连接-状态推送
  • JavaScript实现分页效果
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • mysql 5.6 原生Online DDL解析
  • MySQL主从复制读写分离及奇怪的问题
  • QQ浏览器x5内核的兼容性问题
  • React Transition Group -- Transition 组件
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • SQLServer之创建数据库快照
  • Vue 重置组件到初始状态
  • 听说你叫Java(二)–Servlet请求
  • 一起参Ember.js讨论、问答社区。
  • 阿里云移动端播放器高级功能介绍
  • ​2020 年大前端技术趋势解读
  • ​secrets --- 生成管理密码的安全随机数​
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • #Ubuntu(修改root信息)
  • #考研#计算机文化知识1(局域网及网络互联)
  • (2015)JS ES6 必知的十个 特性
  • (多级缓存)多级缓存
  • (二)WCF的Binding模型
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (附源码)计算机毕业设计高校学生选课系统
  • (源码版)2024美国大学生数学建模E题财产保险的可持续模型详解思路+具体代码季节性时序预测SARIMA天气预测建模
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • ***监测系统的构建(chkrootkit )
  • *Django中的Ajax 纯js的书写样式1
  • *上位机的定义
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .form文件_SSM框架文件上传篇
  • .NET 4.0中的泛型协变和反变
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • .sh
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构
  • @拔赤:Web前端开发十日谈
  • [AIGC] Redis基础命令集详细介绍