一、开发安全
在学习安全之前,我们首先学习漏洞,知道漏洞我们才可以更进一步地维护我们的开发安全。注入就是把输入的数据变成可以执行的代码。
二、XSS介绍及防范措施
2.1何为XSS
开发安全 - XSS 详解 | Java 全栈知识体系 (pdai.tech)
就是说其实我们的浏览器十分的愚蠢,它看见js脚本就想执行。(回显)好比我们在文本框或者其他什么给后端发送内容的地方写了这些,而不对其进行过滤,就十分的危险。那么如何防范?过滤。
一个靶场:xss靶场练习(一)之xss.haozi.me_xss(haozimi)靶场地址-CSDN博客
ruoyi的过滤:
步骤一:查看FilterConfig类以及配置文件。(过滤器注入、配置类@Value)
步骤二:产看XssFilter:init、doFilter(实现Filter接口)
步骤三:请求内容处理,XssHttpServletRequestWrapper进行重包装,进入HTMLFilter
@Xss注解对属性进行检查
2.2XSS分类
反射型XSS:点击链接
存储型XSS:评论区攻击
DOM型XSS:属于前段的漏洞
上边俩个是后端的
这篇文章有意思:前端安全系列:如何防止XSS攻击?_location.href xss-CSDN博客,讲的XSS很生动。
2.3常用方法
一、使用HTML实体编码
是否高枕无忧?不。
public String encodeHtmlEntities(String input) {
String encoded = input.replaceAll("&", "&")
.replaceAll("\"", """)
.replaceAll("'", "'")
.replaceAll("<", "<")
.replaceAll(">", ">");
return encoded;
}
二、自定义过滤器
注册
三、前端限制见:前端安全系列:如何防止XSS攻击?_location.href xss-CSDN博客
除此之外,其实我们对用户上传的文件也应该进行过滤。
三、SQL注入介绍及防范措施
3.1何为SQL注入
当web应用向后台数据库传递SQL语句进行数据库操作时,如果对用户输入的参数没有经过严格的过滤处理,那么攻击者就可以构造特殊的SQL语句,直接输入数据库引擎执行,获取或修改数据库中的数据。
3.2常用方法
一、预编译语句PreparedStatement
二、输入验证和过滤(正则、关键词过滤)
三、使用ORM框架(之前讲的MyBatis)
四、重放介绍及防范措施
4.1何为重放
重放攻击原理:
数据截获:攻击者首先截获网络上的数据传输,这可能包括登录凭据、令牌、或其他敏感信息。(抓包)
数据复制:攻击者将截获的数据复制并保留下来。
数据重放:攻击者在未来的某个时间点,将这些复制的数据重新发送到原始服务器或另一个服务器,尝试模仿原始的合法用户。
与之相近的概念还有SSRF和CSRF,都是伪造攻击。
4.2常用方法
通性:
生成唯一标识符:每次接收到请求时,服务器需要生成一个唯一的标识符(如 nonce、timestamp、签名等),并将这个标识符与请求相关联。
存储已使用的标识符:为了能够识别出重复的请求,服务器需要将已经使用过的标识符存储在一个可靠的存储系统中,如数据库、缓存或内存。
验证标识符:当服务器接收到新的请求时,需要检查这个请求是否包含一个新的、未被使用过的标识符。如果标识符已经存在于存储系统中了,说明这个请求是重复的,服务器应该拒绝这个请求。
一、时间戳 前端在每次的请求中发送一个请求时间的时间戳,而我们实际后端处理的时候再次获取当前时刻的时间戳,两者比对,超过一定限度则拒绝请求。例如:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class ServerExample {
public static void main(String[] args) {
SpringApplication.run(ServerExample.class, args);
}
@PostMapping("/login")
public String login(@RequestParam String username, @RequestParam String password, @RequestParam long timestamp) {
long serverTimestamp = System.currentTimeMillis();
// 检查时间戳差异,设置为300000毫秒(5分钟)
if (Math.abs(serverTimestamp - timestamp) > 300000) {
return "请求无效或已过期";
}
// 处理登录逻辑,这里简单返回成功
return "登录成功";
}
}
二、随机数或者随机字符串(Nonce)
一般我们有随机数或者随机字符串(Nonce)完成上述步骤。对Nonce要设置一个定期清理的时间,避免过多存储空间。
客户端生成一个随机的 Nonce,加入到请求头或请求体中。
服务器检查该 Nonce 是否已经被使用过。
如果 Nonce 是第一次出现,则接受请求;如果已经使用过,则拒绝请求。
三、序列号
客户端请求业务接口之前先请求分配序列号接口来获得唯一的序列号。
客户端请求业务接口时,将序列号添加到请求头或者请求体中。
服务器在接收到请求时验证序列号是否已经处理过,未处理过则接受请求并在处理完成后作废此序列号,否则拒绝该请求。
使用此种方式需要注意以下几点:
需要使用加密或签名以防止序列号被篡改
我们看看ruoyi的实现。 步骤一:查看RepeatSubmit注解 步骤二:查看RepeatSubmitInterceptor 步骤三:查看SameUrlDataInterceptor
版权归原作者 Agazigi 所有, 如有侵权,请联系我们删除。