为网站添加额外的安全性
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?
设置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
防止恶意入站HTML/JS/CSS
在所有 user-supplied 字符串字段上使用 Hibernate Validator(您不需要使用 Hibernate ORM 来使用它)和 @SafeHtml
注释。
您可以在一个拦截器中验证所有请求 headers、post 参数和查询参数,以进行简单的 XSS 验证。
转义所有 user-supplied 输出数据
使用 OWASP 的 Java Encoder Project <e:forHtml value="${attr}" />
转义输出或 JSTL 的 <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
让您的 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>
如果您正在托管 user-uploaded 文件,您需要为下载链接使用不同的域(不是子域),这样恶意内容就无法破坏您的 session cookie (是的,即使是 httpOnly)
也会发生这种情况
我想添加这个答案,因为我认为这是一个简单但重要的注意事项:
就我而言,我意识到我不需要允许用户输入任何类型的关键特殊字符。我分析了情况,意识到这没有任何意义,也没有必要在我的任何网页上这样做。
因此,我不必在大约 60k 现有代码行上实现适当样式的 XSS 安全代码,我可以简单地安装一个过滤器来清除所有我不想允许的特殊字符。
就用户友好性而言,您可能会觉得这有点挑剔,但应该没问题。
所以:如果您意识到您不需要允许任何特殊字符,这些字符在可能的上下文之一(例如 JS、HTML、属性、...)中将是至关重要的, 那么你可以安全地完成很多工作,因为你处于与我 am/was in.
相同的情况
显然,如果您是从头开始工作,那么实施 Neil 提到的步骤仍然是正确的方式。
如果人们在编写所有 JS 和 JSP 东西之前就知道这些步骤,他们肯定会实施它们,可能是否需要它们并不重要。
这是我在我的项目中所做的与 hybris 安全相关的事情的列表:
首先阅读文档
以下链接包含有关 hybris 安全性的全部资源和详细信息。
XML 解析器
我们经常需要从xml导入数据。
所有 Sax 解析器都应使用以下功能:
- XMLConstants.FEATURE_SECURE_PROCESSING = 真
- http://xml.org/sax/features/external-general-entities = 假
- http://xml.org/sax/features/external-parameter-entities = 假
- http://apache.org/xml/features/disallow-doctype-decl = 真
它允许
- 指示实现安全地处理 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
我是 运行 一个 Java Spring 基于 MVC 的 Web 应用程序。它还基于 Hybris 平台。
现在,身份验证和授权方面的基本功能已经实现。这意味着我们确实有会话过滤器、有效的用户系统等。
但是,我们目前没有针对 XSS 和其他可能存在的攻击类型的安全措施。 XSS 可能是最大的问题,因为它是最常见的攻击方式。
现在,我想知道...采取哪些步骤比较明智? 我环顾四周,发现存在 XSS-Filter 之类的东西。 实现这样非常简单,只需复制源代码并将其添加为 tomcats web.xml.
但我想知道这种过滤器的安全性是否令人满意?
还有更多臃肿的解决方案,例如我可以使用 spring-security。 但是,阅读文档,我觉得这非常臃肿,其中很大一部分实现了已经实现的内容(例如,两个 A)。我觉得将它配置为我需要它完成的工作量需要做很多工作。 我错了吗?
并且:
您认为建议如何处理安全问题,例如 XSS?您是否使用适合需求的特定预定义框架,或者您的安全 "hand-made" 遵循 cheat sheet?
设置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
防止恶意入站HTML/JS/CSS
在所有 user-supplied 字符串字段上使用 Hibernate Validator(您不需要使用 Hibernate ORM 来使用它)和
@SafeHtml
注释。您可以在一个拦截器中验证所有请求 headers、post 参数和查询参数,以进行简单的 XSS 验证。
转义所有 user-supplied 输出数据
使用 OWASP 的 Java Encoder Project
<e:forHtml value="${attr}" />
转义输出或 JSTL 的<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
让您的 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>
如果您正在托管 user-uploaded 文件,您需要为下载链接使用不同的域(不是子域),这样恶意内容就无法破坏您的 session cookie (是的,即使是 httpOnly)
也会发生这种情况
我想添加这个答案,因为我认为这是一个简单但重要的注意事项:
就我而言,我意识到我不需要允许用户输入任何类型的关键特殊字符。我分析了情况,意识到这没有任何意义,也没有必要在我的任何网页上这样做。
因此,我不必在大约 60k 现有代码行上实现适当样式的 XSS 安全代码,我可以简单地安装一个过滤器来清除所有我不想允许的特殊字符。
就用户友好性而言,您可能会觉得这有点挑剔,但应该没问题。
所以:如果您意识到您不需要允许任何特殊字符,这些字符在可能的上下文之一(例如 JS、HTML、属性、...)中将是至关重要的, 那么你可以安全地完成很多工作,因为你处于与我 am/was in.
相同的情况显然,如果您是从头开始工作,那么实施 Neil 提到的步骤仍然是正确的方式。 如果人们在编写所有 JS 和 JSP 东西之前就知道这些步骤,他们肯定会实施它们,可能是否需要它们并不重要。
这是我在我的项目中所做的与 hybris 安全相关的事情的列表:
首先阅读文档
以下链接包含有关 hybris 安全性的全部资源和详细信息。
XML 解析器
我们经常需要从xml导入数据。
所有 Sax 解析器都应使用以下功能:
- XMLConstants.FEATURE_SECURE_PROCESSING = 真
- http://xml.org/sax/features/external-general-entities = 假
- http://xml.org/sax/features/external-parameter-entities = 假
- http://apache.org/xml/features/disallow-doctype-decl = 真
它允许
- 指示实现安全地处理 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