在 Web 应用程序中存储硬编码域名的最佳选择

Best option to store hardcoded domain names in web application

我有一个 Web 应用程序,我在其中使用域名引用文件名。我在哪里可以添加这些域名并从哪里调用它们。当我 运行 fortify 等工具检查安全问题和标准时,它总是警告我不要保留硬编码域名。最好的选择是什么,比如我可以在哪里存储和从 Web 应用程序端(不是数据库)检索这些主要域名?

我正在使用 visual studio 并致力于 asp.net 核心 mvc 应用程序。

下面是示例

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.common.min.css" />

其他例子

<environment exclude="Development">
        <link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
              asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
              asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />

    </environment>

首先,您可以将文件托管在自己的服务器上并使用相对路径。

如果不可行,您将需要一些系统来动态更改这些依赖项的 URL,您可以从环境变量或配置文件中获取它们?数据库是一个不错的来源。


如果您要包含来自 CDN 的文件,您应该使用 subresource integrity 来确保文件在修改后不会被加载。

我怀疑 SCA 仍会标记那些位于外部域上的漏洞,在这种情况下,如果您不打算改变这种方法,则可以审核漏洞。

在 PHP MVC 世界中,实现此目的的方法之一是通过一个包含所有外部 URI 的库 class。更容易管理,因为您知道在哪里寻找损坏的 link。此外,最好使用“//”而不是 http:// 或 https://。

class External_uri
{
  public function __construct()
  {
    parent::__construct();
  }

  public function get_external_uri($name)
  {
    $uri = [
      'bootstrap_css'     => '//ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css',
      'font_awesome_css'  => '//stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css',
      'kendo_common_css'  => '//kendo.cdn.telerik.com/2018.1.221/styles/kendo.common.min.css',
    ]

    return $uri[$name];
  }
}

并调用它:

$this->External_uri->get_external_uri('bootstrap_css');

在通过 Fortify 等工具解决安全警告时,了解警告背后的原因很重要,这样您才能正确缓解它们。

HTML 警告中的硬编码域

Fortify 对此 "Hardcoded Domain in HTML" 警告的推理是链接到外部域将危及您站点的安全,因为您链接的文件可以更改。以下来自"Fortify Taxonomy: Software Security Errors":

Abstract

Including a script from another domain means that the security of this web page is dependent on the security of the other domain.

Explanation

Including executable content from another web site is a risky proposition. It ties the security of your site to the security of the other site.

Example: Consider the following <script> tag.

<script src="http://www.example.com/js/fancyWidget.js"/>

If this tag appears on a web site other than www.example.com, then the site is dependent upon www.example.com to serve up correct and non-malicious code. If attackers can compromise www.example.com, then they can alter the contents of fancyWidget.js to subvert the security of the site. They could, for example, add code to fancyWidget.js to steal a user's confidential data.

攻击缓解

有两种方法可以解决这个问题:

  1. 将所有脚本移至您自己的域。这样您就可以控制脚本的内容。这似乎是 Fortify 的建议。
  2. 将子资源完整性 属性 用于 <script><link> 标签,如下面的 Mozilla 基金会 (MDN) 所述。这也将阻止浏览器执行已修改的远程脚本。

Subresource Integrity (SRI) is a security feature that enables browsers to verify that files they fetch (for example, from a CDN) are delivered without unexpected manipulation. It works by allowing you to provide a cryptographic hash that a fetched file must match.

SRI integrity 属性的示例如下所示,并被许多 CDN 使用。

<script src="https://example.com/example-framework.js"
    integrity="sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC"
    crossorigin="anonymous"></script>

理想情况下,Fortify 应该支持 SRI 作为一种有效的缓解技术,但如果他们不支持,它们仍会标记这些错误,您将需要手动检查并传递任何已缓解的此类警告。

最佳选择

"Best" 选项取决于您的要求。以下是一些想法:

  • 如果您是 运行 商业服务,并且需要您的站点正常运行并在您的控制之下,那么您自己提供文件可能是最佳选择,因为您不仅可以控制安全性,还可以控制可用性。关于可用性,如果您正在使用远程站点并且远程站点不可用,那么您的站点可能不再正常工作。即使您自己托管这些文件,您仍然应该使用 SRI,以防您自己的文件被泄露。
  • 如果您是 运行 非商业或小型商业站点,则可以将 CDN 与 SRI 一起使用,因为它可以让您在不需要托管文件的情况下加强安全性。缺点是如果更改或消失,您的网站可能无法正常工作。

我通常默认将文件托管在服务器本身上并像这样引用它:

<link rel="stylesheet" href="~/Content/font-awesome/4.7.0/css/font-awesome.min.css">

如果他们的网站出现故障或他们的 SSL 证书失效,这将非常方便。一些站点不使用版本控制,并且在服务器本地拥有副本可以避免新版本破坏现有代码或影响其外观。在本地添加到服务器也可以避免外部版本被恶意版本替换。