通过 <script> 标签加载到网页中的 JavaScript 文件的源代码是不是可以被该页面中的其他 JavaScript 读取?

Posted

技术标签:

【中文标题】通过 <script> 标签加载到网页中的 JavaScript 文件的源代码是不是可以被该页面中的其他 JavaScript 读取?【英文标题】:Can the source of a JavaScript file loaded into a web-page via a <script> tag be read by other JavaScript in that page?通过 <script> 标签加载到网页中的 JavaScript 文件的源代码是否可以被该页面中的其他 JavaScript 读取? 【发布时间】:2013-03-09 06:38:09 【问题描述】:

我正在研究 CSRF 预防,我有一个关于返回 JSON 的 GET URL 的问题,以及该 URL 返回的数据是否可以通过第三方网页访问。

例如假设这个请求

GET HTTP 1.1 /rest/foo.js 
Host: myhost.com

返回动态生成的 JSON,如下所示,每个会话都有一个 CSRF 令牌:

user:"My name", userId:1234, CSRFToken: "EFB8765AC2134ACB23486"

请注意,这不是 JSONP 请求。现在,假设我在sneakythirdparty.com 上有一个网页,内容如下:

<html>
  <head>
    <script language="javascript" src="http://myhost.com/rest/foo.js" />
  </head>
  ...
</html>

我的问题是:第三方网站页面中的脚本、Flash 小程序或其他任何东西是否可以读取 foo.js 的源代码 以获得 CSRF 令牌?

【问题讨论】:

【参考方案1】:

您不必隐藏您的 CSRF 令牌 CSRF 保护的全部目的只是确保对您网站的请求确实来自您的网站(或您可以授权给他们的其他网站)。

所以我真的不明白你在你的例子中想要达到什么目的: 如果您想阻止 foo.js 从另一台服务器调用,您必须强制人们在请求该文件时发送 CSRF 令牌,然后您在服务器中检查此令牌实际上与会话密钥匹配,例如之前设置的验证该用户的会话密钥最初确实来自您的网站。

如果 json user:"My name", userId:1234, CRSFToken: "EFB8765AC2134ACB23486" 是静态写在这个 javascript 中的,那么你就误解了 CSRF 保护的所有概念。

您必须根据一些用户唯一数据(可以是数据库中的数据,可以是会话 ID 等)动态创建令牌,然后在您的站点周围传递令牌并阻止对您想要的页面的请求保护此令牌是否无效/不存在。

CSRF 保护可以通过常规形式和 ajax 调用来完成 - 就像你选择的那样

Good Explanation

【讨论】:

嗨,阿迪迪,JSON 绝对不是静态的,我同意这将是无用的 :-) 我将更新问题以明确这一点。我想确保第三方无法获取通过服务器端 REST 调用检索到的 CSRF 令牌。 嗯 - 答案是肯定的!任何第三方都可以读取 javascript 文件——这就是他们称为客户端文件的原因。如果您想阻止它或控制 json 最终将包含的内容 - 那么您需要检查谁调用了您的文件并根据它进行操作。并且 CSRF 保护在这里会很棒!但是对于那个文件! 我很抱歉,但我认为它没有那么清楚......这是我要询问的具体第三方网页。同源策略应该停止在第三方网页中加载文件,我的问题基本上是是否有任何解决方法,因为它是通过 好吧 - 您可以将您的 json 文件转换为服务器文件并在那里生成它。 (在服务器中,您只需定义响应标头内容类型为 text/javascript) - 然后您将完全控制文件将返回的内容。【参考方案2】:

是的,&lt;script&gt; 标签是有目共睹的。

例如:

var nodes = document.querySelectorAll("script");
var i;
for (i = 0; i < nodes.length; i++) 
    if (nodes[i].hasAttribute('src'))
        console.log(nodes[i].attributes["src"].value);

只需执行一个简单的 XMLHttpRequest 即可获取源并获取 CRSFToken。

编辑:

此方法依赖于CORS 支持,并依赖于假设来自同一客户端(使用相同 cookie)的两个请求对 myhost.com 的响应将使用相同的 CRSFToken。

如果上述任何一项都不成立,则此方法将不起作用。如果“外部”进程(如 Flash 或 Java)可以访问相同的 cookie,理论上它们可以模仿请求并获取 CSRFToken(假设上述第二个条件成立)。

除此之外,如果您不信任用户(或用户的计算机),则可以从内存中获取 CSRFToken,但这似乎超出了您的问题的范围。

【讨论】:

感谢 tjameson 的回复,但这会返回一个 URL 列表,我问的是 URL 的 源代码,而不是脚本的源 URL标签 - 我已经更新了我的问题以澄清这一点。 这很简单,只需使用 XMLHttpRequest 即可。一旦你有了 URL,剩下的就很简单了。当然,我假设从同一个客户端对同一个 URL 的两个请求将产生相同的 CRSFToken。 是的,但是由于同源策略,从sneakythirdparty.com 到myhost.com 的XMLHttpRequest 不起作用。我的问题是,有什么办法可以规避这个问题吗? @Ian 您的 myhost.com 是否支持CORS? 确实如此,但使用它可以完全实现我想要确保在这种情况下是不可能的:-)

以上是关于通过 <script> 标签加载到网页中的 JavaScript 文件的源代码是不是可以被该页面中的其他 JavaScript 读取?的主要内容,如果未能解决你的问题,请参考以下文章

Module 的加载实现

JS代码优化小技巧

es6-Module 的加载实现

js的基础(引入,弹窗,命名规则等)

html css js加载顺序

html,css,js加载顺序