Microsoft 安全咨询3137909

ASP.NET 模板中的漏洞可能导致篡改

发布时间: 2016 年 2 月 9 日 |更新时间:2016 年 2 月 10 日

版本: 1.1

执行摘要

Microsoft 正在发布此安全公告,提供有关 Visual Studio 2013、Visual Studio 2015、ASP.NET MVC5 和 ASP.NET MVC6 公共版本中漏洞的信息。 此公告还提供了有关开发人员可以执行的操作的指导,以帮助确保生成的控件和组件不受漏洞的影响。

Microsoft 知道 Visual Studio 2013 和 Visual Studio 2015 的公共版本中的安全漏洞,该漏洞可用于跨站点请求伪造(CSRF)攻击方案,针对使用受影响的 ASP.NET 项目模板生成的 Web 应用程序。 Microsoft ASP.NET MVC5 和 ASP.NET MVC6 项目模板由软件开发人员用作新 Web 应用程序的初学者模板。

缓解因素

  • 默认情况下,任何生成的应用程序中都未启用双因素身份验证(2FA)。 如果开发人员未根据用户的电话号码启用 2FA,则删除电话号码时不会对安全性造成影响。

咨询常见问题解答

攻击者如何利用漏洞?
攻击者可以使用跨站点请求伪造(CSRF)向使用易受攻击的模板生成的 Web 应用程序发送请求,然后从 ASP.NET 标识数据库中删除经过身份验证的用户电话号码。 被利用的漏洞的结果消除了依赖于电话号码的任何双因素身份验证(2FA)机制。 用户的密码不受影响。

更新的作用是什么?
此更新更正了 MVC5 和 MVC6 的 Visual Studio 2015 ASP.NET 项目模板。

模板更新仅影响新应用程序。 出于此原因,Microsoft 强烈建议使用这些模板构建 Web 应用程序的开发人员立即采取行动,在 “建议的操作 ”部分列出,以评估其 Web 应用程序是否暴露在漏洞中,然后使用该部分中的解决方法进行代码更改,以更新其应用程序,使其免受易受攻击的攻击。

如果运行的是 Visual Studio 2013,则需要使用“建议的操作”部分中列出的解决方法步骤,以便每次使用受影响的模板时手动更新应用程序。

如何实现应用更新?

  1. 启动 Visual Studio。
  2. “工具”菜单下,选择“扩展”和“汇报”。
  3. 展开汇报树。
  4. “产品汇报下找到以下两个条目:
    • Microsoft ASP.NET 和 Web 工具
    • Microsoft ASP.NET Web 框架和工具
  5. 选择每个更新,然后单击“ 更新”。

建议的操作

以下解决方法信息详细介绍了必须对从 ASP.NET 项目模板创建的现有应用程序所做的更改。

Visual Studio 2015 MVC 5 和 Visual Studio 2013 MVC 5
对于 C#

  1. 从控制器目录中加载ManageController.cs。

  2. 搜索 Remove电话Number() (第 199 行)。

  3. 模板代码不带任何自定义项,如下所示:

     public async Task<actionresult> RemovePhoneNumber()
     {
         var result = await UserManager.SetPhoneNumberAsync(User.Identity.GetUserId(), null);
         if (!result.Succeeded)
         {
             return RedirectToAction("Index", new { Message = ManageMessageId.Error });
         }
         var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
         if (user != null)
         {
             await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
         }
         return RedirectToAction("Index", new { Message = ManageMessageId.RemovePhoneSuccess });
     }
    
  4. [HttpPost][ValidateAntiForgeryToken] 属性添加到函数定义中,使代码如下所示:

     [HttpPost]
     [ValidateAntiForgeryToken]
     public async Task</actionresult><actionresult> RemovePhoneNumber()
     {
         var result = await UserManager.SetPhoneNumberAsync(User.Identity.GetUserId(), null);
         if (!result.Succeeded)
         {
             return RedirectToAction("Index", new { Message = ManageMessageId.Error });
         }
         var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
         if (user != null)
         {
             await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
         }
         return RedirectToAction("Index", new { Message = ManageMessageId.RemovePhoneSuccess });
     }
    
  5. 从 Views/Manage 文件夹中加载 Index.cshtml 文件。

  6. 搜索 <dt>电话 Number:</dt> (第 40 行)

  7. 模板代码,不显示任何自定义项,如下所示:

     <dt>Phone Number:</dt>
    
@(模型。电话Number ??“None”) [ @if (Model.电话Number != null) { @Html.ActionLink(“Change”, “Add电话Number”) @:  |  @Html.ActionLink(“Remove”, “Remove电话Number”) } else { @Html.ActionLink(“Add”, “Add电话Number”) } ]
```
  1. 更改视图代码,如下所示:

     <dt>Phone Number:</dt>
    
@(模型。电话Number ??“None”) @if (Model.电话Number != null) {
using (Html.BeginForm(“Remove电话Number”, “Manage”, FormMethod.Post, new { @class = “form-horizontal”, role = “form” })) { @Html.AntiForgeryToken() } } else { }
```
  1. 重新编译应用程序,然后重新部署它。

对于 Visual Basic

  1. 从控制器目录中加载ManageController.cs。

  2. 搜索 Remove电话Number() (第 164 行)。

  3. 模板代码,不显示任何自定义项,如下所示:

         Public Async Function RemovePhoneNumber() As Task(Of ActionResult)
             Dim result = Await UserManager.SetPhoneNumberAsync(User.Identity.GetUserId(), Nothing)
             If Not result.Succeeded Then
                 Return RedirectToAction("Index", New With {
                     .Message = ManageMessageId.[Error]
                 })
             End If
             Dim userInfo = Await UserManager.FindByIdAsync(User.Identity.GetUserId())
             If userInfo IsNot Nothing Then
                 Await SignInManager.SignInAsync(userInfo, isPersistent:=False, rememberBrowser:=False)
             End If
             Return RedirectToAction("Index", New With {
                 .Message = ManageMessageId.RemovePhoneSuccess
             })
         End Function
    
  4. HttpPost><ValidateAntiForgeryToken> 属性添加到函数定义,使其如下所示:<

         <httppost>
    
  1. 从 Views/Manage 文件夹中加载 Index.vbhtml 文件。

  2. 搜索 <dt>电话 Number:</dt> (第 37 行)

  3. 模板代码不带任何自定义项,如下所示:

                 <dt>Phone Number:</dt>
    
@(If(Model.电话Number, “None”) [ @If (Model.电话数量
Nothing) 然后@Html.ActionLink(“Change”, “Add电话Number”) @:  |  @Html.ActionLink(“Remove”, “Remove电话Number”) Else @Html.ActionLink(“Add”, “Add电话Number”) End if ]
```
  1. 更改视图代码,如下所示:

                 <dt>Phone Number:</dt>
    
@(If(Model.电话Number、“None”)@If(Model.电话数量
无) 然后@
@ @Using Html.BeginForm(“Remove电话Number”, “Manage”, FormMethod.Post, New With {.class = “form-horizontal”, .role = “form”}) @Html.AntiForgeryToken @ End Using Else @ End If
```
  1. 重新编译应用程序,然后重新部署它。

Visual Studio 2015 MVC 6
对于 C#

  1. 从控制器目录中加载ManageController.cs。

  2. 搜索 Remove电话Number() (第 178 行)。

  3. 模板代码,不显示任何自定义项,如下所示:

     // GET: /Manage/RemovePhoneNumber
     [HttpGet]
     public async Task<iactionresult> RemovePhoneNumber()
     {
          var user = await GetCurrentUserAsync();
          if (user != null)
          {
              var result = await _userManager.SetPhoneNumberAsync(user, null);
              if (result.Succeeded)
              {
                  await _signInManager.SignInAsync(user, isPersistent: false);
                  return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
             }
         }
         return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
     }
    
  4. 删除 [HttpGet] 属性,然后将 [HttpPost][ValidateAntiForgeryToken] 属性添加到函数定义中,使代码如下所示:

      [HttpPost]
      [ValidateAntiForgeryToken]
     public async Task</iactionresult><iactionresult> RemovePhoneNumber()
     {
         var user = await GetCurrentUserAsync();
         if (user != null)
         {
             var result = await _userManager.SetPhoneNumberAsync(user, null);
             if (result.Succeeded)
             {
                 await _signInManager.SignInAsync(user, isPersistent: false);
                 return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
             }
         }
         return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
    }
    
  5. 从 Views/Manage 文件夹中加载 Index.cshtml 文件。

  6. 完全替换视图文件,使其如下所示:

     @model IndexViewModel
     @{
         ViewData["Title"] = "Manage your account";
     }
    
     <h2>@ViewData["Title"].</h2>
    

@ViewData[“StatusMessage”]

    <div>

更改帐户设置


密码:
@if (Model.HasPassword) { } else { }
外部登录名:
@Model.Logins.Count [  管理  ]
电话号码:
电话数字可用作双重身份验证中的第二个验证因素。 有关设置此 ASP.NET 应用程序以支持使用短信进行双重身份验证的详细信息,请参阅 本文 。 @*@(模型。电话Number ??“None”) @if (Model.电话Number != null) {
[]
} else { }*@
双重身份验证:
未配置双重身份验证提供程序。 请参阅 本文 ,了解如何设置此应用程序以支持双重身份验证。 @*@if (Model.TwoFactor) {
已启用 []
} else {
[] 已禁用
}*@
```
  1. 重新编译应用程序,然后重新部署它。

对于 Visual Basic

  • ASP.Net Core(以前 ASP.NET 5)不支持 Visual Basic。

其他建议的操作

  • 直接在以下位置下载 Visual Studio 工具更新:

  • 保护电脑
    我们将继续鼓励客户遵循“保护计算机”指南,了解如何启用防火墙、获取软件更新和安装防病毒软件。 有关详细信息,请参阅 Microsoft 保险箱ty & 安全中心

  • 使 Microsoft 软件更新保持更新
    运行 Microsoft 软件的用户应应用最新的 Microsoft 安全更新,以帮助确保其计算机尽可能受到保护。 如果你不确定你的软件是否是最新的,请访问 Microsoft 更新,扫描计算机以获取可用更新,并安装你提供的任何高优先级更新。 如果已启用自动更新并配置为提供 Microsoft 产品的更新,则更新会在发布时向你传递,但应验证它们是否已安装。

其他信息

反馈

支持

免责声明

此公告中提供的信息“按原样”提供,没有任何担保。 Microsoft 不明确或暗示所有保证,包括适销性和针对特定用途的适用性和适用性的保证。 在任何情况下,Microsoft Corporation 或其供应商都应对任何损害负责,包括直接、间接、附带、后果性、业务利润损失或特殊损害,即使 Microsoft Corporation 或其供应商被告知存在此类损害的可能性。 某些州不允许排除或限制后果性或附带性损害的责任,因此上述限制可能不适用。

修订

  • V1.0(2016 年 2 月 9 日):已发布公告。
  • V1.1(2016 年 2 月 10 日):已更新公告,包括 Microsoft ASP.NET Web 框架的下载信息,以及工具和Microsoft ASP.NET 和 Web 工具。 这只是一项信息性更改。

页面生成的 2016-02-19 14:36-08:00。