为网站添加额外的安全性

Adding additonal Security to Website

我是 运行 一个 Java Spring 基于 MVC 的 Web 应用程序。它还基于 Hybris 平台。

现在,身份验证和授权方面的基本功能已经实现。这意味着我们确实有会话过滤器、有效的用户系统等。

但是,我们目前没有针对 XSS 和其他可能存在的攻击类型的安全措施。 XSS 可能是最大的问题,因为它是最常见的攻击方式。

现在,我想知道...采取哪些步骤比较明智? 我环顾四周,发现存在 XSS-Filter 之类的东西。 实现这样非常简单,只需复制源代码并将其添加为 tomcats web.xml.

但我想知道这种过滤器的安全性是否令人满意?

还有更多臃肿的解决方案,例如我可以使用 spring-security。 但是,阅读文档,我觉得这非常臃肿,其中很大一部分实现了已经实现的内容(例如,两个 A)。我觉得将它配置为我需要它完成的工作量需要做很多工作。 我错了吗?

并且:

您认为建议如何处理安全问题,例如 XSS?您是否使用适合需求的特定预定义框架,或者您的安全 "hand-made" 遵循 cheat sheet?

  1. 设置Anti-XSSHeaders(提示:使用Spring安全性或自己制作Interceptor

    Content-Security-Policy: default-src 'self'   --only allow content from your own site
    
    X-XSS-Protection: 1; mode=block   --prevent some reflective attacks in some browsers
    
    X-Content-Type-Options: nosniff   --can't trick browser into detecting and running js in other content types
    
  2. 防止恶意入站HTML/JS/CSS

    在所有 user-supplied 字符串字段上使用 Hibernate Validator(您不需要使用 Hibernate ORM 来使用它)和 @SafeHtml 注释。

    您可以在一个拦截器中验证所有请求 headers、post 参数和查询参数,以进行简单的 XSS 验证。

  3. 转义所有 user-supplied 输出数据

    使用 OWASP 的 Java Encoder Project <e:forHtml value="${attr}" /> 转义输出或 JS​​TL 的 <c:out value="${attr}"/> 并在 web.xml 中设置

    <context-param>
        <param-name>defaultHtmlEscape</param-name>
        <param-value>true</param-value>
    </context-param>
    

    如果转义 HTML 节点文本,它们同样安全,但 OWASP 对于 HTML 属性或 <script> 转义更安全。

    如果要编辑的文件太多,请考虑 http://pukkaone.github.io/2011/01/03/jsp-cross-site-scripting-elresolver.html

  4. 让您的 session cookie 无法被 JavaScript 读取。在 web.xml:

    <session-config>
        <cookie-config>
            <!-- browser will disallow JavaScript access to session cookie -->
            <http-only>true</http-only>
        </cookie-config>
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>
    
  5. 如果您正在托管 user-uploaded 文件,您需要为下载链接使用不同的域(不是子域),这样恶意内容就无法破坏您的 session cookie (是的,即使是 httpOnly)

  6. 也会发生这种情况

我想添加这个答案,因为我认为这是一个简单但重要的注意事项:

就我而言,我意识到我不需要允许用户输入任何类型的关键特殊字符。我分析了情况,意识到这没有任何意义,也没有必要在我的任何网页上这样做。

因此,我不必在大约 60k 现有代码行上实现适当样式的 XSS 安全代码,我可以简单地安装一个过滤器来清除所有我不想允许的特殊字符。

就用户友好性而言,您可能会觉得这有点挑剔,但应该没问题。

所以:如果您意识到您不需要允许任何特殊字符,这些字符在可能的上下文之一(例如 JS、HTML、属性、...)中将是至关重要的, 那么你可以安全地完成很多工作,因为你处于与我 am/was in.

相同的情况

显然,如果您是从头开始工作,那么实施 Neil 提到的步骤仍然是正确的方式。 如果人们在编写所有 JS 和 JSP 东西之前就知道这些步骤,他们肯定会实施它们,可能是否需要它们并不重要。

这是我在我的项目中所做的与 hybris 安全相关的事情的列表:

首先阅读文档

以下链接包含有关 hybris 安全性的全部资源和详细信息。

XML 解析器

我们经常需要从xml导入数据。

所有 Sax 解析器都应使用以下功能:

它允许

  • 指示实现安全地处理 XML。这可能会对 XML 构造设置限制以避免诸如拒绝 服务攻击。
  • 不包括外部一般实体。
  • 不包括外部参数实体或外部 DTD 子集
  • 如果传入文档包含 DOCTYPE 声明,则抛出致命错误

JSON

必须使用 OWASP 库 json-sanitizer 验证所有输入。参见 https://www.owasp.org/index.php/OWASP_JSON_Sanitizer

示例:

String wellFormedJson = JsonSanitizer.sanitize(jsonData);
try
{
    return new ObjectMapper().readValue(wellFormedJson, JsonNode.class).toString();
}
catch (final IOException ex)
{
     LOG.error("Incorrect json data : " + wellFormedJson, ex);
}

日志

不得直接记录来自应用程序外部的字符串,以防止日志注入。

手柄壳

在网络上下文中,所有控制器都必须扩展 BaseController。此 class 包含方法 logParam,应该用于记录未知内容。

此方法使用YSanitizer.sanitize(input).

public class YSanitizer
{
    public static String sanitize(final String input) {
        String output = StringUtils.defaultString(input).trim();
        output = output.replaceAll("(\r\n|\r|\n)+", " ");
        output = StringEscapeUtils.escapeHtml(output);
        return output;
    }
}

其他情况

调用StringEscapeUtils.escapeJava(valToLog)应该就够了。

保护敏感数据免受堆检查

因为可以检查堆,敏感数据不应存储在 String 个对象中。

的确,字符串是不可变的,可以在堆中保留一段时间。

为防止出现此问题,所有敏感字符串都必须存储在 char[].

该数组应尽快用“0”填充(当不需要该值时)。

并不是说此方法不是 100% 安全,而是减少了 window 在堆中查找密码的时间。

跨站点脚本 (XSS)

确保 de.hybris.platform.servicelayer.web.XSSFilter 在传入请求的过滤器列表中

部署检查(from Go-Live Checklist

  • 验证是否已更改所有用户的默认密码
  • 更改生产管理员用户密码
  • 禁用自动登录或预填充密码
    • 产品驾驶舱
    • CMS 主控室
    • CS驾驶舱
    • hMC
  • 密码编码应为 MD5 或更好的 SHA256
  • 更改默认密码编码器
  • 更改 MD5 和 SHA256 密码编码器的 SALT
  • 验证数据库密码以及将它们以纯文本形式存储在 local.properties 中的要求。
  • 确认用户帐户和结帐页面只能通过安全的 SSL 连接访问
  • 检查是否安装了 Web 应用程序防火墙
  • 执行代码审查以确保没有敏感数据(如信用卡信息或密码)记录到日志文件
  • 验证 hybris 应用程序服务器不是 运行 root
  • 保护连接的 JMX