mirror of
https://github.com/dataease/dataease.git
synced 2026-05-18 09:48:10 +08:00
fix: 潜在越权漏洞
This commit is contained in:
@@ -2,13 +2,19 @@ package io.dataease.auth.filter;
|
||||
|
||||
import io.dataease.auth.bo.TokenUserBO;
|
||||
import io.dataease.constant.AuthConstant;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.result.ResultMessage;
|
||||
import io.dataease.utils.*;
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.HttpStatusCode;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
|
||||
public class TokenFilter implements Filter {
|
||||
@@ -35,32 +41,52 @@ public class TokenFilter implements Filter {
|
||||
}
|
||||
String requestURI = request.getRequestURI();
|
||||
|
||||
if (ModelUtils.isDesktop()) {
|
||||
UserUtils.setDesktopUser();
|
||||
boolean match = false;
|
||||
try {
|
||||
match = WhitelistUtils.match(requestURI);
|
||||
} catch (DEException e) {
|
||||
HttpServletResponse res = (HttpServletResponse) servletResponse;
|
||||
ResultMessage resultMessage = new ResultMessage(e.getCode(), e.getMessage());
|
||||
ResponseEntity<ResultMessage> entity = new ResponseEntity<>(resultMessage, HttpStatus.UNAUTHORIZED);
|
||||
sendResponseEntity(res, entity);
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
return;
|
||||
}
|
||||
if (match) {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (ModelUtils.isDesktop()) {
|
||||
UserUtils.setDesktopUser();
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
return;
|
||||
}
|
||||
String executeVersion = null;
|
||||
if (StringUtils.isNotBlank(executeVersion = VersionUtil.getRandomVersion())) {
|
||||
Objects.requireNonNull(ServletUtils.response()).addHeader(AuthConstant.DE_EXECUTE_VERSION, executeVersion);
|
||||
}
|
||||
String linkToken = ServletUtils.getHead(AuthConstant.LINK_TOKEN_KEY);
|
||||
if (StringUtils.isNotBlank(linkToken)) {
|
||||
TokenUserBO tokenUserBO = TokenUtils.validateLinkToken(linkToken);
|
||||
UserUtils.setUserInfo(tokenUserBO);
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
return;
|
||||
}
|
||||
String token = ServletUtils.getToken();
|
||||
TokenUserBO userBO = TokenUtils.validate(token);
|
||||
UserUtils.setUserInfo(userBO);
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
} finally {
|
||||
UserUtils.removeUser();
|
||||
}
|
||||
}
|
||||
|
||||
if (WhitelistUtils.match(requestURI)) {
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
return;
|
||||
}
|
||||
|
||||
String executeVersion = null;
|
||||
if (StringUtils.isNotBlank(executeVersion = VersionUtil.getRandomVersion())) {
|
||||
Objects.requireNonNull(ServletUtils.response()).addHeader(AuthConstant.DE_EXECUTE_VERSION, executeVersion);
|
||||
}
|
||||
String linkToken = ServletUtils.getHead(AuthConstant.LINK_TOKEN_KEY);
|
||||
if (StringUtils.isNotBlank(linkToken)) {
|
||||
TokenUserBO tokenUserBO = TokenUtils.validateLinkToken(linkToken);
|
||||
UserUtils.setUserInfo(tokenUserBO);
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
return;
|
||||
}
|
||||
String token = ServletUtils.getToken();
|
||||
TokenUserBO userBO = TokenUtils.validate(token);
|
||||
UserUtils.setUserInfo(userBO);
|
||||
filterChain.doFilter(servletRequest, servletResponse);
|
||||
private void sendResponseEntity(HttpServletResponse httpResponse, ResponseEntity<ResultMessage> responseEntity) throws IOException {
|
||||
HttpStatusCode statusCode = responseEntity.getStatusCode();
|
||||
httpResponse.setStatus(statusCode.value());
|
||||
httpResponse.setCharacterEncoding(StandardCharsets.UTF_8.name());
|
||||
httpResponse.getWriter().write(Objects.requireNonNull(JsonUtil.toJSONString(responseEntity.getBody()).toString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,12 +2,18 @@ package io.dataease.exception;
|
||||
|
||||
import io.dataease.result.ResultCode;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DEException extends RuntimeException {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 8170873998824378304L;
|
||||
private int code;
|
||||
|
||||
private String msg;
|
||||
|
||||
@@ -5,6 +5,7 @@ import io.dataease.i18n.Translator;
|
||||
import io.dataease.result.ResultCode;
|
||||
import io.dataease.result.ResultMessage;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.validation.ObjectError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
@@ -14,20 +15,29 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
|
||||
/** -------- 参数校验异常 -------- **/
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResultMessage MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
|
||||
ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
|
||||
String msg = objectError.getDefaultMessage();
|
||||
msg = Translator.get(msg);
|
||||
LogUtil.error(msg);
|
||||
return new ResultMessage(ResultCode.PARAM_IS_INVALID.code(),msg);
|
||||
return new ResultMessage(ResultCode.PARAM_IS_INVALID.code(), msg);
|
||||
}
|
||||
|
||||
@ExceptionHandler(DEException.class)
|
||||
public ResultMessage deExceptionHandler(DEException e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
return new ResultMessage(e.getCode(),e.getMessage());
|
||||
return new ResultMessage(e.getCode(), e.getMessage());
|
||||
}
|
||||
|
||||
@ExceptionHandler(NullPointerException.class)
|
||||
public ResultMessage noUserExceptionHandler(Exception e) {
|
||||
String message = e.getMessage();
|
||||
LogUtil.error(message, e);
|
||||
if (StringUtils.contains(message, "Cannot invoke \"io.dataease.auth.bo.TokenUserBO.getUserId()\" because \"user\" is null")) {
|
||||
return new ResultMessage(ResultCode.USER_NOT_LOGGED_IN.code(), ResultCode.USER_NOT_LOGGED_IN.message());
|
||||
}
|
||||
return new ResultMessage(ResultCode.PARAM_IS_BLANK.code(), message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,10 @@ public class AuthUtils {
|
||||
USER_INFO.set(userBO);
|
||||
}
|
||||
|
||||
public static void remove() {
|
||||
USER_INFO.remove();
|
||||
}
|
||||
|
||||
public static boolean isSysAdmin() {
|
||||
TokenUserBO user = null;
|
||||
if (ObjectUtils.isEmpty(user = getUser())) {
|
||||
|
||||
@@ -14,4 +14,8 @@ public class UserUtils {
|
||||
bo.setDefaultOid(1L);
|
||||
AuthUtils.setUser(bo);
|
||||
}
|
||||
|
||||
public static void removeUser() {
|
||||
AuthUtils.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import org.springframework.core.env.Environment;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static io.dataease.result.ResultCode.INTERFACE_ADDRESS_INVALID;
|
||||
|
||||
public class WhitelistUtils {
|
||||
|
||||
private static String contextPath;
|
||||
@@ -50,9 +52,7 @@ public class WhitelistUtils {
|
||||
"/");
|
||||
|
||||
public static boolean match(String requestURI) {
|
||||
if (requestURI.contains(";") && !requestURI.contains("?")) {
|
||||
DEException.throwException("Invalid uri: " + requestURI);
|
||||
}
|
||||
invalidUrl(requestURI);
|
||||
if (StringUtils.startsWith(requestURI, getContextPath())) {
|
||||
requestURI = requestURI.replaceFirst(getContextPath(), "");
|
||||
}
|
||||
@@ -100,4 +100,10 @@ public class WhitelistUtils {
|
||||
}
|
||||
return redirect_uri + AuthConstant.DE_API_PREFIX + "/";
|
||||
}
|
||||
|
||||
private static void invalidUrl(String requestURI) {
|
||||
if (requestURI.contains("./") || (requestURI.contains(";") && !requestURI.contains("?"))) {
|
||||
DEException.throwException(INTERFACE_ADDRESS_INVALID.code(), String.format("%s [%s]", INTERFACE_ADDRESS_INVALID.message(), requestURI));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user