javascript和同源策略混淆
Posted
技术标签:
【中文标题】javascript和同源策略混淆【英文标题】:java script and same origin policy confusion 【发布时间】:2013-06-19 12:44:19 【问题描述】:我正在尝试了解浏览器的同源策略。从理论上讲,事情似乎还可以。所以我现在正在尝试使用一个小演示来实际理解它。
我在 wamp 上托管了 2 个域,即 domain1.com 和 domain2.com
domain1.com 由 index.php、innocent.php 和 javascript 文件夹中的 2 个 js 文件组成,即 dom1_javascript.js 和 dom1_normal.js
以下是上述文件的详细信息:-
index.php
<?php
$value = "domain 1 cookie";
// send a simple cookie
setcookie("Dom1Cookie",$value);
?>
<html>
<script type="text/javascript" src="../javascript/dom1_javascript.js">
</script>
<body>
this is from doamin 1
</body>
</html>
innocent.php
<?php
$userSecret=$_GET['userCreds'];
if($userSecret)
echo "the user's secret is "+$userSecret;
else
echo "sorry user secret not found";
?>
dom1_javascript.js
alert(document.cookie);
dom1_normal.js
alert("alert domain 1");
alert(document.cookie);
//referring the div
var bdy=null;
// creating the form
var secretForm=document.createElement("form");
secretForm.id="goodForm";
secretForm.method="get";
var myQryStr="http://domain1.com/innocent.php?userCreds=abcd";
alert(myQryStr);
secretForm.action=myQryStr;
//creating the text box in the form
var hiddenBox=document.createElement("input");
hiddenBox.type="text";
hiddenBox.name="secBox";
hiddenBox.value="abhinav";
//appending the box to the form
secretForm.appendChild(hiddenBox);
//appending the form to the div
bdy=document.getElementById("mydiv");
alert(bdy);
bdy.appendChild(secretForm);
//submitting the form
document.getElementById("goodForm").submit();
domain2.com 包含两个版本的 index.php,即 index.php 和 index1.php
这里是上述 php 文件的详细信息:-
index.php
<?php
$value = "domain 2 cookie";
// send a simple cookie
setcookie("Dom2Cookie",$value);
?>
<html>
<head>
<script type="text/javascript" src="http://domain1.com/javascript/dom1_javascript.js">
</script>
</head>
<body>
<div id="mydiv">
<img src="http://domain1.com/images/dom1.bmp"/>
this is from doamin 2
</div>
</body>
</html>
index1.php
<?php
$value = "domain 2 cookie";
// send a simple cookie
setcookie("Dom2Cookie",$value);
?>
<html>
<head>
<script type="text/javascript" src="http://domain1.com/javascript/dom1_normal.js">
</script>
</head>
<body>
<div id="mydiv">
<img src="http://domain1.com/images/dom1.bmp"/>
this is from doamin 2
</div>
</body>
</html>
我使用 firefox 作为浏览器来测试这些脚本。 首先,我在浏览器中转到 domain1.com。这将设置 domain1 cookie。然后我转到 domain2.com/index.php 正如预期的那样,domain2/index.php 上的脚本设置了 domain2 cookie。然后来自 domain1 的 javascript 被加载,上面写着
alert(document.cookie)
此脚本的执行会提醒 domain2 cookie 值。
假设1:- 所以我在这里的理解是,由于浏览器的同源策略,即使从domain1调用脚本,它也没有警告domain1 cookie,而是警告domain2 cookie。
如果我在上述假设中正确,请告诉我?
现在我清除浏览器缓存并从浏览器中删除所有 cookie。再次运行 domain1.com,这将再次设置 domain1 cookie。然后,这次我转到 domain2.com/index1.php,它为 domain2 设置 cookie,然后访问
中的脚本domain1.com/javascript/dom1_normal.js
现在,如果我的假设 1 是正确的,(即在 domain2.com 中导入时来自 domain1.com 的 javascript 将仅参考 domain2 执行,而不是其传入域,根据相同的来源策略)然后在这种情况下它也应该与 dom1_normal.js 相同。所以 dom1_normal.js 中的 javascript 应该可以访问 domain2/index1.php 中的所有 HTML 元素。正如
所证实的那样,它并没有真正发生bdy=document.getElementById("mydiv");
alert(bdy);
在 domain1.com/javascript/dom1_normal.js 中提示 null
请让我知道我哪里出错了。而且我经历了十多次讨论(关于堆栈溢出和其他地方,包括 MDN、wiki、google 等)和关于同源策略的文章,但没有一个让我明白这个想法。
【问题讨论】:
【参考方案1】:同源策略与加载 JavaScript 没有太大关系。无论脚本来自何处,其操作都发生在主页的 aegis 域下。因此,如果您的主页来自“domain1”,那么所有脚本都在“domain1”的上下文中执行,无论它们来自该域还是任何其他域。
请注意,无法访问从其他域加载的脚本的源代码。
您的“dom1_normal”脚本为该元素引用报告“null”的原因可能是因为您在<body>
之前导入脚本。 DOM 是增量构建的,但脚本在加载时会同步运行,因此如果您为 <script>
标记 之后 标记的某些元素调用 getElementById()
,它将不存在。
【讨论】:
(实际上我认为你无法获取通过“src”属性加载的任何脚本的来源。我现在发烧了,所以我不认为我会尝试:/) "神盾" ?谁会得到那个? “在范围内”而不是“在盾牌下”怎么样;) @mplungjan 老实说,我在这句话上苦苦挣扎:-) @geek_ji 查看我的编辑 - 这可能是因为您将它导入到<head>
中。脚本在加载后立即同步运行,因此如果您在 <body>
之前执行此操作,则该元素将不可用,因为解析器还没有看到它。
@geek_ji 因为这就是 Web 浏览器的工作方式 :-) 在 DOM 构建过程中同步获取和评估脚本。如果您将“index1.php”中的<script>
标记移到正文结尾之前(就在</body>
之前),那么它将起作用。以上是关于javascript和同源策略混淆的主要内容,如果未能解决你的问题,请参考以下文章