目录
服务端之间接口调用
唯一请求sid
认证
app_id, app_key, app_secret
加解密+签名
防重放
数据格式总结
请求时:
响应时:
服务端前端页面(客户端)之间调用
加密方案如何确定
前后端有状态
前后端无状态
防重放
通用接口安全方案
加解密
对称加密
非对称加密
签名
Md5签名
Rsa 私钥签名
防重放
xss脚本注入
Sql注入
上传漏洞
命令执行漏洞
后台url跳转漏洞
目录遍历漏洞
异常信息返回
返回过多非必须字段
Springmvc中的解决方案
请求参数统一处理
spring相关类参考:
完整参数的加解密的统一处理
单个参数的加解密统一处理
响应参数统一处理
相关类参考:
跨域
服务端之间接口调用
由于服务是在后端,相对于前端,密钥盐等不是暴露给用户的,所以这里理论上不用考虑密钥泄露问题。
唯一请求sid
sid在请求方生成,32位uuid。
用处:
- 为了区别每次请求,方便请求有问题快速定位。
- 配合加密或者签名还可以用于防重放,即对有sid的数据进行加密或签名,由于攻击方不知道密钥或者盐,即不能对自己生成的sid进行伪造数据。接收方判断sid是否是已经存储过了,具体实现方案参考后面防重放。
如何用:
可放在请求头中,也可和真实数据一块放在请求体中。根据需要加密或签名。
认证
认证有两种需求,
一种只是为了区别别哪个app请求来的如用于解密或者验签,需要传输的数据为:明文app_key+加密或者签名数据,若攻击者随机使用app_key,但是针对与app_key的密文和签名在接收端验证也通不过。
一种是要根据app_key 和 app_secret 来判断来源是否正确,这种每次请求都要要暴露app_key 和 app_secret 。加app_secret的原因,1是为了验证密码是否正确,2是防止泄露后,可随时更改app_secret,而app_key不需要改动、因为在库中app_key会关联很多数据。
app_id, app_key, app_secret
对于平台来说, 需要给你的 你的开发者账号分配对应的权限:
1. app_id 是用来标记你的开发者账号的, 是你的用户id, 这个id 在数据库添加检索, 方便快速查找
2. app_key 和 app_secret 是一对出现的账号, 同一个 app_id 可以对应多个 app_key+app_secret, 这样 平台就可以分配你不一样的权限, 比如 app_key1 + app_secect1 只有只读权限 但是 app_key2+app_secret2 有读写权限.. 这样你就可以把对应的权限 放给不同的开发者. 其中权限的配置都是直接跟app_key 做关联的, app_key 也需要添加数据库检索, 方便快速查找
有状态的认证
类似与微信公众号的接口调用。
在首次验证(类似登录场景) , 你需要用 app_key(标记要申请的权限有哪些) + app_secret(密码, 表示你真的拥有这个权限) 来申请一个token, 就是我们经常用到的 access_token, 之后的数据请求, 就直接提供access_token 就可以验证权限了,access_token有过期时间,需要定时换.
无状态的认证
根据需要,可以只传app_key或者
认证信息放在请求头中:
在请求header中加上extAuth属性,extAuth = Base64(app_key:app_secret)。
认证信息放在请求体中:
{app_key:xxx,data:加密的数据},根据app_key去解密数据,若能解开说明正确,一是解决了来自哪个app的问题,二是同时解决了该用哪个app的密钥解密。
加解密+签名
RSA公私钥
公私加密验签,私钥解密签名。具体参看rsa加解密签名。
Aes+md5
Aes加密解密,md5签名验签。具体参看aes,md5
防重放
加密签名防止不了重放攻击,通过抓包抓到,可把原始包重新发送。
具体参考,防重放方案。
数据格式总结
请求时:
sid 放在请求头或者放在数据body体中,根据需要判断是否需要加密,如重放攻击时就需要对sid加密,不然可以随意伪造sid。
认证appKey 放在请求头或者数据body体中且是明文,根据需要判断是否要加appSecret。
请求明文:
假设对明文A -》{x:123}加密后的数据为B,对A签名后的数据为C
请求密文示例:
这里暂时不考虑sid和appKey的加密后数据:
{content:B,signature:C}
content代表对A加密后数据B,signature代表对B的签名。
响应时:
一般响应明文A为
{code:0,msg:xxx,data:{}}
加密分为两种:
- 仅对A中数据部分data字段加密得到B,对B签名得到C,得到响应数据:
{code:0,msg:xxx,content:B,signature:C}