我想使用 post 来更新数据库并且不希望人们手动执行它,即它应该只能通过客户端中的 AJAX 来实现。在这种情况下是否有一些众所周知的加密技巧可以使用?
假设我正在发出一个 GET 请求,将一个新用户插入到我的数据库中site.com/adduser/<userid>
。有人可以通过发出虚假请求来过度填充我的数据库。
在这种情况下,无法避免伪造请求,因为客户端浏览器已经拥有发出请求所需的一切;恶意用户只需进行一些调试即可弄清楚如何向您的后端发出任意请求,甚至可能使用您自己的代码使其更容易。你不需要“加密技巧”,你只需要混淆,这只会让伪造有点不方便,但仍然不是不可能的。
这是可以实现的。
每当您呈现应该发出此类请求的页面时。生成一个随机令牌并将其存储在会话(用于经过身份验证的用户)或数据库中(如果此请求被公开允许)。
如果令牌有效或无效(来自会话或数据库)
,而不是在收到此类请求时调用site.com/adduser/<userid>
call如果
令牌正确,则处理请求并从会话/数据库中删除使用的令牌
如果令牌不正确,则拒绝请求。site.com/adduser/<userid>/<token>
我真的不需要限制对服务器的访问(虽然那会很棒),我正在寻找一种加密技巧,它可以让服务器知道什么时候来自应用程序而不是由用户使用嗅探令牌。
你不可以做这个。这几乎是客户端/服务器应用程序的基本问题之一。这就是它不起作用的原因:假设您有一种方法可以让您的客户端应用程序向服务器验证自己的身份 - 无论是秘密密码还是其他方法。应用程序需要的信息必须是应用程序可以访问的(密码隐藏在某处或其他地方)。但是因为它在用户的计算机上运行,这意味着他们也可以访问这些信息:他们所需要的只是查看源代码、二进制文件或应用程序与服务器之间的网络流量,最终他们会弄清楚您的应用程序验证和复制它的机制。也许他们甚至会复制它。也许他们' 我会编写一个巧妙的 hack 来让你的应用完成繁重的工作(你总是可以向应用发送虚假的用户输入)。但无论如何,他们已经获得了所需的所有信息,并且无法阻止他们拥有它也不会阻止您的应用程序拥有它。
防止直接访问由 ajax 函数调用的文件似乎解决了这个问题。
你可以(在其他解决方案中,我敢肯定)......
但是,如果人们足够努力,任何事情都可能被欺骗。唯一完全安全的系统是任何人都无法访问的系统。
这是与 CSRF 相同的问题 - 解决方案是相同的:在 AJAX 请求中使用一个令牌,该令牌您以前存储在 eslewhere (或可以重新生成,例如通过使用 sessin id 作为密钥加密参数)。Chriss Shiflett对此有一些明智的说明,并且有一个OWASP 项目用于使用 PHP 检测 CSRF
这是一些授权问题:只有授权请求才会导致创建新用户。因此,当收到这样的请求时,您的服务器需要检查它是否来自被授权创建新用户的客户端。
现在主要的问题是如何决定什么请求被授权。在大多数情况下,这是通过用户角色和/或一些票务系统完成的。使用用户角色,您将需要解决其他问题,例如用户识别和用户身份验证。但如果这已经解决,您可以轻松地将用户映射到角色,例如Alice 是管理员,Bob 是普通用户,只有管理员有权创建新用户。
它像任何其他网页一样工作:登录身份验证,检查推荐人。
解决方案是将粗线添加到 ajax 请求中。此外,您应该查看基本身份验证,这不会是唯一的保护者。您可以使用 ajax 页面中的这些代码获取收入
阿贾克斯调用
function callit()
{
if(window.XMLHttpRequest){xmlhttp=new XMLHttpRequest();}else{xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");}
xmlhttp.onreadystatechange=function(){if(xmlhttp.readyState==4&&xmlhttp.status==200){document.getElementById('alp').innerHTML=xmlhttp.responseText;}}
xmlhttp.open("get", "call.asp", true);
**xmlhttp.setRequestHeader("X-Requested-With","XMLHttpRequest");**
xmlhttp.send();
}
PHP/ASP 请求的页面答案
ASP
If Request.ServerVariables("HTTP_X-Requested-With") = "XMLHttpRequest" Then
'Do stuff
Else
'Kill it
End If
PHP
if( isset( $_SERVER['HTTP_X_REQUESTED_WITH'] ) && ( $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' ) )
{
//Do stuff
} else {
//Kill it
}