1

我正在创建一个网页,用户可以在其中注册自己和他们新购买的产品。

因此,该页面最初包含两个输入字段:序列号和他们的社会保险号。这些值将针对两个不同的 API 进行验证。用户不应滥用这些 API 调用,因为第二个调用每次调用都要花钱。另一个也应该以某种方式受到限制,以便用户无法访问我们所有的序列号。

并希望用ajax 制作这个网页,以创造良好的用户体验。所以我使用jQuery ajax 函数来调用我放在页面代码隐藏中的webmethods。

反过来,每个 Web 方法都使用凭据调用匹配的 API。但这是否意味着任何人都可以编辑脚本客户端,以便他们可以对 API 进行多少次调用?

我需要能够防止这种情况发生。我该怎么做呢?我可以检查调用不是由用户插入的脚本发起的吗?

另一个问题,如何在客户端验证两个 ajax 调用都已成功返回?如果只有一个 ajax 调用,这很容易。我会在成功中做一些事情:ajax 函数的一部分。我可以检查输入字段旁边的所有复选标记是否可见,但这很容易被用户篡改。那么有什么好方法呢?一旦成功进行了两次调用,我想启用一个按钮,以便用户可以确认来自 API 的结果。

[WebMethod]
    public static string CheckSerialNumber(String _input)
    {
        string result = null; 
        var client = new CheckSerialNumberClient(); //A service reference to the API
        try
        {
            //make the API call.
            result = client.checkSerialNumber(_input);
        }
        catch (Exception)
        {
            result = "An error occured";
        }
        return result;
    }

[WebMethod]
    public static string GetCustomerInfo(String _input)
    {
        string result = null; 
        var client = new CustomerInfoClient(); //A service reference to the API
        try
        {
            //make the API call.
            result = client.getCustomerInfo(_input, myCredentials); //credentials is so that the company that has the API can charge us for each call.
        }
        catch (Exception)
        {
            result = "An error occured";
        }
        return result;
    }

jQuery,我得到了这个工作,但不妨展示它。这是在针对正则表达式验证输入之后:

$.ajax({
type: "POST",
url: "/Default.aspx/CheckSerialNumber",
data: ...
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
    return true;
}
4

4 回答 4

4

您可以使 CheckSerialNumber 返回一个 nonce(单次使用密钥),在调用 GetCustomerInfo 时必须使用该 nonce(然后验证服务器端)。这将强制您的 api 用户在转到 GetCustomerInfo 之前通过 CheckSerialNumber。

这将解决调用 GetCustomerInfo 而不首先通过序列号验证的问题,但不会阻止某人重复调用第一个然后再调用另一个,直到您用完现金,前提是他们至少有一个经过验证的序列号。

您可以限制每个序列号的调用次数,在这种情况下,攻击者必须生成有效序列号列表(不确定这有多容易)

您可以检查请求 ip 并尝试限制这样的调用,但老实说,很难阻止足够坚定的人绕过此类限制,因此通常此类攻击是在网络级别处理的。如果您使用 SSL,这将使生活变得更加困难,因为据我所知,在使用 SSL 时不可能进行 IP 欺骗,但同样,它不是防弹的。

设置 cookie 等与使用攻击工具时删除 cookie 或忽略它们很容易无关。

至于确认一切顺利,在第一次调用的成功方法中,您可以调用第二次验证(如果您实现了一个随机密钥,无论如何您都必须这样做)。然后在 GetCustomerInfo 的成功方法中,您可以确认它也验证成功。

作为最后的手段,限制您在给定时间范围内对 client.getCustomerInfo api 的调用次数,因此如果有人确实绕过了您的限制,您可以通过限制您为该服务支付的费用来限制入侵的影响。例如,您可以说平均每分钟有 100 个调用,因此每分钟超过 200 个调用都应该停止服务处理新请求,直到您了解这是实际请求的激增还是攻击。

于 2013-02-03T15:55:20.000 回答
2

您应该始终验证从客户端发送的数据,无论它是否在客户端上进行了验证。否则,您将容易受到恶意客户端的攻击。如果您担心恶意客户端,您必须接受不会有万无一失的方法来防止篡改。您可以通过使用身份验证和授权系统、为每个请求添加令牌、限制允许的请求数量等等来让它们变得更难一些……但即便如此,也没有绝对的安全性。

如果您想检查两个呼叫是否成功,只需在呼叫成功返回时设置一些全局标志。或者您可以在第一个呼叫成功之前发起第二个呼叫。您还可以返回一些令牌,这是以后调用所需的,但这也可能被滥用。

出于安全考虑,您可能还想查看OWASP网站。尤其是“参考”和“操作方法”部分可能很有用。

并且总会有客户端关闭 javascript,然后您的网站将无法按预期运行。

还要考虑想要编写这些访问脚本的客户。或者,您可能想将这些 Web 方法作为 API 提供,那么将没有带有 javascript 的客户端,并且您必须在服务器上验证提供的数据。

于 2013-02-03T15:42:09.953 回答
1

您是否为每个 Web 输入进行一次 ajax 调用?为什么不将它们组合成 1,作为形式?

请记住,除了任何客户端验证之外,您还应该始终进行服务器端验证。客户端验证不足以确保安全。在这种情况下,您可以使用会话变量或数据库表来记录用户进行的呼叫次数,对照他们的序列号来识别他们。然后,您将有办法在 x 次尝试失败后忽略它们。

您也可以使用他们的 IP 来识别他们,但这并不可靠 - 许多人拥有可以轻松更改的动态 IP 地址。IP地址也可以很容易地被欺骗。

于 2013-02-03T15:45:44.257 回答
0

在数据库中捕获用户存储的 IP 地址,并且只允许每分钟 x 次尝试和每天 x 次尝试。

于 2013-02-03T15:43:51.070 回答