如何保护Ajax链接请求?

问题描述 投票:37回答:8

想象一下下一个场景:用户想要注册到网页并填写表格。当他填写表单时,如果字段有效,jQuery会继续检查regular expression等等...

将电子邮件作为用户在注册登录后将使用的主键,需要使用Ajax检查电子邮件字段,以便用户知道该电子邮件是否已注册。我想用Ajax检查它,以避免发送完整的表单并清空它,刷新页面等...

因此,当用户结束填写电子邮件字段时,Ajax请求将发送到服务器,类似于下一个链接:

example.com/[email protected]

当check.php收到电子邮件时,它询问数据库是否存在,并返回如下信息:User already exists(如果用户存在)或null(如果用户不存在)。

问题是:如果有人挖掘我的.js并找到类似的链接,他们可以使用该链接发送大量请求以查明是否存在这些随机电子邮件。这可能导致大量使用数据库,或者在最坏的情况下甚至导致崩溃和私人信息泄露。

有人可以做一个巨大的for循环检查电子邮件,如:

//Getting the response of the next links
example.com/[email protected] // Returns null
example.com/[email protected] // Returns null
example.com/[email protected] // Returns null
example.com/[email protected] // Returns User already exists

------------------------------------------------------------------------------------------------------------------------------------

自从我上次接受答案以来,我一直在调查这个问题,并找到了避免这种行为的解决方案。以下代码适用于JAVA,但逻辑可以应用于任何其他服务器端语言。

在对服务器执行任何ajax请求之前,我向服务器请求令牌。这个令牌看起来像这个fmf5p81m6e56n4va3nkfu2ns8n它是通过一个简单的方法制作的,但它可以更复杂,但这很好。

public String getToken() throws UnsupportedEncodingException {
    return new BigInteger(130, new SecureRandom()).toString(32);
}

在请求令牌时,服务器不仅会返回令牌,还会返回一个小脚本,以防万一有人使用浏览器检查元素(和浏览器导航栏),这样的脚本将运行并且令牌将被清除。 Servlet返回如下内容:

_html += "<head>"
    + "<script> "
    + "window.onload=function(){\n"
    + "       document.body.innerHTML = \"\";\n"
    + "    }"
    + "window.location.href='http://mywebsite.com' "
    + "</script>"
    + "</head>"
    + "<body>"
    + "[" + token+ "]"
    + "</body>"
    + "</html>";

首先清空身体然后导航回我们想要的任何地方。然而,javascript / jquery将整个内容作为字符串捕获,然后我只是在[和]之间提取字符串。此令牌仅适用于下一个请求,因此每个AJAX请求都将具有其唯一令牌。在第二个请求中,删除刚刚使用的令牌。

获得令牌后,我将其作为参数附加到我请求的任何链接,如下所示:

ajaxRequestObjet = $.ajax({
    url: "http://localhost:8084/mywebsite.com/servlet", //<-- local tomcat server
    method: "POST",
    data: "type=AJAX&page=some-article&token=fmf5p81m6e56n4va3nkfu2ns8n"
});

这种方法适用于手动检查网站并尝试使用链接的人,但是自动执行此操作的java / php / IIS服务器呢?

为此请求标题!像这样的东西:

boolean isAjax = "XMLHttpRequest".equals(request.getHeader("X-Requested-With")); 

仅当XMLHttpRequest存在时才会成立....

还有一件事要记住。确保'Access-Control-Allow-Origin' header is NOT present in your app确保您服务器中的任何javascript都不会获得服务器资源。如果此标头不存在,则chrome将返回以下内容:

XMLHttpRequest cannot load http://localhost:8084/mywebsite.com/servlet. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

Java服务器在tomcat中,我有另一个apache用于此测试,这是apache中存在的小html,它给出了上面的错误:

<html>
<head>
    <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>

    <script>
    ajaxRequestObjet = $.ajax({
        url: "http://localhost:8084/mywebsite.com/servlet",
        method: "POST",
        data: "type=AJAX&page=Token"
    });

    ajaxRequestObjet.done(function (msg) { 
        alert(msg);
    });

    </script>

</head>
<body>
</body>
</html>
javascript php jquery ajax
8个回答
9
投票

虽然你无法控制这100%...有一些选择..

尝试使用人们使用Captcha脚本的相同方法。

基本上当用户加载表单/页面时..你在他们的PHP会话中生成一个随机字符串/ id并存储它..当他们发送ajax请求时,让你的ajax检查还附加字符串/ id并在允许之前需要它检查执行其他返回500或其他什么的标题..

将此方法与会话一起使用,您可以设置允许的检查限制(例如5),一旦用户尝试了超过5次检查,他们需要重新加载页面或执行人工检查(例如Captcha)..然后重置他们的计数..甚至允许在1小时/每个IP或其他东西中总共说30。

同时使用智能事件在ajax检查完成时触发,例如字段/标签更改或按下按钮..或者当检测到有效电子邮件时...但是.com.au会触发两次。

基本上这种方式,即使有人嗅探你的JS文件并试图自动化电子邮件检查器..这将要求他们找到一种方法来追加你生成的字符串/ id,并限制他们执行的请求数量。

除此之外,你可以轻松做到更多......但是还有一些其他的想法。

他们中的大多数人都会使用PHP会话/ cookie。例如,如果他们检查并找到3个电子邮件地址。然后再次将其设置为限制并强制他们要求手动提交或其他内容。

看看上面的建议如何适合您,任何问题都可以随意询问。但是可能需要一两天才能回复周末。还要研究Captcha脚本如何为他们提供大量的源代码..因为他们的工作理念相同。

时间延迟看起来很糟糕/使您的网站看起来很慢/等待用户等待响应。

你需要限制每个会话/ IP地址的查找量。否则总有办法通过这些检查..基本上一旦达到限制..强制用户/ IP /会话等待几分钟/小时并使用Captcha脚本验证它们,因此无法编写脚本...

Javascript安全/隐藏源

虽然你不能真正做到这一点,你可以做某些事情使用带有JS头的PHP页面生成JS ..所以<script src='myjscode.php'></script>这允许PHP检查有效的会话..所以停止外部请求到一定程度..但这对于允许JS仅在成员资格/登录后面可用非常有用。

在这种情况下,多次检查/如果可能的话

根据您的方法,用户是否可以检查他们是否已拥有帐户?如果是这样..你可以将电子邮件检查与其名称/国家/年龄/ dob等结合起来......所以他们需要选择两个或三个正确的匹配值才能从ajax调用中获得检查/响应?

也许不是你的情况,但只是想也会加上这个。


9
投票

您网站上的JavaScript代码在用户的计算机上执行,因此您无法阻止他挖掘您的代码。即使您使用代码混淆器(例如,https://www.javascriptobfuscator.com/),黑客也可以调试您的应用程序并记录发送到服务器的所有请求。

安全相关的一切都必须在服务器上进行。您可以限制来自特定IP地址的请求数量。


1
投票

你可以使用与CSRF tokens类似的东西防止暴力攻击:

为每个客户端会话分配服务器生成的ID。每次向check.php提出的请求都应包含此ID。

check.php应拒绝不包含ID的请求,或者包含服务器未生成的ID(以防止使用欺骗ID进行攻击)。它还应该对ID进行速率限制 - 如果给定的ID在(比方说)最后一秒发出请求,或者给定的ID在10秒的时间间隔内发出超过n的请求,它应该返回错误响应。这可以防止来自多个IP地址的单个会话的请求。

您还应该按IP地址限制速率,以通过打开大量Web应用程序会话来防止暴力破解。

您无法阻止攻击者查找特定电子邮件地址的单个或少数 - 这是此类验证的固有风险。


0
投票

这种类型的攻击可以像任何其他暴力攻击一样对待,其中唯一有效的解决方案是使用Captcha。但是当然,Captchas对用户体验不利,所以你必须考虑额外的安全性是否值得,特别是对于不太可能发生的攻击。也就是说,您可能希望在注册表上使用Captcha,以防止机器人创建帐户。

这种攻击对于攻击者来说几乎没有奖励。有数十亿个可能的电子邮件地址需要测试。如果有问题的网站特别敏感,例如某种成人网站,攻击者希望勒索他发现的用户,那么这样做是非常值得的。

CloudFlare的

不如Captcha解决方案,但CloudFlare的DDoS系统可能会检测到并阻止暴力攻击。此外,CF可以强制Tor用户在访问您的站点之前解析Captcha,这可以防止攻击者使用Tor作为攻击的载体。

IP速率限制

基于IP的速率限制存在问题,因为如果攻击者决定承担如此大的任务,他可能会使用Botnet或其他多台计算机系统来发动攻击。

考虑一个大型组织,例如大学,所有用户共享公共IP。其中一个用户在您的网站上发起攻击,并阻止他的IP,并在阻止其他人的进程中。这种对策实际上可以用于发动DoS攻击。

会话ID / CSRF令牌

绝对不是解决方案,因为攻击者需要首先向页面发出请求,以获取令牌。这是一个额外的请求,但只给攻击者带来不便。


0
投票

首先:我对邮件地址进行URL编码。 'example.com/check.php?email=' . urlencode([email protected])

广告你的问题:当调用check.php时,你可以

  • 检查,如果用户的会话和他的IP在最后几秒内发送了请求
  • 如果没有,将用户的会话,用户的IP加上当前时间戳写入帮助程序表加上cookie并点击数据库
  • 如果是,则阻止该请求

但我担心这不会帮助你免受欺诈,因为每个人都可以检查你的JavaScript,如果有人想要利用这个,他会找到方法。


-1
投票

check.php应该取决于设置,只能在内部访问,或验证连接的位置。看一下上一个问题 - 我希望它可能是您正在寻找的。 how to verify the requesting server in php?


-1
投票

你可以使用CSRF token并从你的脚本中提前退出,如果你发现没有或无效的CSRF token。几乎(如果不是全部)PHP框架都支持这一点。

另请查看来自安全社区的问题:https://security.stackexchange.com/questions/23371/csrf-protection-with-custom-headers-and-without-validating-token


-1
投票

解决此问题的一种方法可能是:

假设您有ajax请求,请求您的服务器接收来自特定用户或客户端的响应。您可以在数据库中拥有一个表,为每个用户或散列值提供唯一标记,每次用户向服务器发出ajax请求时都可以检查该标记。如果令牌值与用户请求值匹配,则他是真正的用户。您还可以在桌面上记录他的请求数量,以确保他提出合法请求。我承认它可能会降低您的应用程序性能,但这是安全的选择。注意:您需要在HTML页面上检索令牌以使用ajax发送它。

请评论以了解更多信息。我一直在使用这种方法,直到现在都没有问题。

例:

© www.soinside.com 2019 - 2024. All rights reserved.