Discord window.localStorage 未定义。如何访问 Discord 页面上的 localStorage?

sxf*_*x8o 9 javascript local-storage discord

当我window.localStoragehttps://stackoverflow.com它上面运行时返回,localStorage但是当我在 Discord 页面上使用相同的命令时,它undefined每次都会返回。

Discord 是否正在采取措施将其localStorage从客户端中删除?如果是这样,有没有办法localStorage在删除之前更改它,防止它被删除或以任何其他方式在它被删除之前以某种方式访问​​它undefined

有什么帮助吗?

Sem*_*lon 23

您仍然可以通过编程方式获取访问权限。他们已经删除了window.localStorage。这是窗口实例的自有属性,但它不是数据属性,而是访问器。访问器的get函数将返回localStorage与任何合适的接收器 ( thisarg)*相关联的值。删除localStorage访问器对对​​象本身是否存在没有影响,因此再次访问它所需要做的就是找到另一个get localStorage()函数。幸运的是,您可以通过多种方式获得——每个 Window 对象都使用一种方式创建。

// If we create an <iframe> and connect it to our document, its
// contentWindow property will return a new Window object with
// a freshly created `localStorage` property. Once we obtain the
// property descriptor, we can disconnect the <iframe> and let it
// be collected — the getter function itself doesn’t depend on
// anything from its origin realm to work**.

function getLocalStoragePropertyDescriptor() {
  const iframe = document.createElement('iframe');
  document.head.append(iframe);
  const pd = Object.getOwnPropertyDescriptor(iframe.contentWindow, 'localStorage');
  iframe.remove();
  return pd;
}

// We have several options for how to use the property descriptor
// once we have it. The simplest is to just redefine it:

Object.defineProperty(window, 'localStorage', getLocalStoragePropertyDescriptor());

window.localStorage.heeeeey; // yr old friend is bak

// You can also use any function application tool, like `bind` or `call`
// or `apply`. If you hold onto a reference to the object somehow, it
// won’t matter if the global property gets deleted again, either.

const localStorage = getLocalStoragePropertyDescriptor().get.call(window);
Run Code Online (Sandbox Code Playgroud)

如果这是一场军备竞赛,有兴趣隐藏 localStorage 的一方可以尝试修补整个 DOM 中的每个方法和访问器,这些方法和访问器可以返回对 localStorage 属性尚未删除的窗口对象的引用。这比显而易见的更难做到。然而,即使他们成功了,最终决定权仍将留在用户端:浏览器扩展的清单可以声明一个内容脚本,当文档加载时,该脚本将在任何其他代码之前进行评估。即使是 CSP 也无法阻止它。(一方面这很糟糕……另一方面,如果没有这种功能,广告拦截扩展将永远无法工作。)

Storage API,无论是 sessionStorage 还是 localStorage,都不是用来保存敏感数据的。它根本不受保护。试图隐藏它暗示它可能会被滥用——如果作者认为删除该属性会提供某种安全性,您可能需要小心在该站点上输入敏感数据。

* 这里合适的接收器是任何没有被用户禁用存储的窗口对象(例如 Safari incognito)并且具有“非不透明”来源(意味着例如它在浏览器about:blank页面中不起作用,因为存储需要与正常来源相关联)。

旁白:关于全球品牌属性的奖励古董。

**反正一般不依赖本源境界。但是,当接收者为空或未定义时,从 [Global] 接口上的 Web IDL 属性创建的属性可以表现出独特的行为,其中原始领域可能变得重要。如果我们在没有接收器的情况下调用get函数,例如

const { get } = getLocalStoragePropertyDescriptor();
get(); // ... null?
Run Code Online (Sandbox Code Playgroud)

...然后它会返回 null,而不是像典型的那样抛出 TypeError。事实上,所有平台属性,不仅仅是 [Global] 接口上的属性,都有一个默认接收器。如果给定的接收器为空或未定义,则默认接收器是创建函数的领域的全局对象。[Global] 情况的不同之处在于,这个默认值实际上可以并且通常是一个有效的接收器——即它可以是一个真正实现了其属性 this 的接口的对象(任何其他函数最终仍会抛出相同的类型错误,所以你永远不会知道这个默认接收器)。

在那个例子中,它默认为来自原始 iframe 的 window 对象。它试图抓取它的localStorage对象,但因为 iframe 早已不复存在,它反而返回 null。我实际上不确定最后一个行为是在哪里指定的。我猜它实际上没有指定,因为它与属性的 IDL 定义相矛盾。不过这是有道理的(它必须做点什么),这就是 Chrome 所做的。在 Firefox 中,尝试这样做会导致内部引擎错误,这表明这种边缘情况可能没有得到很多考虑。


小智 1

在reddit上找到的。TL;DR,他们将 window.localStorage 移动到另一个变量,然后删除 window.localStorage。

我发现获取 localStorage (尽管手动)的一种方法如下:

1:转到%AppData%/discord/Local Storage/

https_discordapp.com_0.localstorage2:在SQLite Studio中打开

3:转到https_discordapp.com_0 > Tables > ItemTable并双击它。

4:在Data选项卡下双击一个值并读取/转换十六进制数据,删除所有其他00十六进制。