Skip to content

Commit 5d73968

Browse files
authored
Merge pull request #89 from WinterChenS/fix/Incorrect-Access-Control-vulnerability
fix: invorrect access control vuInerability
2 parents 72a7152 + d402b2a commit 5d73968

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

src/main/java/cn/luischen/interceptor/BaseInterceptor.java

+38-12
Original file line numberDiff line numberDiff line change
@@ -48,37 +48,63 @@ public class BaseInterceptor implements HandlerInterceptor {
4848
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
4949
String uri = request.getRequestURI();
5050

51+
// 规范化路径,防止路径遍历
52+
uri = uri.replaceAll("/+", "/");
53+
5154
LOGGE.info("UserAgent: {}", request.getHeader(USER_AGENT));
5255
LOGGE.info("用户访问地址: {}, 来路地址: {}", uri, IPKit.getIpAddrByRequest(request));
5356

54-
55-
//请求拦截处理
57+
// 请求拦截处理
5658
UserDomain user = TaleUtils.getLoginUser(request);
5759
if (null == user) {
5860
Integer uid = TaleUtils.getCookieUid(request);
5961
if (null != uid) {
60-
//这里还是有安全隐患,cookie是可以伪造的
62+
// 这里还是有安全隐患, cookie 是可以伪造的
6163
user = userService.getUserInfoById(uid);
6264
request.getSession().setAttribute(WebConst.LOGIN_SESSION_KEY, user);
6365
}
6466
}
65-
if (uri.startsWith("/admin") && !uri.startsWith("/admin/login") && null == user
66-
&& !uri.startsWith("/admin/css") && !uri.startsWith("/admin/images")
67-
&& !uri.startsWith("/admin/js") && !uri.startsWith("/admin/plugins")
68-
&& !uri.startsWith("/admin/editormd")) {
67+
68+
// 如果是以 /admin 开头并且不是特定的静态资源文件,则要求认证
69+
if (uri.startsWith("/admin")
70+
&& !uri.startsWith("/admin/login")
71+
&& null == user
72+
&& !isStaticResource(uri)) {
73+
6974
response.sendRedirect(request.getContextPath() + "/admin/login");
7075
return false;
7176
}
72-
//设置get请求的token
73-
if (request.getMethod().equals("GET")) {
74-
String csrf_token = UUID.UU64();
77+
78+
// 设置 CSRF token 并要求对敏感操作进行校验
79+
if ("GET".equalsIgnoreCase(request.getMethod())) {
80+
String csrfToken = UUID.UU64();
7581
// 默认存储30分钟
76-
cache.hset(Types.CSRF_TOKEN.getType(), csrf_token, uri, 30 * 60);
77-
request.setAttribute("_csrf_token", csrf_token);
82+
cache.hset(Types.CSRF_TOKEN.getType(), csrfToken, uri, 30 * 60);
83+
request.setAttribute("_csrf_token", csrfToken);
84+
} else if ("POST".equalsIgnoreCase(request.getMethod())) {
85+
// 检查 POST 请求的 CSRF token
86+
String csrfToken = request.getParameter("_csrf_token");
87+
String expectedUri = cache.hget(Types.CSRF_TOKEN.getType(), csrfToken);
88+
if (expectedUri == null || !expectedUri.equals(uri)) {
89+
response.sendError(HttpServletResponse.SC_FORBIDDEN, "CSRF token invalid or expired.");
90+
return false;
91+
}
92+
cache.hdel(Types.CSRF_TOKEN.getType(), csrfToken); // Token 仅使用一次
7893
}
94+
7995
return true;
8096
}
8197

98+
/**
99+
* 检查是否为静态资源文件,避免对静态资源文件进行认证
100+
*/
101+
private boolean isStaticResource(String uri) {
102+
return uri.startsWith("/admin/css") || uri.startsWith("/admin/images")
103+
|| uri.startsWith("/admin/js") || uri.startsWith("/admin/plugins")
104+
|| uri.startsWith("/admin/editormd");
105+
}
106+
107+
82108
@Override
83109
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
84110
OptionsDomain ov = optionService.getOptionByName("site_record");

0 commit comments

Comments
 (0)