使用jQuery Ajax存在安全风险

11

这是一个困扰我一段时间的问题,所以我正在寻求意见和解决方案来防止应用程序成为安全风险。

我使用jQuery进行许多事情,但主要用于处理jQuery对话框窗口。很多时候需要从表单字段中获取值,将该信息与.serialize()命令连接起来,并将其传递给jQuery ajax调用,以便通过PHP文件进行数据库交互。

我的问题是:

猜测PHP处理的URL难度是否过低?
您可以在现代浏览器中打开源代码并单击链接以查看包含ajax调用的完整JavaScript文件。

我可能可以通过压缩JavaScript文件来进行混淆,但这不是可靠的安全形式。

我正在使用PDP进行数据库访问,并使用准备好的语句来防止SQL注入攻击,但如果有人花时间查看,他们不能只是形成有效的url并将其发送到数据库中插入他们想要的内容吗?

我不是在谈论黑客攻击数据库以窃取信息,我更多地是谈论如何像应用程序自身添加数据一样插入恶意信息。 想象一下将$ 50的物品添加到购物车中,只需支付$ 25。

如果将ajax请求从GET更改为POST并更改我的PHP文件,是否就是这样简单?

编辑:该人已登录并获得适当的身份验证。

我只想知道其他人都做了些什么。

谢谢!


相关:https://dev59.com/W3VC5IYBdhLWcg3wvT1a - Rob W
我只是好奇,为什么选择PHP?大多数情况下,当我想要调用数据库时(我使用MVC3),我会让调用转到控制器,并从那里对其进行处理。就个人而言,我可以想到两种可能性。如果您有一个通过ajax将信息发布到数据库的调用,最好的方法是为您想要进行的任何调用添加一次性密钥。这将在一定程度上保护它。您需要做的就是在调用被执行之前不要让密钥可见,然后就完成了。嗯,我需要更深入地思考这个问题。 - John Sykor
这不是一个“jQuery ajax”问题,也不是一个jQuery问题,更不是一个ajax问题,而是一个“用户可以伪造整个客户端”的普遍问题。@John Sikora - 为什么不用PHP?数据库访问仍然在服务器端进行,相当于您在MVC3中所做的操作。 - nnnnnn
在MVC中,如果你只是简单地提交了一个表单,我不知道你如何通过控制器和模型将恶意内容存入数据库,因为它们不知道它是如何被处理的,除了在框中的内容,它们不能修改模型,此外,它仍然应该经过验证器的验证。我只是想知道漏洞在哪里?除了任何白痴都可以向你的数据库添加数十亿行之外? - John Sykor
3
我不明白为什么人们认为Ajax应该以任何形式掩盖客户端与服务器的交互,它只是一种与服务器通信的方法,仅仅是一个接口而已。如果您的后端是安全的,使用Ajax并不会改变任何东西,您的网站也是安全的,无论如何与后端进行通信。您是否担心购物车中价格的更改?我建议您根本不要处理任何由客户端提供的价格,只需使用ID并从数据库中检索价格即可... - cyber-guard
6个回答

15

您说得很对,稍微懂一点技术的人都可以识别任何web应用程序的公共服务器端点。他们甚至不需要查看代码,可以使用他们的webkit/firebug跟踪请求,或者像Charles这样监视网络活动的程序。

这就是为什么你需要在服务器端代码中处理身份验证授权的原因。

身份验证通常是由用户名和密码处理的,它是验证用户身份的行为。

授权可以通过服务器上的角色来处理,并检查用户是否能够完成他们想要完成的操作。

有了这两种机制,即使用户知道URL,他们仍然需要“登录”并具有执行他们想要执行的操作的权限。

想一想,如果您在线查看银行账户信息,您可以轻松识别加载您账户信息的请求。没有这些机制,有什么能防止您简单地更改传递给服务器的账户ID以尝试获取其他人的账户信息呢?有了身份验证/授权,服务器知道即使它收到一个请求来加载某些数据,它也可以检查用户的详细信息以查看他们是否有权限获取该数据并拒绝请求。


10
即使你从GET方式改为POST方式,任何有兴趣的人仍然可以很容易地查看(并更改)发送到你的服务器的任何参数。但问题在于:即使你根本不使用AJAX而只是使用传统的表单,也极其容易查看和编辑发送到服务器的任何参数。
在关键情况下,你永远不能完全依赖于客户端发送过来的数据。
例如,如果你想向购物车中添加商品,则仅需将商品ID和数量传递给服务器,不要从客户端获取价格详细信息,而是从数据库获取。如果有人试图攻击你并编辑发送的商品ID或数量,则最糟糕的结果就是他们会购买自己不想要的东西;这完全是他们的问题。(但出于同样的原因,如果是限时优惠,你需要验证所接收到的数量是否超过了任何一个客户能够购买的限制)
所以说,归根结底,你作为开发者必须决定你希望用户控制哪些值,并在服务器端验证是否接收到了超出用户应该能够执行的操作范围的请求。

3
你永远不能依赖任何来自客户端的操作或数据,不仅仅是与jQuery有关。您必须在服务器端处理各种安全问题。始终仔细检查来自用户的数据(一个用于减少性能请求数量的客户端,另一个用于实际确认的服务器端)。请求类型(GET或POST)实际上并不重要,它可以很容易地被模拟。当用户试图为25美元添加50美元的商品时,您应该检查您的数据库并确认商品的实际价格。

我同意。这只是一个基本的示例,试图说明一点。 - Kris.Mitchell
我知道,这只是一个基本示例的基本建议 :) - SadullahCeran
我同意,如果我曾经传递定价信息,我已经感觉到它是不安全的。如果价格或账单总额被传递,您会希望对其进行加密,以便不能随意添加一个随机数字并检查物品与价格。否则,最有效的方法是始终将值保留在服务器端,并从客户端中获取购买的物品并为其收费。此外,您显然不希望在最终确认后修改列表中的产品。只有当他们回到上一步并添加或删除产品时才能这样做。 - John Sykor

2

是的,您需要服务器端安全性来验证发送到服务器的每个数据。例如,您可以在javascript / jquery中验证数据:

if($(this).val() != ""){
   // post to my server page (mypage.cfm/php/asp)
}

但是如果您不保护服务器页面,我可以轻易地向您的服务器发布空数据并避免JavaScript。因此,您需要使用另一个验证脚本来保护服务器页面,例如:

<cfif val is "">
  //dont post to my server ...
</cfif>

有时候这是一项双重工作,但我们都会有时面对它....


2

数据库的风险通常包括:恶意数据、SQL注入和CSRF。

缩小/混淆你的JavaScript可能会有所帮助。但是,无论你做什么,用户都可以轻松捕获自己的请求数据。而且没有明确的方法可以防止用户查看混乱的代码。

只有当用户无法黑掉你时,安全才是真正的安全,即使他们知道你的所有源代码和配置。

安全没有简单的解决方案。以下是一些通用的实践,可避免大多数情况下出现问题:

使用HTTPS和POST请求。 通过HTTPS进行POST请求,请求数据将被加密。URL会被暴露,但通常没问题。这可以防止中间人攻击,并大大减少隐私问题(例如密码/信用卡泄漏)。 如果使用GET请求,所有数据都将作为查询字符串传递到URL中。这意味着第三方有很大机会更改您的数据。

服务器端验证 始终在服务器端验证数据。用户可能是恶意的,客户端可能存在错误。例如,在服务器端计算总价格,而不是在客户端计算。否则,用户可能会输入0。

访问权限控制AKA授权 限制允许的操作,并限制其有效范围。例如,不要允许用户代表其他人下订单。不要让他们删除他们的操作历史记录。

生成令牌以防止CSRF 一些库可以防止CSRF。或者你可以自己实现。主要概念是生成一个随机令牌并请求客户端将其传回。这可以防止其他网站使用你的客户凭据触发请求到你的服务器。

适当的备份和日志记录 定期备份数据库有助于从灾难中恢复(是的,它们会发生)。通过日志模块跟踪用户的操作记录。


2

您绝不能以这种方式编写代码,因为价格是单独从客户端传输的,任何人都可以发送价格为0或0.01的数据,而不管商品/服务的数量。

更一般地说:永远不要相信客户端数据。


我同意,只是用那个例子作为一个非常基本的例子。 - Kris.Mitchell
2
如果有人花时间查看,他们不是可以形成一个有效的URL,将其发送到数据库并插入他们想要的内容吗?是的,他们可以。而且他们会这样做。 - kirilloid

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接