如何防止请求的URL被篡改

简介:

如图,是我们模拟的一个从浏览器发送给服务器端的转账请求。久一的ID是 web_resource,正在操作100元的转账。

011c822f6fef7f79982b215ef04e86e575f33682

再如图,因为是通过浏览器 `url` 访问服务,这个时候金额被篡改成了 200,那么服务器接受到了200,直接扣除了200怎么解决?这就是本文要讲解的内容。

816f7967f96573d2a164a84178f5f0009e8ce8d5

防止url被篡改的方式有很多种,本文就讲述最简单的一种,通过 secret 加密验证。

道理很简单,服务器接收到了 price 和 id,如果有办法校验一下他们是否被修改过不就就可以了吗?

那么我们传递的时候增加一个参数,叫做sign,sign是使用用户不可见的一个secret和price、id组合加密获得,然后传递给服务器端。当服务器端接收到请求的时候,获取到price、id,通过同样的secret加密和sign比较如果相同就通过校验,不同则被篡改过。

c02c62f3f9b6410977719b12333fc9e56c8f4281

那么问题来了,如果参数特别多怎么办?

所以通用的做法是,把所有需要防止篡改的参数按照字母正序排序,然后顺序拼接到一起,再和secret组合加密得到 sign。具体的做法可以参照如下。

 
 
public static String generateSign (Map<String , String> parameters) {
try {
List<String> names = new ArrayList<>() ;
parameters.forEach((k , v) -> {
if (v != null && !Objects.equals(v , "" )
&& !Objects.equals(k , "sign" )) {
names .add(k) ;
}
}) ;

List sortedNames = names.stream().sorted()
.collect(Collectors.toList()) ;
StringBuffer sb = new StringBuffer() ;
sortedNames.forEach(n ->
sb .append(String.format( "%s=%s" , n , parameters .get(n)))) ;
String sign = md5(sb.toString()) ;
return sign ;
} catch (Exception e) {
return "" ;
}
}

private static String md5 (String inputString)
throws NoSuchAlgorithmException , UnsupportedEncodingException {

MessageDigest md = MessageDigest.getInstance( "MD5" ) ;
md.update(inputString.getBytes( "UTF-8" )) ;

byte [] digest = md.digest() ;

return convertByteToHex(digest) ;
}

private static String convertByteToHex ( byte [] byteData) {
StringBuilder sb = new StringBuilder() ;
for ( int i = 0 ; i < byteData. length ; i++) {
sb.append(Integer.toString((byteData[i] & 0xff ) + 0x100 , 16 )
.substring( 1 )) ;
}
return sb.toString() ;
}

generateSign 就是所有需要加密的参数,包括secret

有的同学担心,那么他万一猜到了我的加密算法怎么办,这个不用担心,你的secret是保持在服务器端的,不会暴漏出去的,所以他知道了算法也不会知道具体加密的内容。

那么问题又来了,如果小明通过抓包工具获取到了URL,他是不是可以无限制的访问这个地址呢?那就出现了“久一”的钱被一百一百的转空了。

那可怎么办?这里涉及到了另一个话题,接口的幂等,我们后面会详细讲解怎么通过幂等控制重复扣款。这里我们要讲解的是怎么控制 URL 失效。

这里又有一个通用的做法,就是再添加一个参数 timestamp。对的,就是当前的时间戳。服务器获取到 timestamp 以后检验一下是否在5分钟以内,如果不是直接返回请求失效就可以了?那么如果timestamp 被篡改了呢?不会的,因为我们按照上面的做法同样对 timestamp 做了加密防止篡改。

1ee5ade7c3b2274f36fcc0cd26b3b6f6d39fb1f7

最简单的校验接口被篡改的方式,你学会了吗?


原文发布时间为:2018-10-29

本文作者:王久一

本文来自云栖社区合作伙伴“Web项目聚集地”,了解相关信息可以关注“Web项目聚集地”。

相关文章
|
2月前
feign发起url请求日期序列化问题
feign发起url请求日期序列化问题
41 0
|
3月前
Copy网页中F12里的请求url到postman,并且把所有参数都带过来
Copy网页中F12里的请求url到postman,并且把所有参数都带过来
29 0
|
4月前
|
Web App开发 JavaScript Java
教会你什么是Spring-Rest- url 请求风格
教会你什么是Spring-Rest- url 请求风格
50 0
|
6月前
|
Web App开发 资源调度 开发者
SAP Fiori Elements 应用 OData 元数据请求 url 里的模型名称决定逻辑
SAP Fiori Elements 应用 OData 元数据请求 url 里的模型名称决定逻辑
49 0
|
6月前
|
存储 JavaScript 前端开发
SAP UI5 OData 请求 url 中的参数 sap-value-list=none
SAP UI5 OData 请求 url 中的参数 sap-value-list=none
31 0
|
6月前
|
Web App开发 JSON 数据格式
使用 http-proxy 代理 HTTP 请求时遇到的 the requested url is invalid 错误消息
使用 http-proxy 代理 HTTP 请求时遇到的 the requested url is invalid 错误消息
103 0
|
7月前
|
JSON 算法 API
阿里云 OpenAPI 中,一般情况下请求参数是放在请求的 URL 中的
阿里云 OpenAPI 中,一般情况下请求参数是放在请求的 URL 中的
99 1
|
8月前
|
Web App开发 缓存 JavaScript
Rest-优雅的url 请求风格
Rest-优雅的url 请求风格
45 1
|
10月前
|
测试技术
【解决方案 十】判断URL请求是否成功并检测访问效率
【解决方案 十】判断URL请求是否成功并检测访问效率
174 0
|
10月前
|
测试技术 应用服务中间件 网络安全
接口测试中请求URL管理的正确姿势
接口测试中,必不可少的第一个要素就是请求URL。如何进行URL管理是接口测试的首要任务。

热门文章

最新文章