我目前正在开发一个网站所有者可以安装的脚本,该脚本允许用户突出显示一个单词,并在一个小弹出div中查看该单词的定义。我只是在业余时间做这个业余爱好而无意出售它或任何东西,但我仍然希望它是安全的。
当文本突出显示时,它会向我的域发送一个AJAX请求到一个PHP页面,然后在数据库中查找该单词并输出包含该信息的div。据我所知,同源策略禁止我使用普通的AJAX完成此操作,但我也不能使用JSONP,因为我需要返回HTML,而不是JSON。
我研究过的另一个选择是添加
header("Access-Control-Allow-Origin: *");
到我的PHP页面。
由于我真的没有太多的安全经验,因为我这样做是为了一个爱好,有人可以向我解释使用Access-Control-Allow-Origin:*的安全风险吗? 或者我有更好的方法来做这件事吗?
答案 0 :(得分:2)
Cross-Origin Resource Sharing (CORS),Access-Control-Allow-Origin
标头字段后面的规范,是为了通过XMLHttpRequest允许跨源请求而建立的,但通过提供一个接口来保护用户免受恶意网站的攻击允许server to define which cross-origin requests are allowed and which are not。因此,CORS不仅仅是Access-Control-Allow-Origin: *
,这表示允许来自任何来源的XHR请求。
现在提出您的问题:假设您的服务是公开的并且不需要任何身份验证,使用Access-Control-Allow-Origin: *
来允许来自任何来源的XHR请求是安全的。但请确保仅在您希望允许该访问策略的那些脚本中发送该标头字段。
答案 1 :(得分:1)
JSONP应该符合您的需求。它是一种广泛部署的Web技术,旨在解决跨域问题。您还应该了解CORS,它解决了JSONP的一些缺点。我给你的链接还将包含有关这些技术的安全注意事项的信息。
您写道:
但我也不能使用JSONP,因为我需要返回HTML,而不是JSON。
为什么不呢?您可以使用这样的JSONP响应:
callback({'content':'<div class="myclass">...</div>'});
然后使用DOM操作将result.content
注入当前页面。
答案 2 :(得分:1)
“当文本突出显示时,它向我的域发送一个AJAX请求到一个PHP页面,然后在数据库中查找单词并输出包含信息的div。我知道同源策略禁止我完成这与普通的AJAX,但我也不能使用JSONP,因为我需要返回HTML,而不是JSON。“
正如hek2mgl所说,JSONP可以正常工作。您需要做的就是将您的HTML包装在JSONP包装器中,如下所示:
displayDefinition({"word": "example", "definition": "<div>HTML text...</div>"});
其中displayDefinition()
是一个JS函数,它显示一个带有给定HTML代码的弹出窗口(并且可能会将其缓存以供以后使用)。
“我调查的另一个选项是将
时的安全风险header("Access-Control-Allow-Origin: *");
添加到我的PHP页面。因为我真的没有太多的安全经验,因为我这样做是为了一个爱好,有人可以向我解释使用Access-Control-Allow-Origin: *
?
风险与JSONP基本相同;在任何一种情况下,你都允许任何网站对你的脚本做任意的GET请求(他们实际上可以做到这一点)并读取结果(使用普通的JSON,他们通常不能,尽管旧的浏览器可能有一些安全漏洞,可以允许这个)。特别是,如果用户在登录您的站点时访问恶意网站,并且您的站点可能通过JSONP或CORS公开敏感用户数据,则恶意站点可以访问此类数据。
对于您描述的用例,任何一种方法都应该是安全的,只要您只将它用于该特定脚本,并且只要脚本只执行您所描述的操作(查找单词并返回其定义)
当然,对于您不希望任何网站访问的脚本,您也不应该使用CORS或JSONP,例如银行转帐表单。这些脚本,如果他们可以修改服务器上的数据,通常还需要使用额外的防御措施,如anti-CSRF tokens,以防止“盲目”的CSRF攻击,攻击者并不真正关心响应,而只是关于侧面请求的效果。显然,反CSRF令牌本身就是敏感的用户特定数据,因此不应通过CORS,JSONP或绕过同源保护的任何其他方法获得。
“或者我有更好的方式来做这件事吗?”
另一种方法(尽管不一定更好)可以让您的PHP脚本将定义作为HTML返回,并且弹出窗口只包含指向脚本的iframe
元素。
答案 3 :(得分:0)
CORS问题很简单 - 您是否希望任何人能够远程AJAX您的域名?如果您的表格容易出现CSRF,这可能会非常危险。这是一个直接从我脑海中拔出的例子。
设置:
A&lt; - &gt; B对话被视为合法。但是,如果黑客可以设法使标记(B)加载一个可以触发AJAX请求的JS(通过大型网站上的永久XSS漏洞很容易),他/她可以让B向A发起请求通过JSON,被允许并被视为正常请求!
你可以做这么多可怕的事情。想象一下,银行的表格输入如下:
POST:
* targetAccountID -> the account that will receive money
* money -> the amount to be transferred
如果标记已登录,我可以注入:
$.ajax({ url: "http://A/money.transfer.php"; data { targetAccountID: 123; money: 9999; }; });
突然之间,访问该网站并登录到A的任何人都会看到他们的帐户耗尽了9999个单位。
这个是为什么CORS需要少量盐 - 实际上,不要打开超过你需要打开的东西。打开你的API就是这样。
很酷的一面,在IE9之前,CORS不起作用。因此,您需要构建一个后备,可能是iframe或JSONP。
我在不久前写过这个话题:http://www.sebrenauld.co.uk/en/index/view/access-json-apis-remotely-using-javascript顺便说一下比维基百科更快乐的形式。这是我心中所珍视的话题,因为我不得不多次与API开发竞争。
答案 4 :(得分:0)
CSRF(跨站点请求外观)的概念可能是您关心的问题
http://en.wikipedia.org/wiki/Cross-site_request_forgery
有多种方法可以限制此问题,最常用的技术是使用csrf token
。
此外,您还应该将基于IP的Rate limiter
用于“限制执行从某个IP发出的号码请求”,以限制如果您是目标可以执行的DoS攻击,您可以寻求一些来自How do I throttle my site's API users?