文章目录
- 1:spring actuator导致的信息泄露
- 1.1、Endpoint配置启用检测
- 1.2、信息泄露复现
- 1.3、防御
- 2:服务端口的合理使用
- 3:弱口令(密码)管理
- 4:服务端攻击
- 4.1、短信业务,文件上传等资源型接口
- 1、文件上传下载
- 2、短信
- 4.2、SOL注入攻击
- 4.3、敏感信息泄露
- 4.4、权限漏洞
- 5:客户端攻击
- 5.1、跨站脚本(XSS)攻击
- 5.1.1、知识点简介
- 5.1.2、xss攻击防御
- 1、Spring Boot 防 Xss 代码攻击
- 5.2、CSRF 跨域攻击
- 5.2.1、CORS跨域简介
- 1、解决跨域
- 5.3、点击劫持
使用springboot开发的应用可能存在各种使用不当导致的信息泄露和漏洞,在此记录
1:spring actuator导致的信息泄露
使用spring actuator你可以选择通过使用HTTP端点或使用JMX来管理和监控你的应用程序。 审计、健康和指标收集也可以自动应用于你的应用程序。
使用maven依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
1.1、Endpoint配置启用检测
Actuator 端点(endpoint)让你可以监控并与你的应用程序互动。 Spring Boot包括一些内置的端点,并允许你添加自己的端点。 例如, 端点提供基本的应用程序健康信息:health
比如在application.yaml中配置
# Actuator 监控端点的配置项
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * 可以开放所有端点。
但是在开启 include: ‘*’ 或者开启heapdump之后会存在信息泄露
可用已通过访问http://127.0.0.1:port/actuator/env
获取程序运行的所有的配置信息(包括application配置文件系统的默认配置等)
或者直接访问http://127.0.0.1:port/actuator/heapdump下载内存分析文件。里面可能会泄露配置的连接数据库的密码,ip等信息。
1.2、信息泄露复现
1、开启端点
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * 可以开放所有端点。
2、下载堆分析文件:http://127.0.0.1:port/actuator/heapdump
3、使用jvm堆分析工具分析JVM堆的heapdump:比如jdk自带的JDK自带的JVisualVM工具开源的https://github.com/wyzxxz/heapdump_tool
下载jar包后在运行目录下运行:后面的heapdump就是你下载的分析文件
输入0或者1选择分析的模式,选0即可
后输入passowrd就会开始查找,最终查询的结果会打印出来同时会写到当前目录下的*_output.txt文件中
里面可能存在配置的数据库密码等导致信息泄露
1.3、防御
方案1:禁用heapdump,使得无法访问堆分析文件
exclude: ‘heapdump’
management:
endpoints:
web:
base-path: /actuator # Actuator 提供的 API 接口的根目录。默认为 /actuator
exposure:
include: '*' # 需要开放的端点。默认值只打开 health 和 info 两个端点。通过设置 * ,可以开放所有端点。
exclude: 'heapdump' #禁用headump
此时重启程序再访问就访问不到了
- 方案2:结合Spring Security限制URL访问的规则
比如需要登录后才能访问等 - 方案3:加密springboot配置application.yaml中的password等机密信息
2:服务端口的合理使用
合理开通防火墙端口。
对于mysql,redis,后端的服务端口不应该暴漏给公网上,只允许在内网通过前端连接后台,后台连接数据库。
严格区分生产和测试数据库。有时候为了测试方便会开放测试数据库的端口给公网,注意区分生产上
3:弱口令(密码)管理
- mysql\redis等数据库:
对于数据库redis必须设立密码,对于mysql\redis\应用的登录入口严禁使用弱密码如123456、admin123、admin\admin等常见密码,非常容易被彩虹表破解。建议设立的复杂一些 - 后台管理系统登录 :加验证码、强密码、手机号验证码等
- 服务器的root等用户登录密码
比如可以使用一些密码生成器:https://1password.com/zh-cn/password-generator密码生成器
4:服务端攻击
4.1、短信业务,文件上传等资源型接口
别人恶意调用短信发送接口或者文件的上传下载。业务被消耗,下载流量持续被别人消耗,带来的是公司钱的损失!!
后台的相关接口除了登录注册等接口,肯定是需要登陆鉴权后才能访问的,这里主要针对于一些提供给第三方使用的开放接口,直接公开就能访问的接口需要做的鉴权!
就比如,大家应该对微信登录、短信接口、支付宝支付等其他第三方服务!!看下别人写的对接文档,接口的参数都有什么apiId, apiSecret ,MD5加密校验
1、文件上传下载
常见发生位置 :所有使用到上传功能的位置。
-
用户可自定义的头像、背景图片等。
-
富文本编辑器中的文件上传功能。
防御措施
-
将上传目录权限设置为不可执行。
-
严格判断文件类型,使用白名单而不是黑名单(注意大小写问题)。需要注意与Web Server相关的漏洞所造成的问题,例如Apache、IIS、Nginx 等Web服务器的文件解析漏洞。
-
使用随机数改写上传后的文件名和文件路径。
-
单独设置文件服务器及域名。
/**
* 白名单文件类型
*/
private static final Set<String> WHITE_FILE_TYPES =
SetUtils.asSet("gif", "jpg", "svg", "png", // 图片
"eot", "woff2", "ttf", "woff", // 字体
"xdb");
对于使用对象存储的服务,应该严格限制上传下载的频率、桶的私有性,各种鉴权机制
2、短信
短信发送:比如手机号必须在数据库
4.2、SOL注入攻击
介绍:SOL注入攻击是攻击者成功的向服务器提交恶意的SQL查询代码,程序在接收后错误的将攻击者的输入作为查询语句的一部分执行,导致原始的查询逻辑被改变,额外的执行了攻击者精心构造的恶意代码。
举例:’ OR ‘1’=‘1,这是最常见的 SQL注入攻击。当我们输入用户名 admin ,然后密码输入’ OR ‘1’=1=‘1的时候,我们在查询用户名和密码是否正确的时候,本来要执行的是SELECT * FROM user WHERE username=’’ and password=‘’,经过参数拼接后,会执行 SQL语句 SELECT * FROM user WHERE username=‘’ and password=‘’ OR ‘1’=‘1’,这个时候1=1是成立,自然就跳过验证。
防御:对进入数据库的特殊字符('"<>&*;等)进行转义处理,或编码转换。在应用发布之前建议使用专业的SQL注入检测工具(如sqlmap、SQLninja)进行检测,以及时修补被发现的SQL注入漏洞。避免网站打印出SQL错误信息,比如类型错误、字段不匹配等,容易把代码里的SQL语句暴露出来。
4.3、敏感信息泄露
1、后台敏感数据,如用户的邮箱、手机号、身份证
2、Web 服务器的一些敏感信息,如用户名、密码、源代码、服务器信息、配置信息等。
防御:
- 敏感信息加密传输,后端对涉密的数据去敏感信息返回;
- 应用程序报错时,不对外产生调试信息;
- 过滤用户提交的数据与特殊字符;
- 保证源代码、服务器配置的安全。
4.4、权限漏洞
划分合理的用户,组织、菜单、按钮间的增删改查的权限配置
5:客户端攻击
5.1、跨站脚本(XSS)攻击
5.1.1、知识点简介
存在三种XSS类型,通常针对用户的浏览器:
反射式XSS:应用程序或API包括未经验证和未经转义的用户输入,作为HTML输出的一部分。一个成功的攻击可以让攻击者在受害者的浏览器中执行任意的HTML和JavaScript。 通常,用户将需要与指向攻击者控制页面的某些恶意链接进行交互,例如恶意漏洞网站,广告或类似内容。
存储式XSS:你的应用或者API将未净化的用户输入存储下来了,并在后期在其他用户或者管理员的页面展示出来。 存储型XSS一般被认为是高危或严重的风险。
基于DOM的XSS:会动态的将攻击者可控的内容加入页面的JavaScript框架、单页面程序或API存在这种类型的漏洞。理想的来说,你应该避免将攻击者可控的数据发送给不安全的JavaScriptAPI。
典型的XSS攻击可导致盗取session、账户、绕过MFA、DIV替换、对用户浏览器的攻击(例如:恶意软件下载、键盘记录)以及其他用户侧的攻击。
比如:在api接口传参时param或者body中的属性上传一些脚本的命令等
http://192.168.1.101/xss/example2.php?name=<sCript>alert("hey!")</scRipt>
比如body的type属性中加入脚本
POST /user
Host: api.felord.cn
{
"userId" : 1001,
"username" : "felord.cn",
"type" : "\<script\>alert(document.cookie)\</script\>"
}
目的:达到对入参或者出参内容的修改,劫持内容达到目的
5.1.2、xss攻击防御
防御可以在前端和后端进行,目前主流的浏览器都支持很多xss攻击的策略,包括前端对参数html的转义判断,后端进行xss防御等,下面主要说后端的方案。
Xss 的防范手段
首先是过滤。对诸如(script、img、a)等标签进行过滤。
其次是编码。像一些常见的符号,如<>在输入的时候要对其进行转换编码,这样做浏览器是不会对该标签进行解释执行的,同时也不影响显示效果。
最后是限制。通过以上的案例我们不难发现xss攻击要能达成往往需要较长的字符串,因此对于一些可以预期的输入可以通过限制长度强制截断来进行防御。
1、Spring Boot 防 Xss 代码攻击
从上面可以知道,Xss 攻击是对入参或者说输出进行修改,劫持内容达到目的。因此我们需要对整个系统的提交进行过滤和转义。
spring boot 防范 XSS 攻击可以使用过滤器,对内容进行转义,过滤。
这里就采用Spring boot+Filter的方式实现一个Xss的全局过滤器
还可以使用编码的形式来转义请求参数和响应体的字符来防止XSS攻击。这里会用到Spring提供的工具类org.springframework.web.util.HtmlUtils
Spring boot实现一个Xss过滤器, 常用的有两种方式:
第一种:
自定义过滤器
- 重写HttpServletRequestWrapper、
重写getHeader()、getParameter()、getParameterValues()、主要处理@param的参数的过滤 - 重写 getInputStream()实现对传统“键值对Json”传参方式的过滤也就是@RequestBody参数
比如重写过滤器:
import org.springframework.web.util.HtmlUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.stream.Stream;
public class XssHttpServletRequestWrapper extends HttpServletRequestWrapper {
public XssHttpServletRequestWrapper(HttpServletRequest request) {
super(request);
}
@Override
public String getHeader(String name) {
String value = super.getHeader(name);
return HtmlUtils.htmlEscape(value);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
return HtmlUtils.htmlEscape(value);
}
@Override
public String[] getParameterValues(String name) {
String[] values = super.getParameterValues(name);
return values != null ? (String[]) Stream.of(values)
.map(HtmlUtils::htmlEscape).toArray() :
super.getParameterValues(name);
}
}
第二种:
自定义序列化器, 对MappingJackson2HttpMessageConverter 的objectMapper做设置.
重写JsonSerializer.serialize()实现对出参的过滤 (PS: 数据原样保存, 取出来的时候转义)
重写JsonDeserializer.deserialize()实现对入参的过滤 (PS: 数据转义后保存)
实现后在配置文件中进行配置后测试
比如
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
5.2、CSRF 跨域攻击
跨域攻击存在session/cookie的环境中,伪造或劫持了客户的的cookie信息(可能包含用于的登录信息)后伪造请求进行了攻击。
token可以抵抗csrf,cookie+session不行
5.2.1、CORS跨域简介
跨域限制访问,其实是浏览器的限制。理解这一点很重要!!!同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域;
后端解决CORS跨域
对于 CORS的跨域请求,主要有以下几种方式可供选择:
- 返回新的CorsFilter (全局配置)
- 重写WebMvcConfigurer(全局配置)
- 使用注解@CrossOrigin(局部配置)
- 手动设置响应头 (HttpServletResponse)(局部配置)
自定webfilter实现跨域
注意:
CorFilter、 WebMvConfigurer、@CrossOrigin需要SpringMVC 4.2以上版本才支持,对应springBoot 1.3版本以上
如果使用了局部跨域是会覆盖全局跨域的规则,所以可以通过@CrossOrigin 注解来进行细粒度更高的跨域资源控制。
其实无论哪种方案,最终目的都是修改响应头,向响应头中添加浏览器所要求的数据,进而实现跨域
所有解决跨域问题,不外乎就是解决浏览器拦截问题,要么前端设置请求头,要么后端设置请求头,无论谁设置请求头,浏览器只要放行即可
1、解决跨域
创建CorsFilter注册到springboot
/**
* 创建 CorsFilter Bean,解决跨域问题
*/
@Bean
public FilterRegistrationBean<CorsFilter> corsFilterBean() {
// 创建 CorsConfiguration 对象
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOriginPattern("*"); // 设置访问源地址
config.addAllowedHeader("*"); // 设置访问源请求头
config.addAllowedMethod("*"); // 设置访问源请求方法
// 创建 UrlBasedCorsConfigurationSource 对象
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config); // 对接口配置跨域设置
return createFilterBean(new CorsFilter(source), WebFilterOrderEnum.CORS_FILTER);
}
配置springboot security
@Bean
protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
// 登出
httpSecurity
// 开启跨域
.cors().and();
}
5.3、点击劫持
伪造页面的按钮,通过覆盖现有的页面内容等方式诱导用户点击,是前端的攻击