系统的报错信息过于详细,导致系统的版本、数据库字段等信息泄露。攻击者可通过报错页面的详细信息,收集系统中间件的版本信息、数据库字段等信息,从而进行下一步的攻击。为解决该问题,根据项目中存在的编码规范(jax-rs:runtime使用的resteasy和springboot),采用对应的全局异常处理方案;
1)Springboot
(1)系统异常处理:InterfaceExceptionHandler.java
package com.chinacreator.c2.handler;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.chinacreator.c2.common.util.ResponseResult;
import lombok.extern.slf4j.Slf4j;
/**
* 自定义异常处理器 springboot
*
* @author
*/
@ControllerAdvice
@Slf4j
public class InterfaceExceptionHandler {
/**
* 系统异常捕获处理
*/
@ResponseBody
@ExceptionHandler(value = Exception.class)
public ResponseResult exceptionHandler(Exception e) {
log.error("自定义异常处理:" + e.getMessage(), e);
e.printStackTrace();
// 设置跳转路径
return new ResponseResult(30004, e.getMessage());
}
}
(2)客户端异常处理:HttpErrorController.java
package com.chinacreator.c2.handler;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.chinacreator.c2.common.util.ResponseResult;
import lombok.extern.slf4j.Slf4j;
/**
* HttpErrorController
* @author
*
*/
@Slf4j
@RestController
public class HttpErrorController extends AbstractErrorController {
public HttpErrorController(ErrorAttributes errorAttributes) {
super(errorAttributes);
}
private final static String ERROR_PATH = "/error";
@ResponseBody
@RequestMapping(path = ERROR_PATH )
public ResponseResult error(HttpServletRequest request, HttpServletResponse response){
log.info("访问/error" + " 错误代码:" + response.getStatus());
Map<String, Object> attributes = getErrorAttributes(request, true);
//获取日志需要的请求url和详细堆栈错误信息
String path = attributes.get("path").toString();
String trace = attributes.get("trace").toString();
log.error("path:{} trace:{}",path, trace);
//获取错误时间、状态码和错误描述信息,返回给用户
Date timestamp = (Date) attributes.get("timestamp");
Integer status = (Integer) attributes.get("status");
String message = attributes.get("message").toString();
//String error = attributes.get("error").toString();
return new ResponseResult(status, message + "/" + timestamp, path);
}
@Override
public String getErrorPath() {
return ERROR_PATH;
}
}
2)jax-rs
(1)系统异常处理:ExceptionHandler.java
package com.chinacreator.c2.handler;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.springframework.stereotype.Controller;
import lombok.extern.slf4j.Slf4j;
/**
* 自定义异常处理 resteasy
* @author
*
*/
@Slf4j
@Provider
@Controller
public class ExceptionHandler implements ExceptionMapper<Exception> {
@Override
public Response toResponse(Exception e) {
// TODO Auto-generated method stub
log.error("resteasy自定义Exception 异常处理:" + e.getMessage(), e);
return Response.status(Status.INTERNAL_SERVER_ERROR)
.entity("An error has occurred").type(MediaType.TEXT_PLAIN)
.build();
}
}
(2)客户端异常处理:BadRequestHandler.java
package com.chinacreator.c2.handler;
import javax.ws.rs.ClientErrorException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
import org.springframework.stereotype.Controller;
import lombok.extern.slf4j.Slf4j;
/**
* 自定义bad request 异常处理 resteasy
* @author
*
*/
@Slf4j
@Provider
@Controller
public class BadRequestHandler implements ExceptionMapper<ClientErrorException> {
@Override
public Response toResponse(ClientErrorException e) {
// TODO Auto-generated method stub
log.error("resteasy自定义bad request异常处理:" + e.getMessage(), e);
return Response.status(Status.BAD_REQUEST)
.entity("An error has occurred").type(MediaType.TEXT_PLAIN)
.build();
}
}