保障接口安全的11个方法

在这里插入图片描述

一、参数校验

  • 校验参数是否为空,有些接口中可能会包含多个参数,有些参数允许为空,有些参数不允许为空,需要对这些参数做校验,防止接口底层出现异常。
  • 校验参数类型,比如:age 是 int 类型的,用户传入了一个字符串:“123abc”,这种情况参数不合法,需要被拦截
  • 校验参数的长度,特别是对于新增或者修改数据接口,必须要做参数长度的校验,否则超长了数据库会报异常。比如:数据库 username 字段长度是 30,新用户注册时,输入了超过 30 个字符的名称,需要提示用户名称超长了。虽说前端会校验字段长度,但接口对参数长度的校验也必不可少。
  • 校验枚举值,有些接口参数是枚举,比如:status,数据库中设计的该字段只有1、2、3三个值。如果用户传入了4,则需要提示用户参数错误。
  • 校验数据范围,对于有些金额参数,需要校验数据范围,比如:单笔交易的 money 必须大于 0,小于 10000。

可以自己写代码,对每个接口的请求参数一一做校验,也可以使用一些第三方的校验框架。
Hiberate 的 Validator 框架,它里面包含了 @Null、@NotEmpty、@Size、@Max、@Min 等注解,有些日期字段和枚举字段,可能需要通过自定义注解的方式实现参数校验。

二、统一封装返回值

写的某个接口底层的 SQL,在某种条件下有语法问题。某个用户请求接口之后,在访问数据库时,直接报了 SQL 语法错误,将数据库名、表名、字段名、相关 SQL 语句都打印出来了。
接口将这些异常信息直接返回给外网的用户,有些黑客拿着这些信息,将参数做一些调整,拼接一些注入 SQL,可以对数据库发起攻击。
因此,非常有必要对接口的返回值做统一的封装。


{
    "code":0,
    "message":null,
    "data":[{"id":123,"name":"abc"}]
}

code:表示响应码,0-成功,1-参数为空,2-参数错误,3-签名错误 4-请求超时 5-服务器内部错误等。
message:表示提示信息,如果请求成功,则返回空。如果请求失败,则返回我们专门在代码中处理过,让用户能看懂的错误信息。
data:表示具体的数据,返回的是一个 JSON 字段。

对返回值这样封装之后,即使在接口的底层出现了数据库的异常,也不会直接提示用户,给用户提示的是服务器内部错误。
对返回值统一封装的工作,没有必要在业务代码中做,完全可以在放到API网关。
业务系统在出现异常时,抛出业务异常的 RuntimeException,其中有个 message 字段定义异常信息。
所有的 API 接口都必须经过 API网关,API 网关捕获该业务异常,然后转换成统一的异常结构返回,这样能统一返回值结构。

三、做转义

在用户自定义输入框,用户可以输入任意内容。
有些地方需要用 html 的格式显示用户输入的内容,比如文章详情页或者合同详情页,用户可以自定义文案和样式。

这些地方如果我们不做处理,可能会遭受 XSS(Cross Site Scripting)攻击,也就是跨站脚本攻击。

攻击者可以在输入的内容中,增加脚本,比如:,这样在访问合同详情页时,会弹出一个不需要的窗口,攻击者甚至可以引导用户访问一些恶意的链接。
由此,我们需要对用户输入内容中的一些特殊标签做转义。

下面这张图中列出了需要转义的常见字符和转义后的字符:
在这里插入图片描述
可以自定义一个转义注解,打上该注解的字段,表示需要转义
有个专门的 AOP 拦截器,将用户的原始内容,转换成转义后的内容。
保存到数据库中是转义之后的内容。
除此之外,为了防止 SQL 注入的情况,也需要将用户输入的参数做 SQL 语句方面的转义。

四、做权限控制

①、校验是否登录

对于用些公共数据,比如:外部分类,所有人都能够看到,不用登录也能看到。
而对于有些查看内部分类的接口,需要用户登录之后,才能访问。

可以从当前用户上下文中获取用户信息,校验用户是否登录。
如果用户登录了,当前用户上下文中该用户的信息不为空。

②、接口功能权限控制

对于有些重要的接口,比如订单审核接口,只有拥有订单审核权限的运营账号,才有权限访问该接口。

可以自定义一个权限注解,在注解上可以添加权限点。在网关层有个拦截器,会根据当前请求的用户的权限,去跟请求的接口的权限做匹配,只有匹配上次允许访问该接口。

③、接口数据权限控制

对于有些订单查询接口,普通运营只能查看普通用户的数据。
而运营经理可以查看普通用户和 VIP 用户的数据
不同的角色,能够查看的数据范围不同,可以在查询数据时,在 SQL 语句中动态拼接过滤数据权限的 SQL。

五、加验证码

对于一些非常重要的接口,在做接口设计的时候,要考虑恶意用户刷接口的情况。
最早的用户注册接口,是需要用图形验证码校验的,比如下面这样的:
在这里插入图片描述
仅靠图形验证码,防止用户注册接口被刷,难道太大了。又出现了一种移动滑块形式的图形验证方式,安全性更高。

在这里插入图片描述
此外,使用验证码比较多的地方是发手机短信的功能。
发手机短信的功能,一般是购买的云服务厂商的短信服务,按次收费,比如:发一条短信 0.1 元。
如果发送短信的接口,不做限制,被用户恶意调用,可能会产生非常昂贵的费用。

六、限流

从页面上的验证码,只能限制当前页面的不能重复发短信,但如果用户刷新了页面,也可以重新发短信。
因此非常有必要在服务端,即:发送短信接口做限制。

增加一张短信发送表,该表包含:id、短信类型、短信内容、手机号、发送时间等字段。
在这里插入图片描述
有用户发送短信请求过来时:

  • 先查询该手机号最近一次发送短信的记录
  • 如果没有发送过,则发送短信
  • 如果该手机号已经发送过短信,但发送时间跟当前时间比超过了 60 秒,则重新发送一条新的短信
  • 如果发送时间跟当前时间比没超过 60 秒,则直接提示用户操作太频繁,请稍后重试

这样就能非常有效的防止恶意用户刷短信的行为。

漏洞:
用户知道在 60 秒以内,是没法重复发短信的。他有个程序,刚好每隔 60 秒发一条短信。
这样1个手机号在一天内可以发:60*24 = 1440 条短信。
如果他有 100 个手机号,那么一天也可以刷你很多条短信。
由此,还需要限制每天同一个手机号可以发的短信次数。

其实可以用 Redis 来做:
用户发短信之后,在 Redis 中保存一条记录,key 是手机号,value 是发短信的次数,过期时间是 24 小时。
这样在发送短信之前,要先查询一下,当天发送短信的次数是否超过10次(假设同一个手机号一天最多允许发 10 条短信)
如果超过 10 次,则直接提示用户操作太频繁,请稍后重试。如果没超过 10 次,则发送短信,并且把 Redis 中该手机号对应的 value 值加 1。
在这里插入图片描述

七、加ip白名单

比如:会员系统的开通会员接口,业务系统可能会调用该接口开通会员。
这个 IP 白名单前期可以做成一个 Apollo 配置,可以动态生效。

如果后期 IP 数量多了的话,可以直接保存到数据库。
只有ip在白名单中的那些服务器,才允许调用开通会员接口。
这样即使开通会员接口地址和请求参数被泄露了,调用者的 IP 不在白名单上,请求开通会员接口会直接失败。

除非调用者登录到了某一个白名单 IP 的对应的服务器,这种情况极少,因为一般运维会设置对访问器访问的防火墙。

当然如果用了 Fegin 这种走内部域名的方式访问接口,可以不用设置 IP 白名单,内部域名只有在公司的内部服务器之间访问,外面的用户根本访问不了。
但对于一些第三方平台的接口,他们更多的是通过设置ip白名单的方式保证接口的安全性。

八、校验敏感词

对于某些用户可以自定义内容的接口,还需要对用户输入的内容做敏感词校验。
比如:在创建商品页面,用户输入了:傻逼商品,结果直接显示到了商城的商品列表页面,这种情况肯定是不被允许的。

当然你也可以做一个审核功能,对用户创建的商品信息做人工审核,如果商品数量太多,这样会浪费很多人力。
当然你也可以做一个审核功能,对用户创建的商品信息做人工审核,如果商品数量太多,这样会浪费很多人力。

可以调用第三方平台的接口,也可以自己实现一个敏感词校验接口。
可以在 GitHub 上下载一个开源的敏感词库,将那些敏感词导入到数据库中。
然后使用 hanlp 对用户输入的内容,进行分词。对分好的词,去匹配敏感词库中的那些敏感词。

如果匹配上了,则说明是敏感词,则验证不通过。
如果没有匹配上,则说明非敏感词,则验证通过。

不可能在每个业务接口中都调用敏感词校验接口,我们可以自定义注解,在AOP拦截器中调用敏感词校验接口。
在调用业务接口之前,先触发拦截器,校验打了敏感词校验注解的那些字段,将他们里面包含的内容,作为入参传入敏感词校验接口做校验。
当然有时候 hanlp 分词器会把句子分错词,还需要添加一个敏感词的白名单,白名单中的词不是敏感词。

九、使用https协议

HTTP(HyperText Transport Protocol,即超文本传输协议)协议

  1. 使用明文通讯,内容容易被窃听。
  2. 不验证通讯方的真实身份,容易遭到伪装。
  3. 无法证明报文的完整性,报文很容易被篡改。

HTTPS 协议是在 HTTP 协议的基础上,添加了加密机制:

  • SSL:它是Secure Socket Layer的缩写, 表示安全套接层。
  • TLS:它是Transport Layer Security的缩写,表示传输层安全。

HTTPS = HTTP + 加密 + 认证 + 完整性保护。
HTTPS 协议需要申请证书,有些额外的费用

十、数据加密

有些信息是用户的核心信息,比如:手机号、邮箱、密码、身份证、银行卡号等,不能别泄露出去。
在保存到数据库时,我们要将这些字段,做加密处理。

这种情况可以使用AES对称加密的方式,因为后面系统的有些业务场景,需要把加密的数据解密出来。

为了安全性考虑,我们需要设置一个用于加密的密钥,这个密钥可以稍微复杂一点,包含一些数字、字母和特殊字符
同样可以通过自定义注解的方式,给需要加密的字段添加该注解,在 Mybatis 拦截器中实现加解密的功能。

对于查询操作,需要将加了该注解的字段的数据做解密处理。
对于写入操作,要将加了该注解的字段的数据做加密处理。

有些页面显示的地方,手机号一般不会显示完整的手机号,中间有一部分用代替,比如:182**3457。

十一、做风险控制

有些特殊的接口,比如用户登录接口,我们需要对该接口做风险控制,尽可能减小被盗号的风险。

用户登录失败之后,需要有地方,比如:Redis,记录用户登录失败的次数。
如果用户第一次输入账号密码登录时,出现的是一个稍微简单的验证码。

如果用户把账号或密码连续输错 3 次之后,出现了更复杂的验证码。
或者改成使用手机短信验证。

如果用户在一天之内,把账号或密码连续输错 10 次,则直接锁定该账号。
这样处理是为了防止有人用一些软件,暴力破解账号和密码。

在用户登录成功之后,需要有一张表记录用户的 IP、所在城市和登录的设备id。
如果你的账号被盗了。
在盗号者在页面输入账号密码登录,会调用登录接口,此时登录接口中可以根据用户的ip和设备id,做一些风险控制。
接口判断如果用户当前登录的 IP、所在城市和设备 IP,跟上一次登录成功时记录的相差非常大。

比如:1 小时之前,用的 IP 是 100.101.101.101,城市是北京,设备 id 是 1001,而 1 小时之后,用的 IP 是200.202.202.101,城市是广州,设备 id 是 2002。
这种情况用户的账号极有可能被盗了。登录接口做安全性升级,需要校验用户手机验证码才能登录成功。
由于盗号者只有你的账号和密码,没有手机验证码,所以即使被盗号了,也没办法登录成功。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/352545.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

对鸢尾花进行分类预测-----pycharm

项目说明 #项目: 对鸢尾花进行分类预测 #实例数量150个(3类各50个) #属性数量:4(数值型,数值型,帮助预测的属性和类) #特征:花萼长度,花萼宽度,花瓣长度,花瓣宽度 单位&#xff1…

HarmonyOS 鸿蒙组件启动规则(Stage模型)

组件启动规则(Stage模型) 启动组件是指一切启动或连接应用组件的行为: 启动UIAbility、ServiceExtensionAbility、DataShareExtensionAbility,如使用startAbility()、startServiceExtensionAbility()、startAbilityByCall()等相关…

FOC系列(五)----STM32F405RGT6控制板焊接与初步编写代码

声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。    首先祝大家新年快乐,因为我也快放假了,驱动板只能是开学之后再去测试了,本篇博客应该是本专栏年前的最后一篇了 一…

【计网·湖科大·思科】实验三 总线型以太网的特性、集线器和交换机的区别、交换机的自学习算法

🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要&…

字符串相关的函数和内存块相关函数

𝙉𝙞𝙘𝙚!!👏🏻‧✧̣̥̇‧✦👏🏻‧✧̣̥̇‧✦ 👏🏻‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - :来于“云”的“羽球人”。…

[学习笔记] ONNX 基础知识

1. ONNX 简介 1.1 什么是 ONNX 开放神经网络交换 ONNX(Open Neural Network Exchange)是一套表示深度神经网络模型的开放格式,由微软和 Facebook 于 2017 推出,然后迅速得到了各大厂商和框架的支持。通过短短几年的发展&#xf…

【JavaEE进阶】 #{}和${}

文章目录 🍃前言🌳#{}和${}使⽤🚩Interger类型的参数(基础数据类型)🎈使用#{}🎈使用${} 🚩String类型的参数使用🎈#{}使用🎈${} 🎍#{}和${}区别&a…

林浩然与极限的“无穷”约会

林浩然与极限的“无穷”约会 Lin Haoran’s Encounter with the Mathematical “Infinity” 在数学王国里,有一位名叫林浩然的大侠,他的江湖就是高等数学的殿堂。而他要挑战的终极Boss,便是那个既神秘又顽皮的“极限”。 In the kingdom of …

《golang设计模式》第三部分·行为型模式-10-模板方法(Template Method)

文章目录 1. 概述1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概述 模板方法(Template Method)用来定义算法的框架,将算法中的可变步骤定义为抽象方法,指定子类实现或重写。 1.1 角色 AbstractClass(…

字符串相关函数【超详细】(strcpy,strstr等string.h中的函数)

文章目录 strlen库中函数定义函数作用函数大概“工作”流程函数使用注意(要求)函数使用例举 strcpy库中函数定义函数作用函数使用注意(要求)函数大概“工作”流程函数使用例举 strcat库中函数定义函数作用函数使用注意&#xff08…

Go 的命令行解析 flag 包如何扩展新类型呢?

上篇文章 说到,除布尔类型 Flag,flag 支持的还有整型(int、int64、uint、uint64)、浮点型(float64)、字符串(string)和时长(duration)。 flag 内置支持能满足…

transformer和vit学习笔记

以下记录自己对transformer的学习笔记,可能自己看得懂【久了自己也忘了看不懂】,别人看起来有点乱。以后再优化文档~ 小伙伴请直接去看学习资源: Transformer的理解T-1_哔哩哔哩_bilibili 首先,时序处理:一些模型的出…

Two-factor authentication (2FA) is required for your GitHub account解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

【基于电商履约场景的 DDD 实战】DDD业务建模第二部分:履约的战术设计(梳理整个战术设计流程图)

欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送! 在我后台回复 「资料」 可领取编程高频电子书! 在我后台回复「面试」可领取硬核面试笔记! 文章导读地址…

Java笔记 --- 二、Stream流

二、Stream流 结合Lambda表达式,简化集合、数组的操作 获取Stream流对象 单列集合获取Stream流 双列集合获取Stream流 数组获取Stream流 一堆零散的数据获取Stream流 Stream流的静态方法of的形参是一个可变参数,可以传递零散数据,也可以传递…

【Python】02快速上手爬虫案例二:搞定验证码

文章目录 前言1、不要相信什么验证码的库2、以古诗文网为例,获取验证码1)code_result.py2)gsw.py 前言 提示:以古诗文网为例,获取验证码: 登录:https://so.gushiwen.cn/user/login.aspx 1、不…

【C++】类与对象(一)

前言 类与对象(一) 文章目录 一、面向对象和面向过程的对比二、类的引入2.1 C中的结构体2.2 类2.3 类定义方法2.4 修饰限定符2.5 封装2.6 类的实例化2.7 类对象的大小 三、this指针3.1 this 指针的使用 一、面向对象和面向过程的对比 面向过程编程是将程…

【Docker】nacos集群搭建Nginx负载均衡

目录 一、mysql安装与基操 1.1 数据准备 1.2 创建mysql与数据表 二、Nacos集群部署 2.1 创建nacos及配置 2.2 创建Nginx容器 一、mysql安装与基操 1.1 数据准备 拉取mysql docker pull mysql:5.7(版本) 定义挂载目录 mkdir -p /mysql/{conf,data,script} 配置my.c…

【排序4】探秘归并排序:提高程序效率的必备技巧

😊归并排序 🎊1、基本思想🎊2、代码示例🎊3、非递归实现🎊4、归并排序的性能分析🎊5、归并排序的优缺点🎊6、归并排序的应用场景🎊7、总结 🎊1、基本思想 归并排序&…

(笔记总结)C/C++语言的常用库函数(持续记录,积累量变)

写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…