PageSourceSearch

https://retiola.com/strip-auth-fragment.js

js retiola.com collected 2026-10-02 01:40:59 UTC 2,035 bytes, 61 lines download raw bytes

1/**
2 * Remove auth tokens from the URL fragment before anything else can read them.
3 *
4 * Supabase falls back to the project's Site URL when a redirect target is not
5 * on its allowlist, and that fallback delivers the session in the fragment —
6 * so a misconfigured or stale redirect (an unpacked extension whose id is not
7 * allowlisted, an old link, a copied URL) can drop a live access token on an
8 * ordinary marketing page. Those pages load React and Babel from unpkg, and
9 * any third-party script on the page can read location.hash.
10 *
11 * This runs as the first script on every page that has no business seeing a
12 * token. auth.html and reset-password.html legitimately consume the fragment
13 * and therefore must NOT include this file.
14 *
15 * Only auth-shaped parameters are removed; ordinary anchors are left alone so
16 * in-page links keep working.
17 */
18(function () {
19    var hash = window.location.hash || '';
20    if (hash.length < 2) return;
21
22    var AUTH_KEYS = [
23        'access_token',
24        'refresh_token',
25        'provider_token',
26        'provider_refresh_token',
27        'id_token',
28        'expires_in',
29        'expires_at',
30        'token_type',
31        'error',
32        'error_code',
33        'error_description',
34    ];
35
36    var params;
37    try {
38        params = new URLSearchParams(hash.replace(/^#/, ''));
39    } catch (_e) {
40        return;
41    }
42
43    var carriesToken = false;
44    for (var i = 0; i < AUTH_KEYS.length; i += 1) {
45        if (params.has(AUTH_KEYS[i])) {
46            carriesToken = true;
47            params.delete(AUTH_KEYS[i]);
48        }
49    }
50    if (!carriesToken) return;
51
52    var rest = params.toString();
53    var cleaned = window.location.pathname + window.location.search + (rest ? '#' + rest : '');
54    try {
55        window.history.replaceState(null, '', cleaned);
56    } catch (_e) {
57        // replaceState can throw in exotic embedding contexts; clearing the
58        // fragment directly still removes the token from the visible URL.
59        window.location.hash = '';
60    }
61})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.