WebApi系列~安全校验中的防篡改和防复用

简介:

web api越来越火,因为它的跨平台,因为它的简单,因为它支持xml,json等流行的数据协议,我们在开发基于面向服务的API时,有个问题一直在困扰着我们,那就是数据的安全,请求的安全,一般所说的安全也无非就是请求的防篡改和请求的防复用,例如,你向API发一个查询用户账户的请求,在这个过程中,你可能要传递用户ID,用户所在项目ID等,而现在拦截工具如此盛行,很容易就可以把它的请求拦截,然后篡改,再转发,这样你的API就是不安全的,而对于订单,账户模块这种糟糕的API设计更是致命的,可能引起的损失是不可预计的,是灾难性的,拍拍脑子想想就知道,你向项目提现10元,我把请求拦截把10改成100000,那么这个将是一个灾难!

防篡改

一般使用的方式就是把参数拼接,加上双方约定的“密钥”,加上你的当前项目AppKey,做一次MD5加密,这个过程生成的字符串我们一般称为密文,而对应的可见参数我们叫明文,其中明文和密文用于网络传输,而密钥存储在本地和服务器,不能进行传输!

防复用

一般请求,被重复的使用,也是正常的,就上面的方式进行加密,就无法解决防复用的问题,这时我们需要在客户端和服务端分别生成UTC的时间戳,这个UTC是防止你的客户端与服务端不在同一个时区,呵呵,然后把时间戳timestamp拼在密文里就可以了,至于防复用的有效性,我们可以自定义,当然大叔定义的是秒,即同一秒内,请求可以重复发送。

大叔API安全结构图

web api核心安全校验代码片断

代码供大家参考和学习,正式的项目可以根据自己公司的需要去设计

 /// <summary>
    /// 功能:api数据安全性验证
    /// 校验方式:ciphertext=md5(form键的值拼接+timestamp+passkey),服务端用接收到的表单数据与时间戳和自己的passkey进行md5生成,最后比较值是否一致
    /// passkey为私钥,不用于网络传递,你可以将它与appKey进行关联,appKey用来传递,服务器根据appKey去数据库里取对应的passkey然后进行比较
    /// 功能:请求唯一性,防伪造性
    /// timestamp:UTC时间戳,不用于网络传递,在客户端调用服务器时,服务器也生成yyyyMMddhhmmss的时间戳,然后进行计算,看是否过期
    /// </summary>
    [AttributeUsage(AttributeTargets.Method)]
    public class ApiValidateFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            #region 初始化
            var context = (HttpContextBase)actionContext.Request.Properties["MS_HttpContext"];//获取传统context
            var request = context.Request;//定义传统request对象
            var paramStr = new StringBuilder();
            var coll = new NameValueCollection();
            if (request.HttpMethod.ToLower() == "get")
                coll = request.QueryString;
            else
                coll = request.Form;
            #endregion

            #region 解析XML配置文件
            var config = CacheConfigFile.ConfigFactory.Instance.GetConfig<ApiValidateModelConfig>().ApiValidateModelList.FirstOrDefault(i => i.AppKey == coll["AppKey"]);
            if (config == null)
            {
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
                {
                    Content = new StringContent("AppKey不是合并的,请先去组织生成有效的Key", Encoding.GetEncoding("UTF-8"))
                };
                base.OnActionExecuting(actionContext);
            }
            if (config.ExpireDate < DateTime.Now)
            {
                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
                {
                    Content = new StringContent("AppKey不是合并的,密钥已过期", Encoding.GetEncoding("UTF-8"))
                };
                base.OnActionExecuting(actionContext);
            }
            #endregion

            #region 验证算法
            var keys = new List<string>();
            foreach (string param in coll.Keys)
            {
                if (!string.IsNullOrEmpty(param))
                {
                    keys.Add(param.ToLower());
                }

            }
            keys.Sort();
            foreach (string p in keys)
            {
                if (p != "ciphertext")
                {
                    if (!string.IsNullOrEmpty(coll[p]))
                    {
                        paramStr.Append(coll[p]);
                    }

                }
            }
            paramStr.Append(DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmmss"));
            paramStr.Append(config.PassKey);
            #endregion


            if (Lind.DDD.Utils.Encryptor.Utility.EncryptString(paramStr.ToString(), Lind.DDD.Utils.Encryptor.Utility.EncryptorType.MD5)
                != request["cipherText"])
            {

                actionContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden)
                {
                    Content = new StringContent("验证失败,请求非法", Encoding.GetEncoding("UTF-8"))
                };
            }

            base.OnActionExecuting(actionContext);
        }
    }

在上的配置项大叔把它存储到的XML里,使用的是大叔自己封装的XML缓存组件CacheConfigFile,文件第一次访问会加载到内存,下次使用直接从内存返回,而当文件修改后,文件的最后更新时间发生变化,这时缓存过期,在生产缓存时,还是采用了单例模式,

这个在大叔框架里经常被看到,呵呵。

本文转自博客园张占岭(仓储大叔)的博客,原文链接:WebApi系列~安全校验中的防篡改和防复用,如需转载请自行联系原博主。

目录
相关文章
|
存储 前端开发 安全
前端安全性:常见攻击方式及防范措施
前端安全性是现代 Web 应用程序中不可忽视的重要方面。在网络环境中,前端代码容易受到各种攻击,比如 XSS(跨站脚本攻击)、CSRF(跨站请求伪造)、点击劫持等。为了保护用户的数据和确保应用程序的安全,开发者需要采取一系列防范措施。本文将介绍常见的前端安全攻击方式,并提供相应的防范措施。
964 0
|
安全 前端开发 Java
SpringBoot接口如何设计防篡改、防重放攻击
Spring Boot 防篡改、防重放攻击本示例主要内容请求参数防止篡改攻击基于timestamp方案,防止重放攻击使用swagger接口文档自动生成API接口设计API接口由于需要供第三方服务调用,所以必须暴露到外网,并提供了具体请求地址和请求参数,为了防止被别有用心之人获取到真实请求参数后再次发起请求获取信息,需要采取很多安全机制。
4445 0
|
2月前
|
安全 前端开发 Java
SpringBoot接口设计防篡改和防重放攻击
本文介绍了API接口的安全问题及解决方案,包括防止接口参数被篡改和重放攻击的方法。主要措施有:使用HTTPS传输、参数加密、时间戳签名验证等。并通过创建过滤器对请求参数进行签名验证,确保接口的安全性。
229 10
|
4月前
|
JSON 算法 安全
Web安全-JWT认证机制安全性浅析
Web安全-JWT认证机制安全性浅析
45 2
|
6月前
|
存储 运维 安全
防盗、防泄露、防篡改,我们把 ZooKeeper 的这种认证模式玩明白了
ZooKeeper 作为应用的核心中间件在业务流程中存储着敏感数据,具有关键作用。正确且规范的使用方法对确保数据安全至关重要,否则可能会因操作不当而导致内部数据泄露,进而带来严重的安全风险。因此,在日常的 ZooKeeper 运维和使用过程中,标准化和安全的操作对于加强企业安全防护和能力建设显得格外关键。为了实现这一目标,MSE 提供了一整套标准化流程,帮助用户以更安全、更简便的方式使用 ZooKeeper,从而加速企业安全能力的提升同时最大程度地降低在变更过程中可能出现的风险。
9075 15
|
安全 中间件 数据安全/隐私保护
Django中防范CSRF跨站点请求伪造攻击
Django中防范CSRF跨站点请求伪造攻击
121 0
WebApi登录防暴力破解
WebApi登录防暴力破解
122 0
|
安全 数据库 数据安全/隐私保护
如何解决网站被篡改提示该站点可能受到黑客攻击,部分页面已被非法篡改!
最近一段时间,我们SINE安全公司一连接到数十个公司网站被跳转到彩票,博彩网站上去,客户反映从百度搜索网站进去,直接跳转到彩票网站上,直接输入网址没有跳转,导致客户网站的流量急剧下滑,做的百度推广跟搜狗推广,都给彩票网站做广告了,公司领导高度重视网站安全的问题,因为给公司的形象以及名誉带来的损失太大了,我们安排安全技术人员对其网站进行全面的网站安全检测,对网站存在的漏洞,以及木马后门进行全面的清除与漏洞修复,安全加固。
6763 0