如何在 JavaScript 中访问通过 <script type="text/plain" src=...> 检索到的纯文本内容?

IT技术 javascript text xss
2021-02-24 08:54:07

使用 时<script type="text/plain" src="http://..."></script>,其中 URL 指的是纯文本文件,有没有办法在 JavaScript 中访问文件的内容?文件被传输到浏览器,但元素innerHTML属性script没有改变(它仍然是空字符串)。检查 DOM 中的元素节点似乎没有揭示可以找到接收到的内容的任何属性。

我知道可以改用 XMLHTTPRequest,但我对为什么浏览器以我描述的方式获取数据但似乎不提供任何访问权限的问题感兴趣。

4个回答

首先, 的text属性HTMLScriptElement是访问内联<script>元素文本的首选方法DOM-Level-2HTML5: 4.11.1都表明脚本应该有一个text包含脚本内部文本的属性

IDL 属性text必须script以树顺序返回作为元素元素的所有 Text 节点的内容的串联(忽略任何其他节点,例如注释或元素)。在设置时,它必须以与textContentIDL 属性相同的方式起作用

由于<script>元素为空(您指定了外部源)texttextContentinnerHTML为空。这是因为该text属性仅在内联脚本中设置:

如果脚本是内联的并且脚本块的类型是基于文本的语言:

text上次设置元素的“已启动”标志时 IDL 属性的值是脚本源。

所以不可能text/plain使用这种方法包含外部

也可以看看:

  • W3C:HTML5:4.11.1 脚本元素:文本属性和游戏地图示例:
    <script src="game-engine.js"></script> <!-- game engine isn't inline -->
    <script type="text/x-game-map"> <!-- but data needs to be inline -->
    ........U.........e
    o............A....e
    .....A.....AAA....e
    .A..AAA...AAAAA...e
    </script>
    
这听起来很有说服力。它并不能证明无法访问加载的内容,但它使这很有可能。正如@toofast 所提到的,Chrome 甚至没有加载它。
2021-04-17 08:54:07

请注意,如果支持此功能,它将提供一个巨大的安全漏洞和一种绕过保护 json 和其他数据的跨站点脚本保护的方法。本质上,我讨厌的网页(例如nasty.com)可以通过使用脚本标签加载来访问受cookies 保护的私人数据。例如

<script type="text/plain" 
       src="https://supersecure.com/youraccount/privatedocs/list"/>

由于 supersecure.com 的 cookie 将自动与请求一起发送(就像请求任何资源时的情况一样),安全站点只返回数据(例如私有文档列表),因为它不能轻易区分请求来自其合法网页的ajax请求之一。ajax 不存在这个漏洞,因为浏览器将简单地阻止来自 nasty.com 的页面向 supersecure.com 发出 ajax 请求,这要归功于同源策略。

显然,内联数据不存在安全问题。

经过几天对同一问题的研究,我发现了对以下代码的几个引用:

<html>
<head>
  <script type="text/javascript">
    function init() {
      var extText = window.frames.messageTxt.document.body.lastChild.lastChild.data;
      extText = extText.replace(/[\r\n]/g, " ");
      document.forms[0].nMessage.value = extText;
    }
    window.onload = init;
  </script>
</head>
<body>
  <iframe name="messageTxt" src="txtData.txt" style="display:none"></iframe>
  <form>
    <textarea name="nMessage"></textarea>
    <input type="button" value="click" onClick="init()">
  </form>
</body>
</html>

上面的代码确实访问了 txtData.txt 文件(假设它存在)并将其转储到 a<textarea>作为默认文本。出于某种原因,上面的回答都没有提到这是有效的,我假设是因为这个问题似乎<src>特别暗示了标签(对于类似的技术可能不可用;我没有检查过);但是,我仍然认为值得一提的是,假设您的查询涉及获取外部 .txt 文件的更普遍的问题(或者如果遇到此页面的其他人正在寻找所述问题的答案),主要是因为我花了几个小时研究它,所以我相信答案很难产生是有道理的。

你是对的,我的问题反映了一个更普遍的问题,使用iframe是一种有趣的方法(尽管它不适用于本地文件的 Chrome,并且它通常受到跨域限制——实际上,就像“带有 HTML 嵌入的 Ajax light”)。这里的赋值extText是最重要的代码——为了获取文本内容,剩下的取决于我们想用它做什么。
2021-05-12 08:54:07

是的,不,我认为您无法获得那样的文本内容。这主要是因为您将使用 dom 访问元素来获取一些从未真正注入 dom 本身的文本。

我尝试了几个选项,但它们都不起作用。我没有充分的理由为什么你找不到它,但我放弃/这样思考的原因是因为即使我使用的 WebKit 检查器也没有三角形披露在 script-src 标签旁边。它所做的是将 src 转换为您可以单击的链接,然后它使用 Ajax 或其他任何方式从服务器读取该文本。