防止参数篡改和使用Javascript发送值的最佳方法?

时间:2015-11-29 17:01:57

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

我将一个表单发布到控制器并使其异步。我将值隐藏在输入表单中。单击按钮时,将调用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获取存储值的最佳方法是什么(更安全的方式然后隐藏输入类型)?

     

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

3 个答案:

答案 0 :(得分:4)

  

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

你不能!

  

让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
}

答案 1 :(得分:3)

如果值需要来自客户端(并且是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,而是设计您的网络应用程序中的授权层。

答案 2 :(得分:0)

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

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

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

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

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