如何确保JavaScript调用AJAX?

时间:2013-08-07 13:16:08

标签: php javascript ajax security

之前我问了一个类似的问题,答案很简单:

  

如果JavaScript可以做到,那么任何客户都可以做到。

但我仍然想找到一种限制AJAX调用JavaScript的方法。

原因是:

当用户点击图片时,我正在构建一个Web应用程序,标记如下:

<img src='src.jpg' data-id='42'/>

JavaScript调用这样的PHP页面:

$.ajax("action.php?action=click&id=42");

然后action.php在数据库中插入行。

但是我担心一些用户可以通过调用必要的url来自动化“点击”所有id等的条目,因为它们在源代码中可见。

如何阻止此类操作,并确保它仅在点击时有效,而不是通过从浏览器标签调用网址?

P.S。

我认为可能的解决方案是使用加密,例如在用户访问时生成密钥,并使用该密钥调用操作页面,或者使用hash / md5sum /其中任何一个。但我认为可以在不将其转化为安全问题的情况下完成。我对吗 ?此外,我不确定这种方法是否是一种解决方案,因为我对这种安全性或它的实现一无所知。

5 个答案:

答案 0 :(得分:2)

我不确定是否有100%安全答案。插入到隐藏表单元素中的服务器生成令牌和在一定时间段内限制请求数量等反自动化技术的组合是我能想到的最好的事情。

[编辑] 实际上一个好的解决方案是使用CAPTCHAS

答案 1 :(得分:2)

你的问题不是“如何从非AJAX中讲述AJAX?”这是“如何通过反复点击和选票填充来阻止某人夸大分数?”

在回答您提出的问题时,您引用的答案基本上是正确的。没有可靠的方法来确定请求是由AJAX,特定浏览器,CURL会话还是在远程网络会话中键入原始HTTP命令的人。我们可能会看到浏览器或脚本或应用程序,但所有PHP看到的都是:

GET /resource.html HTTP/1.1
host:www.example.com

如果有一些方便的原因想要知道请求是否是AJAX,那么一些javascript库(如jQuery)会为您可以查找的AJAX请求添加额外的HTTP标头,或者您可以手动添加标头或包含字段到您的有效负载,例如AJAX = 1。然后,您可以检查那些服务器端,并采取您认为应该为AJAX请求执行的任何操作。

当然没有什么能阻止我使用CURL来设置相同的请求,并设置正确的标头以使服务器认为它是一个AJAX请求。因此,您应该只使用这些技巧,无论请求是否是AJAX是有意义的,因此您可以正确格式化响应(如果不是AJAX则发送HTML页面,如果是,则发送JSON)。应用程序的安全性不能依赖于这些技巧,如果应用程序的设计需要能够出于安全性或可靠性原因从非AJAX告诉AJAX,那么您需要重新考虑应用程序的设计。

在回答您实际想要实现的目标时,有几种方法。但是,没有一个是完全可靠的。第一种方法是在第一次单击时在用户的计算机上存储cookie,如果cookie在任何后续请求中,则忽略来自该用户代理的任何后续请求。这是一种相当简单,轻量级的方法,但它也很容易通过简单地删除cookie或者首先拒绝接受它而被击败。

或者,当用户发出AJAX请求时,您可以记录有关请求用户代理的一些信息以及提交点击的事实。例如,您可以存储客户端IP和用户代理字符串的哈希值(存储的内容比MD5强!),以及点击的时间戳。如果您看到很多相同的哈希值以及紧密分组的时间戳,那么可能会尝试滥用。同样,这个技巧不是100%可靠,因为用户代理可以看到他们想要的任何字符串作为他们的用户代理字符串。

答案 2 :(得分:0)

使用post方法而不是get.Read这里的文档http://api.jquery.com/jQuery.post/来学习如何在jquery中使用post方法

答案 3 :(得分:0)

例如,您可以实现检查请求是否真的使用AJAX,而不是仅通过调用URL。

if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
    // Yay, it is ajax!
} else {
    // no AJAX, man..
}

答案 4 :(得分:0)

这个解决方案可能需要更多的反思,但可能会做到这一点

您可以使用Slicedpan的答案中所述的令牌。在为页面提供服务时,您将为每个图像生成uuids并将其存储在会话/数据库中。

然后将你的html服务为

<img src='src.jpg' data-id='42' data-uuid='uuidgenerated'/>

您的ajax请求将成为

$.ajax("action.php?action=click&uuid=uuidgenerated");

然后在php端,检查内存/数据库中的uuid,并允许或不允许该事务。 (您还可以检查ajax上发送的自定义标头,如其他响应中所述)

您还需要在令牌生命周期内,在窗口卸载时,在会话过期时清除uuids ...

此方法不允许您知道请求是否来自xhr,但您可以限制其数量。