API安全设计
谈到API设计的安全,主要从方面来讲。一个是编码层面,还有就是运维层面。这里主要考虑编码层面。
横向越权
对于REST API
来讲,如果没有做好权限控制,很容易发生横向越权的问题。
比如,用户要请求一个资源 GET http://xx.com/api/orders/123
,很容易猜到123
应该是系统存储的订单ID,那么这个时候可以想:124是否是一个有效的订单ID?但是这个好想不是我的订单ID,我是否可以取下来看看🤔?
这个时候,如果没有同级的权限控制,很容易越权访问其它用户的订单。
如何解决这个问题?首先,敏感的信息不应该使用这种整型ID的方式来访问,应该对其进行加密或者使用UUID来进行访问。
不要在URL中拼接token等机密信息
token等机密信息最好放在请求的header中,因为一般情况下,拼接在URL中的内容都会记录在网关的日志里,如果日志泄漏,或者被别有用心的人利用,就有可能造成用户信息的泄漏。
考虑在API中加入时间戳
每次请求都加上时间戳,服务端收到请求后比对时间,如果相差超过一定的时间就拒绝提供服务。在一定程度上可以避免DDOS攻击。
考虑加入签名机制
引入签名,主要是基于参数合法性的考虑。
可以使用MD5或者SHA摘要算法对输入的参数进行计算,计算后得到一个sign,服务端收到请求后会重新按照相同的方法进行计算,如果两次计算的结果不一样,则说明请求被篡改过,此时应该拒绝服务。
对于更改资源状态的请求应该拒绝重复调用,此时可以缓存sign,如果收到相同的sign,则考虑决绝提供服务。
验证输入参数的有效性
参数的有效性,每个框架做法不太一样。Spring可以通过hibernate提供的验证机制,可以对传入的DTO和保存的model进行验证。Rails在保存的时候可以有回调取验证。
使用HTTPS
其它事情做的多好,但是只要传输过程数据有可能被窃取,这时候数据仍然是不安全的,所以,应该尽可能的使用https服务。
妥善保存用户的密码
不建议使用md5处理用户的密码。本质上,md5不属于加密算法,只是一种摘要算法。
可以参考之前的文章:用户密码的存储策略
参考文章: