Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: invorrect access control vuInerability #91

Merged
merged 1 commit into from
Nov 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 15 additions & 10 deletions src/main/java/cn/luischen/interceptor/BaseInterceptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,42 +54,46 @@ public boolean preHandle(HttpServletRequest request, HttpServletResponse respons
LOGGE.info("UserAgent: {}", request.getHeader(USER_AGENT));
LOGGE.info("用户访问地址: {}, 来路地址: {}", uri, IPKit.getIpAddrByRequest(request));

// 请求拦截处理
// 获取当前登录用户
UserDomain user = TaleUtils.getLoginUser(request);
if (null == user) {
if (user == null) {
Integer uid = TaleUtils.getCookieUid(request);
if (null != uid) {
// Cookie 可以伪造,因此要注意
if (uid != null) {
user = userService.getUserInfoById(uid);
request.getSession().setAttribute(WebConst.LOGIN_SESSION_KEY, user);
}
}

// 需要认证的路径,不包括静态资源和登录页面
// 权限控制
if (uri.startsWith("/admin")
&& !uri.startsWith("/admin/login")
&& null == user
&& user == null
&& !isStaticResource(uri)) {

response.sendRedirect(request.getContextPath() + "/admin/login");
return false;
}

// 设置 CSRF token,仅对敏感操作进行 CSRF 校验
// 检查权限:对于敏感操作路径(如删除),确保用户是管理员
if (isSensitiveOperation(uri) && user == null) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Unauthorized access");
return false;
}

// 设置 CSRF token,仅对敏感操作进行校验
if ("GET".equalsIgnoreCase(request.getMethod())) {
String csrfToken = UUID.UU64();
// 默认存储30分钟
cache.hset(Types.CSRF_TOKEN.getType(), csrfToken, uri, 30 * 60);
request.setAttribute("_csrf_token", csrfToken);
} else if ("POST".equalsIgnoreCase(request.getMethod()) && isSensitiveOperation(uri)) {
} else if ("POST".equalsIgnoreCase(request.getMethod()) && isSensitiveOperation(uri) && user == null) {
// 检查 POST 请求的 CSRF token
String csrfToken = request.getParameter("_csrf_token");
String expectedUri = cache.hget(Types.CSRF_TOKEN.getType(), csrfToken);
if (expectedUri == null || !expectedUri.equals(uri)) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "CSRF token invalid or expired.");
return false;
}
cache.hdel(Types.CSRF_TOKEN.getType(), csrfToken); // Token 仅使用一次
cache.hdel(Types.CSRF_TOKEN.getType(), csrfToken);
}

return true;
Expand All @@ -113,6 +117,7 @@ private boolean isSensitiveOperation(String uri) {




@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
OptionsDomain ov = optionService.getOptionByName("site_record");
Expand Down
Loading