GenweiWu / Blog

个人技术能力提升
MIT License
4 stars 0 forks source link

secure安全整改 #68

Open GenweiWu opened 4 years ago

GenweiWu commented 4 years ago

Dynamic Code Evaluation: Unsafe Deserialization反序列化

>理解

下面的将字节转换为object的方法是不安全的,可能存储不安全的/序列化反序列化

public static Object deserialize(byte[] data) throws IOException, ClassNotFoundException {
ByteArrayInputStream in = new ByteArrayInputStream(data);
ObjectInputStream is = new ObjectInputStream(in);
return is.readObject();
}

>解决:使用白名单进行校验

https://www.codota.com/code/java/classes/org.apache.commons.io.serialization.ValidatingObjectInputStream org.apache.commons.io.serialization.ValidatingObjectInputStream

@Test
public void trustJavaLang() throws IOException, ClassNotFoundException {
assertSerialization(willClose(
new ValidatingObjectInputStream(inputStream)
.accept(MoreComplexObject.class, ArrayList.class, Random.class)
.accept("java.lang.*","[Ljava.lang.*")
));
}
GenweiWu commented 4 years ago

安全随机数

避免使用Random

private static String generateVerificationCode()
    {
        SecureRandom secureRandom = null; // 安全随机类
        try
        {
            secureRandom = new SecureRandom();
        }
        catch (Exception e)
        {
            logger.error("secureRandom generate failed", e);
            return null;
        }

        // 验证码数字取值范围
        String codeList = "1234567890";
        // 定义一个验证码字符串变量
        StringBuilder sRand = new StringBuilder();

        for (int i = 0; i < 6; i++)
        {
            // 随即生成一个0-9之间的整数
            int code = secureRandom.nextInt(codeList.length() - 1);
            String rand = codeList.substring(code, code + 1);
            sRand.append(rand); // 将生成的随机数拼成一个六位数验证码
        }
        return sRand.toString();
    }
GenweiWu commented 4 years ago

Cross-Site Scripting: Reflected 跨站脚本攻击

增加输出编码

    public static String escapeHtml(final String value)
    {
        if (ValidateUtil.isEmptyString(value))
        {
            LOG.warn("try to escape an empty String{}", value);
            return value;
        }

        String newValue = value;
        newValue = newValue.replaceAll("&", "&amp;");
        newValue = newValue.replaceAll("<", "&lt;");
        newValue = newValue.replaceAll(">", "&gt;");
        newValue = newValue.replaceAll("\"", "&quot;");
        newValue = newValue.replaceAll("\'", "&#39;");
        newValue = newValue.replaceAll("\\(", "&#40;");
        newValue = newValue.replaceAll("\\)", "&#41;");

        return newValue;
    }

    public static String unescapeHtml(final String value)
    {
        if (ValidateUtil.isEmptyString(value))
        {
            LOG.warn("try to escape an empty String{}", value);
            return value;
        }

        String newValue = value;
        newValue = newValue.replaceAll("&amp;", "&");
        newValue = newValue.replaceAll("&lt;", "<");
        newValue = newValue.replaceAll("&gt;", ">");
        newValue = newValue.replaceAll("&quot;", "\"");
        newValue = newValue.replaceAll("&#39;", "\'");
        newValue = newValue.replaceAll("&#40;", "\\(");
        newValue = newValue.replaceAll("&#41;", "\\)");

        return newValue;
    }

供参考(未实施过):增加校验

String safe = ESAPI.encoder().encodeForHTML( request.getParameter( "input" ) );
<!-- https://mvnrepository.com/artifact/org.owasp.esapi/esapi -->
<dependency>
    <groupId>org.owasp.esapi</groupId>
    <artifactId>esapi</artifactId>
    <version>2.1.0.1</version>
</dependency>