安全框架:通信安全 | 缓解措施

产品/服务 文章
Azure 事件中心
Dynamics CRM
Azure 数据工厂
标识服务器
Web 应用程序
Database
Azure 存储
移动客户端
WCF
Web API
用于 Redis 的 Azure 缓存
IoT 现场网关
IoT 云网关

使用 SSL/TLS 保护与事件中心之间的通信

标题 详细信息
组件 Azure 事件中心
SDL 阶段 构建
适用的技术 泛型
属性 空值
参考 事件中心身份验证和安全模型概述
步骤 使用 SSL/TLS 来保护与事件中心的 AMQP 或 HTTP 连接

检查服务帐户特权,并检查自定义服务或 ASP.NET 页面是否遵循 CRM 的安全性

标题 详细信息
组件 Dynamics CRM
SDL 阶段 构建
适用的技术 泛型
属性 空值
参考 空值
步骤 检查服务帐户特权,并检查自定义服务或 ASP.NET 页面是否遵循 CRM 的安全性

将本地 SQL Server 连接到 Azure 数据工厂时使用数据管理网关

标题 详细信息
组件 Azure 数据工厂
SDL 阶段 部署
适用的技术 泛型
属性 链接服务类型 - Azure 和本地
参考 在本地与 Azure 数据工厂之间移动数据
步骤

需要使用数据管理网关 (DMG) 工具连接到受企业网络或防火墙保护的数据源。

  1. 锁定计算机可以隔离 DMG 工具,防止不正常的程序损坏源计算机或者窥视其数据。 (例如,必须安装最新的更新、启用所需的最少量端口、预配受控帐户、审核启用、启用磁盘加密,等等。)
  2. 必须经常或者每当 DMG 服务帐户密码续订时轮替数据网关密钥
  3. 通过链接服务传输的数据必须加密

确保发往标识服务器的所有流量都通过 HTTPS 连接传输

标题 详细信息
组件 标识服务器
SDL 阶段 部署
适用的技术 泛型
属性 空值
参考 IdentityServer3 - 密钥、签名和加密IdentityServer3 - 部署
步骤 默认情况下,IdentityServer 要求所有传入连接都通过 HTTPS 建立。 只能通过受保护的传输来与 IdentityServer 通信,是一项绝对需要遵守的要求。 在某些部署方案(例如 TLS 卸载)中,可以放宽此项要求。 有关详细信息,请参阅“参考”部分中的标识服务器部署页。

验证用于对 SSL、TLS 和 DTLS 连接进行身份验证的 X.509 证书

标题 详细信息
组件 Web 应用程序
SDL 阶段 构建
适用的技术 泛型
属性 空值
参考 空值
步骤

使用 SSL、TLS 或 DTLS 的应用程序必须全面验证它们所要连接到的实体的 X.509 证书。 这包括验证证书的以下信息:

  • 域名
  • 生效日期(开始日期和过期日期)
  • 吊销状态
  • 用途(例如,对服务器进行服务器身份验证,对客户端进行客户端身份验证)
  • 信任链。 证书必须链接到平台信任的或者由管理员显式配置的根证书颁发机构 (CA)
  • 证书公钥的密钥长度必须 >2048 位
  • 哈希算法必须是 SHA256 和更高级别

在 Azure 应用服务中为自定义域配置 TLS/SSL 证书

标题 详细信息
组件 Web 应用程序
SDL 阶段 构建
适用的技术 泛型
属性 EnvironmentType - Azure
参考 为 Azure 应用服务中的应用启用 HTTPS
步骤 默认情况下,Azure 已使用 *.chinacloudsites.cn 域的通配符证书为每个应用启用了 HTTPS。 但是,就像所有通配符域一样,这不如将自定义域与自己的证书配合使用那么安全。参考 建议针对通过其访问所部署应用的自定义域启用 TLS

强制要求发往 Azure 应用服务的所有流量都通过 HTTPS 连接传输

标题 详细信息
组件 Web 应用程序
SDL 阶段 构建
适用的技术 泛型
属性 EnvironmentType - Azure
参考 对 Azure 应用服务强制执行 HTTPS
步骤

尽管 Azure 已使用 *.chinacloudsites.cn 域的通配符证书为 Azure 应用服务启用了 HTTPS,但它并不强制实施 HTTPS。 访问者仍可使用 HTTP 访问应用,这可能会损害应用的安全性,因此必须显式强制 HTTPS。 ASP.NET MVC 应用程序应使用 RequireHttps 筛选器,强制要求通过 HTTPS 重新发送不安全的 HTTP 请求。

或者,可以使用 Azure 应用服务随附的 URL 重写模块来强制 HTTPS。 开发人员可以使用 URL 重写模块来定义将请求传递给应用程序之前应用到传入请求的规则。 URL 重写规则在 web.config 文件中定义,该文件存储在应用程序根目录中。

示例

以下示例包含可强制所有传入流量使用 HTTPS 的基本 URL 重写规则

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule name="Force HTTPS" enabled="true">
          <match url="(.*)" ignoreCase="false" />
          <conditions>
            <add input="{HTTPS}" pattern="off" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}/{R:1}" appendQueryString="true" redirectType="Permanent" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

此规则的工作方式是当用户使用 HTTP 请求某个页面时,返回 HTTP 状态码 301(永久重定向)。 301 将请求重定向到访问者请求的同一个 URL,但使用 HTTPS 来替换请求的 HTTP 部分。 例如,HTTP://contoso.com 会重定向到 HTTPS://contoso.com

启用 HTTP 严格传输安全性 (HSTS)

标题 详细信息
组件 Web 应用程序
SDL 阶段 构建
适用的技术 泛型
属性 空值
参考 OWASP HTTP 严格传输安全性速查表
步骤

HTTP 严格传输安全性 (HSTS) 是 Web 应用程序使用特殊响应标头指定的一个选用的安全增强功能。 支持的浏览器收到此标头后,将阻止通过 HTTP 将任何通信发送到指定的域,并改为通过 HTTPS 发送所有通信。 它还可以防止浏览器中出现 HTTPS 点击提示。

若要实现 HSTS,必须在代码或配置中为网站全局配置以下响应标头。Strict-Transport-Security: max-age=300; includeSubDomains。HSTS 可解决以下威胁:

  • 用户将 https://example.com 加入书签或手动键入时容易受到中间人攻击者的攻击:HSTS 会自动将 HTTP 请求重定向到目标域的 HTTPS
  • 纯粹只进行 HTTPS 通信的 Web 应用程序无意中包含 HTTP 链接或通过 HTTP 提供内容:HSTS 会自动将 HTTP 请求重定向到目标域的 HTTPS
  • 中间人攻击者试图使用无效的证书来截获受害用户发送的流量,并希望此用户接受错误的证书:HSTS 不允许用户替代无效的证书消息

确保加密 SQL Server 连接并验证证书

标题 详细信息
组件 数据库
SDL 阶段 构建
适用的技术 SQL Azure
属性 SQL 版本 - V12
参考 有关为 SQL 数据库编写安全连接字符串的最佳做法
步骤

SQL 数据库与客户端应用程序之间的所有通信始终使用传输层安全性(TLS,以前称为安全套接字层 (SSL))进行加密。 SQL 数据库不支持未加密的连接。 若要使用应用程序代码或工具验证证书,需显式请求一个加密的连接并且不信任服务器证书。 即使应用程序代码或工具未请求加密的连接,它们仍会收到加密的连接

但是,它们可能不会验证服务器证书,因此将容易受到“中间人”攻击。 若要使用 ADO.NET 应用程序代码验证证书,请在数据库连接字符串中设置 Encrypt=TrueTrustServerCertificate=False。 若要通过 SQL Server Management Studio 验证证书,请打开“连接到服务器”对话框。 在“连接属性”选项卡中单击“加密连接”

强制以加密形式来与 SQL Server 通信

标题 详细信息
组件 数据库
SDL 阶段 构建
适用的技术 OnPrem
属性 SQL 版本 - MsSQL2016,SQL 版本 - MsSQL2012,SQL 版本 - MsSQL2014
参考 启用数据库引擎的加密连接
步骤 启用 TLS 加密可以提高在 SQL Server 实例与应用程序之间通过网络传输的数据的安全性。

确保与 Azure 存储之间的通信通过 HTTPS 进行

标题 详细信息
组件 Azure 存储
SDL 阶段 部署
适用的技术 泛型
属性 空值
参考 Azure 存储传输级加密 - 使用 HTTPS
步骤 为了确保传输中 Azure 存储数据的安全性,请在调用 REST API 或访问存储中的对象时,始终使用 HTTPS 协议。 此外,可以使用共享访问签名,它除了可以委派对 Azure 存储对象的访问权限,还能指定在使用共享访问签名时只能使用 HTTPS 协议,确保任何使用 SAS 令牌发出链接的人都使用正确的协议。

如果无法启用 HTTPS,请在下载 Blob 后验证 MD5 哈希

标题 详细信息
组件 Azure 存储
SDL 阶段 构建
适用的技术 泛型
属性 StorageType - Blob
参考 Windows Azure Blob MD5 概述
步骤

Windows Azure Blob 服务提供相应的机制来确保应用程序和传输层的数据完整性。 如果出于任何原因需要使用 HTTP 而不是 HTTPS,并且使用的是块 Blob,则可以使用 MD5 检查,帮助验证正在传输的 Blob 的完整性。

这会有助于防止网络/传输层错误,但不一定可帮助防止中间攻击。 如果可以使用提供传输级安全的 HTTPS,则使用 MD5 检查就很多余且不必要。

使用与 SMB 3.x 兼容的客户端来确保传输到 Azure 文件共享的数据经过加密

标题 详细信息
组件 移动客户端
SDL 阶段 构建
适用的技术 泛型
属性 StorageType - 文件
参考 Azure 文件存储Windows 客户端的 Azure 文件存储 SMB 支持
步骤 使用 REST API 时,Azure 文件支持 HTTPS,但经常用作附加到 VM 的 SMB 文件共享。 SMB 2.1 不支持加密,因此只允许在 Azure 中的相同区域内连接。 但是,SMB 3.x 支持加密,并且可以配合 Windows Server 2012 R2、Windows 8、Windows 8.1 和 Windows 10 使用,允许跨区域访问,甚至桌面上的访问。

实施证书固定

标题 详细信息
组件 Azure 存储
SDL 阶段 构建
适用的技术 通用、Windows Phone
属性 空值
参考 证书和公钥绑定
步骤

证书绑定可以防范中间人 (MITM) 攻击。 绑定是将主机与其预期 X509 证书或公钥相关联的过程。 某个主机知悉或者识别到某个证书或公钥后,该证书或公钥将关联或“绑定”到该主机。

因此,当攻击者尝试展开 TLS MITM 攻击时,在 TLS 握手期间,攻击者服务器中的密钥将与绑定证书的密钥不同,因此会丢弃该请求,阻止 MITM。可以通过实现 ServicePointManager 的 ServerCertificateValidationCallback 委派来完成证书绑定。

示例

using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography;

namespace CertificatePinningExample
{
    class CertificatePinningExample
    {
        /* Note: In this example, we're hardcoding the certificate's public key and algorithm for 
           demonstration purposes. In a real-world application, this should be stored in a secure
           configuration area that can be updated as needed. */

        private static readonly string PINNED_ALGORITHM = "RSA";

        private static readonly string PINNED_PUBLIC_KEY = "3082010A0282010100B0E75B7CBE56D31658EF79B3A1" +
            "294D506A88DFCDD603F6EF15E7F5BCBDF32291EC50B2B82BA158E905FE6A83EE044A48258B07FAC3D6356AF09B2" +
            "3EDAB15D00507B70DB08DB9A20C7D1201417B3071A346D663A241061C151B6EC5B5B4ECCCDCDBEA24F051962809" +
            "FEC499BF2D093C06E3BDA7D0BB83CDC1C2C6660B8ECB2EA30A685ADE2DC83C88314010FFC7F4F0F895EDDBE5C02" +
            "ABF78E50B708E0A0EB984A9AA536BCE61A0C31DB95425C6FEE5A564B158EE7C4F0693C439AE010EF83CA8155750" +
            "09B17537C29F86071E5DD8CA50EBD8A409494F479B07574D83EDCE6F68A8F7D40447471D05BC3F5EAD7862FA748" +
            "EA3C92A60A128344B1CEF7A0B0D94E50203010001";


        public static void Main(string[] args)
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.azure.cn/");
            request.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
            {
                if (certificate == null || sslPolicyErrors != SslPolicyErrors.None)
                {
                    // Error getting certificate or the certificate failed basic validation
                    return false;
                }

                var targetKeyAlgorithm = new Oid(certificate.GetKeyAlgorithm()).FriendlyName;
                var targetPublicKey = certificate.GetPublicKeyString();
                
                if (targetKeyAlgorithm == PINNED_ALGORITHM &&
                    targetPublicKey == PINNED_PUBLIC_KEY)
                {
                    // Success, the certificate matches the pinned value.
                    return true;
                }
                // Reject, either the key or the algorithm does not match the expected value.
                return false;
            };

            try
            {
                var response = (HttpWebResponse)request.GetResponse();
                Console.WriteLine($"Success, HTTP status code: {response.StatusCode}");
            }
            catch(Exception ex)
            {
                Console.WriteLine($"Failure, {ex.Message}");
            }
            Console.WriteLine("Press any key to end.");
            Console.ReadKey();
        }
    }
}

启用 HTTPS - 安全传输通道

标题 详细信息
组件 WCF
SDL 阶段 构建
适用的技术 NET Framework 3
属性 空值
参考 MSDN巩固王国
步骤 应用程序配置应确保始终使用 HTTPS 来访问敏感信息。
  • 解释: 如果应用程序需要处理敏感信息并且没有使用消息级别加密,则只应允许它通过加密的传输通道进行通信。
  • 建议: 确保禁用 HTTP 传输,改为启用 HTTPS 传输。 例如,将 <httpTransport/> 替换为 <httpsTransport/> 标记。 不要依赖使用网络配置(防火墙)来保证只能通过安全通道访问应用程序。 从哲学的观点来讲,应用程序不应依赖于网络来保证其安全性。

从实践的观点来讲,负责保护网络的人不会一直跟进应用程序的不断变化的安全要求。

WCF:将消息安全保护级别设置为 EncryptAndSign

标题 详细信息
组件 WCF
SDL 阶段 构建
适用的技术 .NET Framework 3
属性 空值
参考 MSDN
步骤
  • 解释: 当保护级别设置为“none”时,将禁用消息保护。 保密性和完整性是使用适当的设置级别实现的。
  • 建议:
    • Mode=None 时 - 禁用消息保护
    • Mode=Sign 时 - 将消息签名但不加密;当数据完整性非常重要时应使用该设置
    • Mode=EncryptAndSign 时 - 将消息签名并加密

请考虑禁用加密,仅当只是需要验证信息的完整性而不关心机密性时,才为消息签名。 对于需要验证原始发送者但不传输任何敏感数据的操作或服务约定,这种做法可能很有用。 降低保护级别时,请注意不要在消息中包含任何个人数据。

示例

以下示例演示了如何将服务和操作配置为只将消息签名。 ProtectionLevel.Sign 服务协定示例:以下是在服务协定级别处使用 ProtectionLevel.Sign 的示例:

[ServiceContract(Protection Level=ProtectionLevel.Sign] 
public interface IService 
  { 
  string GetData(int value); 
  } 

示例

ProtectionLevel.Sign 操作协定示例(用于精细控制):以下是在 OperationContract 级别处使用 ProtectionLevel.Sign 的示例:

[OperationContract(ProtectionLevel=ProtectionLevel.Sign] 
string GetData(int value);

WCF:使用最低特权帐户运行 WCF 服务

标题 详细信息
组件 WCF
SDL 阶段 构建
适用的技术 .NET Framework 3
属性 空值
参考 MSDN
步骤
  • 解释: 不要在管理员或高特权帐户下运行 WCF 服务。 否则,如果服务遭到入侵,将导致严重影响。
  • 建议: 请使用最低特权帐户托管 WCF 服务,因为这样可以在遭到攻击时减小应用程序的攻击面,降低潜在损害。 如果服务帐户需要 MSMQ、事件日志、性能计数器和文件系统等基础结构资源的其他访问权限,应该授予对这些资源的相应权限,使 WCF 服务能够成功运行。

如果服务需要代表原始调用方访问特定的资源,请使用模拟和委派来传送调用方的标识,以便在下游进行授权检查。 在开发方案中,请使用本地网络服务帐户,这是一个特权降低的特殊内置帐户。 在生产方案中,请创建最低特权的自定义域服务帐户。

强制要求发往 Web API 的所有流量都通过 HTTPS 连接传输

标题 详细信息
组件 Web API
SDL 阶段 构建
适用的技术 MVC5、MVC6
属性 空值
参考 在 Web API 控制器中强制 SSL
步骤 如果应用程序同时使用 HTTPS 和 HTTP 绑定,则客户端仍可使用 HTTP 访问站点。 为了防止这种问题,请使用操作筛选器来确保始终通过 HTTPS 向受保护 API 传输请求。

示例

以下代码演示了一个检查 TLS 的 Web API 身份验证筛选器:

public class RequireHttpsAttribute : AuthorizationFilterAttribute
{
    public override void OnAuthorization(HttpActionContext actionContext)
    {
        if (actionContext.Request.RequestUri.Scheme != Uri.UriSchemeHttps)
        {
            actionContext.Response = new HttpResponseMessage(System.Net.HttpStatusCode.Forbidden)
            {
                ReasonPhrase = "HTTPS Required"
            };
        }
        else
        {
            base.OnAuthorization(actionContext);
        }
    }
}

将此筛选器添加到任何需要 TLS 的 Web API 操作:

public class ValuesController : ApiController
{
    [RequireHttps]
    public HttpResponseMessage Get() { ... }
}

确保与 Azure Cache for Redis 之间的通信通过 TLS 进行

标题 详细信息
组件 用于 Redis 的 Azure 缓存
SDL 阶段 构建
适用的技术 泛型
属性 空值
参考 Azure Redis TLS 支持
步骤 Redis 服务器不能现成地支持 TLS,但 Azure Cache for Redis 则可以。 如果要连接到 Azure Cache for Redis 并且客户端支持 TLS(如 StackExchange.Redis),则应使用 TLS。 默认情况下,为新的 Azure Cache for Redis 实例禁用了非 TLS 端口。 请确保安全的默认设置不会更改,除非 Redis 客户端依赖 TLS 支持。

请注意,Redis 旨在由受信任环境中的受信任客户端访问。 这意味着,我们通常不建议将 Redis 实例直接在 Internet 中公开,一般情况下,在不受信任的客户端可以直接访问 Redis TCP 端口或 UNIX 套接字的环境中,也不建议公开 Redis 实例。

保护设备与现场网关之间的通信

标题 详细信息
组件 IoT 现场网关
SDL 阶段 构建
适用的技术 泛型
属性 空值
参考 空值
步骤 对于基于 IP 的设备,通常可将通信协议封装在 SSL/TLS 通道中,以保护传输中的数据。 对于其他不支持 SSL/TLS 的协议,请调查是否有安全的协议版本可在传输或消息层提供安全性。

使用 SSL/TLS 保护设备与云网关之间的通信

标题 详细信息
组件 IoT 云网关
SDL 阶段 构建
适用的技术 泛型
属性 空值
参考 选择通信协议
步骤 使用 SSL/TLS 保护 HTTP/AMQP 或 MQTT 协议。