【问题标题】:Keep Sensitive Data Off Heap将敏感数据保持在堆外
【发布时间】:2017-09-19 20:25:25
【问题描述】:

在使用 Checkmarx 扫描 ASP.net MVC 应用程序时,我经常看到堆检查漏洞。所以我开始怀疑是否可以使用自定义模型绑定器或内置的ByteArrayModelBinder 将密码和其他敏感字符串保留在堆之外,以进行受控处理。我想出了以下解决方案,它通过字节数组发布和显示敏感数据,但我想知道这些数据是否仍然通过某个地方的字符串进入堆。 (注:显示动作仅用于调试。)

视图模型

public class ByteArrayViewModel
{
    public byte[] SensitiveData { get; set; }        
}

输入视图

@model MvcHandlingSensativeStrings.Models.ByteArrayViewModel

@{
    ViewBag.Title = "byte[] Post";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>@ViewBag.Title</h2>
@using (Html.BeginForm("Post", "ByteArray", FormMethod.Post))
{
    @Html.TextBoxFor(m=>m.SensitiveData);
    <button type="submit">Send</button>
}

控制器

public class ByteArrayController : Controller
{
    public ActionResult Index()
    {
        return View(new ByteArrayViewModel());
    }

    [HttpPost]
    public ActionResult Post(ByteArrayViewModel viewModel)
    {
        try
        {
            // Handle sensitive data here
            return View("Display", viewModel);
        }
        catch
        {
            return View("Index");
        }
        finally
        {
            // Clear sensitive data from memory
            //Array.Clear(viewModel.SensitiveData, 0, viewModel.SensitiveData.Leng
        }
    }

    public ActionResult Display(ByteArrayViewModel viewModel)
    {
        return View(viewModel);
    }
}

显示视图

@model MvcHandlingSensativeStrings.Models.ByteArrayViewModel

@{
    ViewBag.Title = "byte[] Display";
    Layout = "~/Views/Shared/_Layout.cshtml";
    string s = Convert.ToBase64String(Model.SensitiveData);
}

<h2>@ViewBag.Title</h2>
<p>@s</p>
<p>@Model.SensitiveData.GetType().ToString()</p>

显示输出

* 更新 *

这表明在 ByteArrayModelBinder 或任何其他模型绑定器执行之前,表单参数存储在字符串数组中,因此容易受到堆检查。

* 更新 2 *

如果您查看 Microsoft 的 NetworkCredential 实现,您会注意到即使 Password 属性是一个字符串,但 SecureString 在下面用于存储。

【问题讨论】:

  • 听起来您正在尝试重新发明 SecureString 类。
  • @mason,SecureString 没有内置模型绑定器,但字节数组有。
  • 你真正想要完成什么?通过绑定到一个秘密,无论技术如何,问题都无关紧要。
  • 您的更新与我的回复一致! RequestObjects 将它们的元素存储在一个字符串数组中。你会把创可贴放在筛子上吗?
  • 我不是故意的,但我只是想指出,如果你通过 ASP.net 堆栈传递秘密,那么“我如何将秘密从我的堆中取出”这个问题是无关紧要的,剃须刀之类的。这与 SecureString 无关。 SecureString 没有模型绑定器,因为这会使 SecureString 的(已经有限的)安全性失效。

标签: c# asp.net-mvc security model-binding checkmarx


【解决方案1】:

这是一个例子,说明静态分析工具不能总是被认真对待。

当密码和敏感数据进入您的应用程序时,猜猜它会进入什么类型的结构?一个 RequestObject,它以字符串的形式出现。你猜怎么了?它已经在堆上,你无能为力。当然,当你将它传递给你的结构时,你可以玩一些游戏来防止它再次被放到堆上,但这不会改变它在其他地方已经不受控制的事实。

不要误以为 SecureString 和其他噱头是解决方案。 Microsoft 现在acknowledges that SecureString isn't what it claims to be,它正在从 .Net Core 中删除。

底线:当他们抱怨堆检查漏洞时,忽略 Checkmarx 和 Fortify 等工具。这些规则应该被抛弃。

【讨论】:

  • 关于“RequestObject,它以字符串形式出现。”。这是我怀疑的。
  • 我认为您歪曲了 Microsoft 在 SecureString 上的立场。 MS 承认 SecureString 是用词不当,它不是真正的“安全”,但不那么不安全。安全是关于保护层和更小的机会窗口。放弃任何不能 100% 保证安全和不可渗透的安全措施是愚蠢的。
  • @MarkGood 是正确的,“不太安全的字符串”。 Securestring 给开发人员带来了很多痛苦,但几乎没有收获。如果有人可以读取你的记忆,那么字符串是在那里一次还是一百次都没有关系:攻击者只需要它一次!虽然人们可以争论有实际好处的场景,但需要权衡安全机制与成本和预期收益。通过这样的衡量标准,SecureString 很容易成为我列出的 10 大不良安全建议。
  • 在内存中保存秘密有时是必要的(在加密之前生成 PK 后考虑)。但是,应注意将这些数据保存在少数地方,限制对其他进程的访问,随机化地址,将其保留在页面文件之外并在使用后“烧掉”它。在这种情况下,SecureString 有时是可用的。在 OP 的上下文中,无论是否为 SecureString,代码都无法抵御任何这些攻击。
  • 如果你看看微软对 NetworkCredential 的实现,你会注意到即使 Password 属性是一个字符串,但 SecureString 是在下面用于存储的。
【解决方案2】:

答案是否定的,你并没有让这变得更安全。

为避免将机密存储在可恢复的内存中,您需要使用 C# 中的 SecureString 类(或 Windows 中的底层加密 API)。这将通过一些努力使秘密更难恢复,方法是在处置时删除它们,同时确保它们永远不会出现在页面文件中。

但更重要的是,将机密打印到网页(即使使用 TLS)显然会将机密暴露给 Web 堆栈的所有层,使其容易受到多个本地攻击以及客户端上的浏览器攻击。

解决方案是永远不要以明文形式存储密码,而是使用加盐哈希。不要试图自己发明这样的东西,使用经过验证的解决方案来安全地验证和存储密码。很容易忽略完全破坏应用程序安全性的东西。例如,加密 API 有一个功能。例如,请参见此处:How to store and retrieve credentials on windows using C#

如果您绝对需要接受来自表单的“秘密”用户数据,并且想要防止对服务器的攻击:

  1. 保护进程免受同一机器上其他进程的远程攻击(在隔离的 VM 中运行,在 Docker 中运行,以单独(非 root)用户身份运行所有内容
  2. 为防止本地攻击,请确保敏感数据不会最终存储在持久性存储(即 SecureString)中。正如已经指出的那样,使用您当前的实现很难做到这一点,因为您需要强化应用程序的所有层,从 SSL/TLS 终止到控制器。

【讨论】:

  • ASP.net MVC 不提供支持 SecureString 的模型绑定器。我的问题更多的是关于在请求管道中处理这些数据的位置。
  • 正如我所写,绑定 SecureString 无效,因为所有其他层都已经有了该字符串。
猜你喜欢
  • 2011-07-25
  • 2016-12-26
  • 2018-09-14
  • 2021-07-05
  • 2017-07-25
  • 1970-01-01
  • 1970-01-01
  • 2011-03-14
  • 2014-07-14
相关资源
最近更新 更多