【问题标题】:Best way to prevent parameter tampering and send values with Javascript?防止参数篡改和使用 Javascript 发送值的最佳方法?
【发布时间】:2016-03-03 07:27:45
【问题描述】:

我正在向控制器发布一个表单并使其异步。我将值存储在隐藏的输入表单中。单击按钮时,将调用 javascript 函数。它既从输入字段中获取值,也从隐藏的输入表单中获取值。然后它会向控制器发送一个 json 字符串来处理这个请求。

控制器:

[HttpPost, Authorize] 
public ActionResult DoSomeStuff (string leagueName, string doSomething)  {
    var service = new Service(_db);
    var league = service.GetLeague(leagueName);
    if (league != null) {
        // validate doSomething
        league.Action = doSomething;
        _db.SaveChanges();
    }

    return new EmptyResult(); 
}

Javascript:

$(document).on("click", "#submitForm", function () {
    var json = {
            "leagueName": $("input[name=leagueName]").val(),
            "doSomething": $("input[name=doSomething]").val()
    };

    $.post("/Home/DoSomeStuff/", json, function () {
        // async display something
    });
}

HTML:

<input type="text" name="doSomething">
<button type="submit" id="submitForm"</button>
<input type="hidden" name="leagueName" value="@item.League.LeagueName" />

让 javascript 获取存储值的最佳方式是什么(比隐藏输入类型更安全的方式)?

如何防止某些用户更改输入类型的值 隐藏字段?

【问题讨论】:

    标签: javascript c# asp.net asp.net-mvc parameter-passing


    【解决方案1】:

    如何防止某些用户更改输入中的值 键入隐藏字段?

    你不能!

    让 javascript 获取存储值的最佳方法是什么(更多 安全方式然后输入类型隐藏)?

    一般规则是,不要相信来自客户端的数据。在执行任何操作之前,您应该始终在服务器上对其进行验证。

    如果您担心用户将表单中的联赛名称字段值更新为其他用户的联赛名称并发布,您应该做的是,明确检查用户是否有适当的权限在发布的内容上做某事联盟在你的服务器代码中。

    [HttpPost, Authorize] 
    public ActionResult DoSomeStuff (string leagueName, string doSomething)  {
        var service = new Service(_db);
        var league = service.GetLeague(leagueName);
    
        // Now check whether the current user has access/permission 
        // to perform some operation on this league.
        // Ex : if(!service.IsUserAuthorizedToDoSomething(league))
        //     {
        //      return View("NotAuthorized");
        //     }
        //to do: Return something
    }
    

    【讨论】:

    • 您好,感谢您的回答!如果我验证此用户对两个联赛都有权限怎么办。那是不是就没有办法查看联赛名称是否被更改了?
    • 如果用户可以访问两个联赛。他可以更新/执行任何操作。您可以做的另一件事是将 League 的唯一 Id 也保留在表单的隐藏字段中。并使用它来验证/从 db 获取联赛。由于用户也可以访问该联赛,因此他可以根据需要更改 id。你无能为力。如果您绝对想阻止这种情况,请在 GET 操作中生成一个随机字符串,并将其设置在您的表单中的隐藏字段中,并在 HttpPost 上验证它。因为这是每个请求会话。您的第二个用户不会知道这个秘密字符串。虽然这是一种肮脏的方式
    • 感谢您的帮助! :)
    【解决方案2】:

    如果值需要来自客户端(并且是 HTTP 请求的一部分),那么您绝对无法阻止客户端修改其内容。如果客户端不应该修改某些字段的内容,那么这些字段与您的标记无关,并且是回发 HTTP 请求的一部分(无论是作为隐藏字段还是您想到的任何标记元素)。它们应该安全地驻留在您的服务器(数据库?)上,并使用来自客户端的某些标识符进行检索。显然,客户端是否可以访问与此标识符相关的信息取决于所谓的授权。基本上,您应该首先知道您的客户是谁(身份验证),然后在您的数据模型中验证该客户是否有权访问相应的记录。就这么简单。

    [HttpPost]
    [Authorize] 
    public ActionResult DoSomeStuff (string id, string doSomething)  
    {
        var service = new Service(_db);
        var league = service.GetLeagueById(id);
        if (!HasAccessToLeague(User.Identity.Name, league)) 
        {
            // you are not suppose to modify the contents of this league
            // throw him a 404 or something
        }
        else
        {
            if (league != null) 
            {
                // validate doSomething
                league.Action = doSomething;
                _db.SaveChanges();
            }
        }
    
        return new EmptyResult(); 
    }
    

    显然HasAccessToLeague(string username, string leagueId)方法的实现很大程度上取决于你的数据模型和你的授权逻辑。

    您还在问题标题中使用了XSS,但这里您的问题不在于XSS 或javascript,而是在您的网络应用程序中设计授权层。

    【讨论】:

    • 您好,感谢您的回答!如果我验证此用户对两个联赛都有权限怎么办。那是不是就没有办法查看联赛名称是否被更改了?
    • 如果允许用户修改联赛名称,那么不要将联赛名称作为隐藏输入,而是一个普通的文本框,用户可以在其中修改其名称。但是查询时使用联赛的唯一标识作为id。如果用户可以访问两个联赛,那么为什么要关心他是否修改了名称?如果您需要大量检测这种情况,那么您可以让您的 UPDATE 语句在 WHERE 语句中包含来自用户的联赛名称以及 id。在这种情况下,如果 0 行受到影响,您将知道用户更改了名称。
    • 感谢您的帮助! :)
    【解决方案3】:

    当然可以这样做!毕竟,您的服务器应用会设法跟踪当前登录的用户正在使用不安全的客户端存储。

    当用户登录时,服务器将生成一条秘密消息并将其存储在一个加密令牌中,该令牌传递给客户端并保存在一个 cookie 中(这只是另一个不安全的客户端数据存储)。当您向服务器发送请求时,它会获取 cookie,对其进行解密,并检查其中的数据以判断用户是谁。

    您也可以这样做 - 对于隐藏字段,加密它们,将它们放入隐藏输入(或 cookie,如果您愿意),然后将它们发送回服务器。但是,如果您也发送纯文本,则只能在客户端 javascript 中使用它们,这意味着您仍需要在服务器上执行一些检查,但检查可以像比较加密值与隐藏表单值一样简单,如果有不匹配的,拒绝请求。

    但要记住,加密速度很慢。取而代之的是,从数据库中获取值会更快,尽管您可能会为这些值使用缓存。 YMMV。

    另一种选择是生成包含值的 javascript 文件,并确保客户端浏览器无法使用安全功能(例如 content-security-policy)对其进行编辑。缺点是无法在 html 中使用这些值(显然用户可以在那里编辑它们),因此您必须通过 js 调用将数据传回服务器。

    【讨论】:

      猜你喜欢
      • 2017-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-16
      • 2016-05-19
      相关资源
      最近更新 更多