关于漏洞"这个页面包含一个错误/警告信息,可能会导致敏感信息泄露"

公司开发的产品.在用软件扫描漏洞时,扫出了这么一个漏洞.

关于漏洞

可以看出有漏洞的地方是登录页面.在登录中,主要逻辑如下: 一些拒绝登录是通过抛异常->然后捕获异常->获取异常信息->跳回到登录页面并展示错误信息. 下面为代码示例

@RequstMapping("login")
public String login(LoginForm loginForm){
    try{
        myService.doLogin(loginForm);
    }catch(Exception e){
        request.setAttribute("errorMessage", e.getMessage());//把错误信息提示给用户
        return "login";
    }
    return "index";//成功登录进入主页
}

public void doLogin(LoginForm loginForm)){
    if(...){
        throw new BusiException("账号被挂起,暂不能登录。");
    }
    if(...){
        throw new BusiException("账号或密码错误");
    }
     
}

感觉异常都可以被正常捕获, 并把错误信息正常提示给用户.

找了很久都不知道是哪里出问题, 看了扫描报告的解决方案: 使用通用页面, 屏蔽掉具体的错误信息. 就开始考虑是不是有的异常没处理好, 导致把异常的英文内容直接返回到页面去了.

最后在看代码的时候发现, 登录的时候涉及到内容的加密和解密. 如果登录时用非常规手段传了一串非法的字符串进行登录.在解密的时候可能会出现一些异常,如索引越界,这样就会把异常的英文内容直接提示给页面了. 以下为解密的代码.

private static byte[] decrypt(byte[] byteArray) {
        try {
            Provider provider = new org.bouncycastle.jce.provider.BouncyCastleProvider();
            Security.addProvider(provider);
            //Cipher: 提供加密和解密功能的实例
            //transformation: "algorithm/mode/padding"
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", provider);
            PrivateKey privateKey = keyPair.getPrivate();
            //初始化
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] plainText = cipher.doFinal(byteArray);
            return plainText;
        } catch(Exception e) {
            throw new MyDecryptException(e); //解密中发生的其他异常,此处没处理,直接抛到上一层
        }
    }

故在登录接口中处理异常的时候, 要根据不同的异常进行处理. 业务的异常, 如密码错误,账户冻结等, 就按业务异常提示.其他意外的错误, 则统一给提示语, 屏蔽掉异常的英文内容

@RequstMapping("login")
public String login(LoginForm loginForm){
    try{
        myService.doLogin(loginForm);
    }catch(BusiException e){
        //业务异常
        request.setAttribute("errorMessage", e.getMessage());//把错误信息提示给用户
        return "login";
    }catch(Exception e){
        //其他的意外异常
        request.setAttribute("errorMessage", "你是sb吗,乱来?");
        return "login";
    }
    return "index";//成功登录进入主页
}

当然这里也可以改解密方法decrypt(), 捕获异常后给个提示语再抛到上一层, 但是由于在这个应用中decrypt()方法是一个通用方法, 直接抛异常也方便开发在调用这个方法的时候做排查. 估这里选择改Controller中对异常的处理方式

处理后,再次扫描,通过了.

另外,对于这种异常处理, 最好做AOP统一处理, 如ControllerAdvice.

本文到此结束

你可能感兴趣的:(关于漏洞"这个页面包含一个错误/警告信息,可能会导致敏感信息泄露")