【问题标题】:How "secure" is the ASP .NET ControllerASP .NET 控制器有多“安全”
【发布时间】:2014-09-06 02:05:06
【问题描述】:

我对 ASP .NET 的 MVC 和 AJAX 的概念和设计还很陌生,我想知道控制器在网络部署时对不受欢迎的用户有多安全。

我问是因为为了好玩,我做了一个需要用户名和密码的小管理面板。输入输入后,信息是 AJAX 提交给控制器中的 ActionResult 方法,该方法只是比较字符串以查看它们是否匹配,然后将响应返回给 AJAX。

我的问题是,有人进入我的控制器并查看硬编码密码有多容易?

没有专业人士会尝试闯入此网站,因为它是大学俱乐部的免费网站,但我想确保普通计算机科学专业的学生不会在发生这种情况时“闯入”对某事“愤怒”或生气(你永远不知道!哈哈)。

问题:在 ASP .NET MVC Web 部署的应用程序上,在控制器中进行密码验证是否“相当”安全?为什么或为什么不?

这是实际代码,以防使用它对答案很重要(出于隐私考虑,域被省略)

注意:我知道使用 Javascript 可能不好,但我正在寻找与密码检查的 AJAX 和控制器安全性相关的答案。

查看(管理员/)

//runs preloadFunc immediately
window.onpaint = preloadFunc();

function preloadFunc() {
    var prompting = prompt("Please enter the password", "****");
    if (prompting != null) {
        $.ajax({
            url: "/Admin/magicCheck",
            type: "POST",
            data: "magic=" + prompting,
            success: function (resp) {
                if (resp.Success) {
                  //continue loading page
                }
                else {
                    //wrong password, re-ask
                    preloadFunc();
                }
            },
            error: function () {
                  //re-ask
                  preloadFunc();
            }
        });
    }
    else {
       // Hitting cancel
        window.stop();
        window.location.replace("google.com");
    }
}

控制器(ActionResult Snippet)

[HttpPost]
public ActionResult magicCheck(string magic)
    {
        bool success = false;
        if (magic == "pass")
        {
            success = true;
        }
        else
        {
            success = false;
        }
        return Json(new { Success = success });
    }

我还是 MVC 和 AJAX 的新手,更不用说任何涉及安全的东西了,所以我只是想知道控制器的安全性如何,特别是在 webdeploy 上这个简单的密码设置。

【问题讨论】:

标签: javascript ajax asp.net-mvc security webdeploy


【解决方案1】:

在正常运行期间,无需担心,因为您的代码已编译,DLL 无法提供服务,浏览器无法请求控制器泄露自己的代码。

但是,服务器的不可预见的错误、漏洞或错误配置可能导致服务器泄露已编译的代码、web.config 等,这并非不可能(但非常罕见),从而有人可以反汇编代码(IL 是轻松反编译)并泄露您的秘密。

更令人担忧的是,有人可以物理访问服务器,只是直接抓取二进制文件并反汇编以找到您的秘密。

要考虑的另一件事是,在正常情况下,谁可能会看到这个秘密,以及他们是否应该知道它。开发人员、测试人员或审阅者可能被允许编写或检查代码,但您可能不希望他们知道其中的秘密。

处理此问题的一种方法是不要以纯文本形式存储机密。相反,create a hash 的有效值,然后更新您的应用程序以以相同的方式散列用户的输入,并比较结果。这样,如果用户获得了您的源代码,他们就无法读取原始纯文本值,甚至无法将其复制/粘贴到您的 UI 中。您可以滚动自己的代码来进行散列,使用FormsAuthentication API 或其他方式。

最后,不要依赖客户端的安全措施。您可以在客户端检查安全性以使 UI 做出适当反应,但所有服务器端请求都应进行检查以确保用户的安全声明有效。

关于如何管理身份、密码和进行安全断言的问题确实超出了这里的范围。花一点时间浏览有关该主题的myriadarticles。此外,Visual Studio ASP.NET 项目模板包括许多已经为您提供了良好开端的安全基础设施。

决不让事情碰运气是一项重要的政策。学习 ASP.NET 和 MVC 的各种身份验证和授权工具是值得的。此外,还有许多 APIs 可以插入,为您完成大量繁重的工作。

【讨论】:

  • 所以听起来大部分情况下都可以,除非系统中存在侥幸现象或有人可以访问服务器?我目前使用 Winhost 托管它,那么在这种情况下服务器问题是否存在问题?谢谢!
  • 这取决于您的关心程度。如果您认为可以造成很小的损害或烦恼,并且您或其他任何人都不关心它是否发生了什么事,那就这样吧。但我会鼓励每个人,如果他们要做某事,就做对。正如我在编辑中所说,Visual Studio 中有预制模板(我想这取决于您拥有的版本),这些模板为您预先配置了安全性内容。您可以从那里编辑应用程序以满足您的目的。
【解决方案2】:

您似乎正在通过 AJAX POST 发送密码。对于您的问题,我的回答是您应该考虑使用 SSL 或在通过 POST 发送密码之前对其进行加密。请参阅此答案以获取示例和说明SSL Alternative - encrypt password with JavaScript submit to PHP to decrypt

正如 HackedByChinese 所说,存储在您的编译文件 (DLL) 中的实际代码没什么大不了的。如果您想更加偏执,还可以将密码存储在 web.config 中并在那里加密。这是How to encrypt username and password in Web.config in C# 2.0的示例和说明

【讨论】:

    【解决方案3】:

    此代码根本不安全。您的 JavaScript 代码可以替换为用户想要的一切。所以有人可以摆脱你的 preloadFunc。普通计算机科学学生将直接从控制台执行此代码:

    if (resp.Success) {
        //continue loading page
        //this code can be executed by hand, from console
    }
    

    就您的安全而言,这就是全部。

    身份验证和授权信息应随每个请求发送到服务器。作为一个简单的解决方案,您可以通过调用

    来使用 FormsAuthentication
    FormsAuthentication.SetAuthCookie("admin")
    

    /Admin/magicCheck 中,仅当密码正确时。

    然后你应该用[Authorize]属性装饰数据检索方法来检查cookie是否存在。

    使用 SSL 来保护浏览器和服务器之间的通信也是明智之举,否则密码会以明文形式传输。

    【讨论】:

    • 只设置带有forms认证的cookie是不够的,还需要在应用程序的web.config文件中配置forms auth的参数才能正常工作。
    【解决方案4】:

    正如已经指出的那样,如果您可以获得应用程序的二进制文件(或者就此而言,任何 .NET 应用程序,而不仅仅是 MVC),那么它肯定会结束。

    刚刚坐在我面前,现在我有 3 个应用程序,可以轻松查看里面的内容。

    • Telerick - 只需反编译
    • IL-间谍

    都可以在几秒钟内免费下载,两者中的前者将占用整个编译程序集,实际上不仅对代码进行逆向工程,还会为我创建一个解决方案文件和其他项目资产,让我加载它立即返回 Visual Studio。

    同时,Visual Studio 将允许我在另一个项目中引用二进制文件,然后让我使用简单的对象浏览器浏览它们以找出它们的调用结构。

    您可以混淆您的程序集,并且有很多应用程序可以做到这一点,但它们仍然无法阻止您反编译代码,而只是使反向工程代码难以阅读。

    另一方面

    即使您没有使用上述任何内容,您仍然可以使用命令行工具(例如“Strings”)或可以显示十六进制字节和可读 ASCII 的编辑器(例如“Ultra Edit 32”和“Notepad++”)来直观地显示挑选出有趣的文本字符串(这种方法也适用于本地编译的代码)

    如果您只是担心偶然的驱动/意外入侵,那么您要做的第一件事就是确保不要将源代码保存在服务器文件夹中。

    令人惊讶的是,我遇到了多少生产 MVC 站点,其中开发人员实际上在为 Internet 提供服务的服务器上拥有活动的项目文件和开发配置。

    值得庆幸的是,在大多数情况下,IIS7 都设置了合理的默认值,这意味着当尝试下载“*.CS”文件或“web.config”文件时会被拒绝。

    这绝不是一门精确的科学,只需尝试以下链接即可了解我的意思!

    filetype:config inurl:web.config inurl:ftp

    (别担心它是安全的,它只是一个常规的 Google 搜索链接)

    所以,为了避免这种泄露文件的情况,需要遵循一些规则:

    • 使用网络发布向导,这将确保只有需要运行的文件最终在服务器上
    • 不要将基于实时 Web 的 FTP 根目录指向您的项目根目录,事实上,如果您根本不能使用 FTP 的话
    • 请仔细检查所有内容,如果可能的话,请几个值得信赖的朋友尝试下载他们不应该下载的东西,即使有一个良好的开端,他们也会遇到困难

    从服务器配置开始,您有大量的安全选择。

    我绝对不提倡做的一件事是自己动手。

    多年来,.NET 已经将许多非常好的基于安全的系统融入其核心,其中主要是“ASP.NET 成员资格”,而目前的新成员是“ASP.NET 简单成员资格”

    每款产品都有自己的长处和短处,但每一款都有你使用的方法所没有的东西,那就是全局保护

    就您现有的代码而言,它只是该控制器上的简单密码。

    但是,如果我不给它一个密码怎么办。

    如果我决定尝试一些随机的 url 并碰巧幸运的话会发生什么。

    例如:http://example.com/admin/banned/

    而且,哦,看,我已经打开了被禁止的用户页面。

    这是完全不熟练的脚本小子和网络破坏者寻找的低挂入口点类型。他们从一个站点到另一个站点四处游荡,尝试像这样的随机和伪随机 URL,而且他们经常很幸运,并找到一个不受保护的页面,让他们能够进入足够远的地方,运行一个自动化脚本来完成剩下的工作。

    可怕的是,像你们这样的小型大学俱乐部网站也正是他们所寻找的那种东西,他们中的许多人这样做是为了吹牛,然后他们在朋友面前炫耀,甚至更少技能比他们自己高,然后他们将他们视为“黑客英雄”,因为他们闯入了“大学网站”

    但是,如果您使用 ASP.NET 成员资格之类的东西,那么您不仅使用了经过尝试和测试的安全性,而且您还可以在您网站中的每个页面上放置这种保护,而无需为您编写的每个控制器添加样板代码。

    相反,您使用简单的数据注释来表示“此控制器不受保护”和“此控制器允许没有管理员身份的用户”让 ASP.NET 对您未设置规则的所有内容应用“不”的站点范围安全性为。

    最后,如果您想了解 ASP.NET 安全、MVC 或其他方面的最终决定权,请访问 Troyhunt.com 我保证,如果您不害怕在手之前,你会在之后。

    【讨论】:

    • 设置 cookie 是当今大多数框架的工作方式,是的,但请确保它是 https(安全 cookie)并且它仅在会话生命周期内持续(也就是说,它会死掉当浏览器关闭页面时 - 许多网站今天不做的一件事是 https 所有涉及安全登录的页面,他们认为只要登录表单是 https ,就无法获取密码和用户名,但是很多中断ins 实际发生是因为有人从非 https 页面上抓取了一个会话 cookie,该页面在登录完成后通过常规 http 提供。
    • 至于您对保护所有页面的评论,很好,是的,但是您现在遇到的问题是维护问题之一。让我们假设在 1 年的时间内,您的大学想要向该网站添加 100 个额外页面。这是您必须确保添加所需的代码以支持您的身份验证系统的 100 倍。现在,如果为时已晚,并且您已经完成了其中的 99 个并且累了,那么第 100 页可能就是您错过的那一页,或者在上面犯了一个编程错误。盔甲上的那个缝隙很可能会带来很大的不同。
    • RE:您的 pastebin 代码。不,不,再一次不 :-) 第一件事是一个巨大的耳光:“在 JS 中设置和重置你的 cookie 值”,这意味着我可以继续,在 chrome 中按 F12,调用你的函数和尽可能多地更改cookie,然后让您的页面相信它已登录。如果您为身份验证设置这样的cookie,它们必须设置在服务器端,更重要的是您滚动自己的身份验证,您需要检查您在每次请求时从客户端返回的 cookie 值,只是为了确保它没有被篡改。
    • 如果您想使用 cookie 服务器端,请参阅:blogin.codeinside.eu/2010/10/19/… 并更好地了解较新的身份验证服务的工作方式:benfoster.io/blog/aspnet-identity-stripped-bare-mvc-part-1 我实际上只是使用了 Ben 的信息网站向一个没有身份验证的旧 MVC 应用程序添加身份验证,因为它现在已经升级,现在需要身份验证。
    • Ben 的方法效果很好,它利用了 .NET 中已有的大量内容,使您无需自己完成任何工作,而无需调用 API。
    猜你喜欢
    • 2015-11-10
    • 2021-11-18
    • 2016-07-28
    • 1970-01-01
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多