Is Discord Token Login safe?

Medium risk

Discord Token Login signs into Discord from a pasted session token, writing it into local storage and skipping the password and 2FA prompt.

The extension's popup takes a Discord session token typed or pasted by the user and passes it to discord.com as a URL query string. A content script on discord.com reads that token from the URL at page load, clears local storage, and writes the token in as the active session, closing any other open Discord tabs first. Because the token travels in a plain URL rather than an encrypted channel, it is left in browsing history and is readable to any other extension with tabs or history access.

49Risk
Who publishes it

1 other listing from the same operator, none carrying a finding

What this publisher told the store about itself, and the other listings that told it the same thing.

Same store account

1 other listing published from this account, 297 users between them, none of them carrying a finding.

AI-generated. Findings may contain errors. Those marked Verified have been manually reviewed.

Publishers can request a review.

Findings

Popup takes any pasted Discord token and logs that account straight in

Code analysis shows the extension takes any Discord token pasted into its popup, closes open Discord tabs, then writes the token into discord.com's local storage so the browser loads signed into that account with no password or 2FA prompt.

Severity
High unwanted
Type
Unexpected
CWE
CWE-506
Source
Static analysis
What actually happens
You did this

You paste a Discord session token into the extension's popup and click the Login button.

The popup has no field for a username or password, only the token.

The extension did this

The extension closes any open Discord tabs, then opens discord.com with your token in the URL and writes it into that page's local storage.

Discord's own web client reads its session state the same way, so the page loads already signed into whichever account the token belongs to, with no password or 2FA challenge.

What the popup asks for and what it does with it
  • The token you paste in
    MTA1ODY3ODkxMjM0NTY3ODkw.G7Xq9p.k3F8n2vQxYzRstU4WbCdEfGhIjKlMnOpQr

    The same credential Discord's client uses to stay signed in. Anyone holding it can access the account with no password or 2FA code.

  • Where the token is placed
    https://discord.com/?discordtoken=<pasted-token>

    The token is appended in plain text to the discord.com URL the extension opens, then copied from there into local storage on that page.

  • Suggested token source
    https://www.lumao8.com/

    If you lack a token, the popup links to this outside site for one; the extension never checks who a pasted token belongs to.

The code that does this

The three files that move the token from the popup into Discord's session storage

Readable version

Popup submit handler (unminified, shipped as-is)

popup/script.js
if (document.querySelector('.discord-token-login-popup')) {    document.querySelector('#submit').addEventListener('click', () => {        token = document.querySelector('#token').value;        if (token != '') {            document.querySelector('#token').style.border = '1px solid #5865f2';            window.open("https://discord.com?discordtoken="+token, '_blank');        } else {            document.querySelector('#token').style.border = '1px solid #5865f2';        }    })}

Content script (unminified, shipped as-is)

content.js
const queryString = window.location.search;const urlParams = new URLSearchParams(queryString);var discordtoken=urlParams.get("discordtoken")if(discordtoken){	localStorage.clear();	localStorage.setItem('token', `"${discordtoken.replace('"', '')}"`);	window.location.replace('https://discord.com/channels/@me');}

Service worker (unminified, shipped as-is)

background.js
function close_discord(){  chrome.tabs.query({}, function(tabs) {	for(var i=0;i<tabs.length;i++)	{		if(tabs[i].url.replace("discord.com") != tabs[i].url)		{			chrome.tabs.remove(tabs[i].id, function() {})		}	}  });}chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {	if(msg.type=="token")	{		console.log(msg);		close_discord();		setTimeout(function(){			chrome.tabs.create({url: "https://discord.com?discordtoken="+msg.token});			sendResponse(true)			},500)			}		return true;	});
Reproduce it yourself

Recreates the extension's token-to-session flow outside the extension so you can see exactly what it does to a token you control, without installing it.

Requires
  • A disposable Discord test account you control
  • Chrome or Chromium DevTools
discord-token-login-repro.js · js
// Run in a discord.com tab's DevTools console, using a token you obtained// from your OWN account's Application > Local Storage panel (never a token// you did not generate yourself).//// This mirrors popup/script.js + content.js from the extension://   1. popup/script.js: window.open('https://discord.com?discordtoken=' + token)//   2. content.js: reads ?discordtoken=, clears storage, writes the token key,//      then redirects to /channels/@me.function simulateExtensionLogin(token) {  const url = new URL(window.location.href);  url.search = '?discordtoken=' + encodeURIComponent(token);  const urlParams = new URLSearchParams(url.search);  const discordtoken = urlParams.get('discordtoken');  if (discordtoken) {    localStorage.clear();    localStorage.setItem('token', `"${discordtoken.replace('"', '')}"`);    console.log('localStorage token key set. Reload channels/@me to see the effect.');  }}// simulateExtensionLogin('YOUR_OWN_TEST_TOKEN_HERE');
How to run it
  1. 1Copy the 'token' value from a disposable test account's DevTools > Application > Local Storage.
  2. 2Sign that tab out.
  3. 3Run simulateExtensionLogin('<token>') in the console.
  4. 4Reload channels/@me signed in.
Why this only works with a token, and why that matters

Discord's password and two-factor login flow never runs here. The token pasted in is the only input the extension accepts, and it never checks that the token belongs to the person entering it.

Observation

Static analysis finding. This behaviour was identified by reading the shipped extension code and has not yet been reproduced in a live run. The trigger conditions and the exact data sent are read from the code, not from an observed capture.

Updated 22 October 2026jfoencjkgihkcpkjndpondkbpflgaoan