无法解决日志伪造Fortify问题

8

我在修复Fortify中的日志伪造问题时遇到了困难。问题是“将未经验证的用户输入写入日志”,这个问题来自于getLongFromTimestamp()方法中的两个日志调用。

public long getLongFromTimestamp(final String value) {
    LOGGER.info("getLongFromTimestamp(" + cleanLogString(value) + ")");

    long longVal = 0;
    Date tempDate = null;
    try {            
        tempDate = new SimpleDateFormat(FORMAT_YYYYMMDDHHMMSS, Locale.US).parse(value);
    } catch (ParseException e) {
        LOGGER.warn("Failed to convert to Date: " + cleanLogString(value) + " Exception: " + cleanLogString(e.getMessage()));
        throw new Exception(e);
    }

    if (tempDate != null) {
        longVal = tempDate.getTime();
    }
    return longVal;
}

private cleanLogString(String logString) {
    String clean = logString.replaceAll("[^A-Za-z0-9]", "");

    if(!logString.equals(clean)) {
        clean += " (CLEANED)";
    }

    return clean;
}

cleanLogString()方法已经解决了我项目中的其他日志注入Fortify问题,但对上述两个问题没有影响。

非常感谢您的帮助!


ParseExceptions 可以包含作为 getMessage 返回字符串的一部分的值,因此我怀疑在 getMessage 返回的值上调用 cleanLogString 将修复其中一个问题。另一个问题发生在 LOGGER.info 调用上? - Neil Smithline
@Neil Smithline 感谢您的回复,但是添加 cleanLogString(e.getMessage()) 并没有解决 LOGGER.warn() 语句的问题。我已经将这个更改添加到问题中,以免引起其他混淆。而且,另一个问题确实与 LOGGER.info 语句有关。 - Brian Redd
我的下一个猜测是Fortify没有识别cleanLogString函数作为清理污染数据的函数。我不确定为什么在某些地方它会识别它而在其他地方则不会。你是否在某个地方有自定义规则? - Neil Smithline
@NeilSmithline,很遗憾我没有访问Fortify规则的权限。我的主管告诉我这些规则仍在不断完善中。一旦规则更加稳定,我会尽力深入了解。感谢您的建议。 - Brian Redd
Fortify有一些误报,如果没有自定义规则是无法消除的。你能否将它们标记为“不是问题”并忽略它们? - Neil Smithline
那是一个选项,但这将是我的领导需要做出的决定。 - Brian Redd
4个回答

4

可以使用 fortify Java 注释告诉 Fortify 数据从清理函数返回时是安全的。

在查看我的日志锻造问题时,我通过 Web API 接收字符串,因此在我的字符串上有 XSSWEB 标志。我试图找到只能删除这些标志的注释,但找不到任何去除 WEB 标志的方法。我所找到的唯一文档是 Samples/advanced/javaAnnotation 目录。

由于我的清理方法确实对字符串进行了清理,因此我选择删除所有标志。然而这可能会隐藏隐私侵犯问题。

@FortifyValidate("return")
private String sanitizeString(String taintedString) {
    return doSomethingWithTheString(taintedString);
}

4
@FortifyValidate 注解在哪个库中可用? - Paramesh Korrakuti
2
它作为一个JAR文件出现在Fortify安装目录中。 - edi_allen

2

最初当这个问题被提出时,我们的团队使用的是log4j v1.2.8版本。然而,我们注意到在升级到log4j v2.6.2版本后,所有的日志伪造问题都消失了。

一旦log4j版本升级,Fortify日志伪造问题就会消失。上面提到的cleanLogString()方法也是不必要的。例如:

LOGGER.info("getLongFromTimestamp(" + value + ")");

1
我知道我的应用程序的复杂性会阻止任何恶意输入按预期工作;但Fortify认为这并不安全。我打赌你也遇到了同样的问题。
你正在剥离日志消息中的任何真正有用的字符,但如果在写入日志之前对输出进行一些编码,看看会发生什么。

http://www.jtmelton.com/2010/09/21/preventing-log-forging-in-java/

// ensure no CRLF injection into logs for forging records
String clean = message.replace( '\n', '_' ).replace( '\r', '_' );
if ( ESAPI.securityConfiguration().getLogEncodingRequired() ) {
    clean = ESAPI.encoder().encodeForHTML(message);
    if (!message.equals(clean)) {
        clean += " (Encoded)";
    }
}

嘿,感谢@DaveC的回答,但不幸的是,我们的团队正在使用Artifactory来管理我们的maven依赖项,而ESAPI jar未经授权,无法使用。如果我们能够获得访问权限,我会告诉您它的工作情况。 - Brian Redd

-6

使用reflecttry-catch。 绕过Fortify很容易。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接