{
	"id": "f0bf25fd-cb4f-4eb6-ae77-bb265a29dccc",
	"created_at": "2026-04-06T01:31:27.008685Z",
	"updated_at": "2026-04-10T13:12:31.083886Z",
	"deleted_at": null,
	"sha1_hash": "bee818ac7729f47beeae7d4403b1229b90377b8b",
	"title": "What Happens If Your JWT Is Stolen?",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 366885,
	"plain_text": "What Happens If Your JWT Is Stolen?\r\nBy Randall Degges\r\nPublished: 2018-06-20 · Archived: 2026-04-06 00:30:31 UTC\r\nAll of us know what happens if our user credentials (email and password) are discovered by an attacker: they can\r\nlog into our account and wreak havoc. But a lot of modern applications are using JSON Web Tokens (JWTs) to\r\nmanage user sessions—what happens if a JWT is compromised? Because more and more applications are using\r\ntoken-based authentication, this question is increasingly relevant to developers and critical to understand if you’re\r\nbuilding any sort of application that uses token-based authentication.\r\nTo help explain the concepts fully, I’ll walk you through what tokens are, how they’re used, and what happens\r\nwhen they’re stolen. Finally: I’ll cover what you should actually do if your token has been stolen, and how to\r\nprevent this in the future.\r\nThis post was inspired by this StackOverflow question. My response to that question has become one of my most\r\npopular responses on StackOverflow to date!\r\nWhat is a Token?\r\nhttps://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen\r\nPage 1 of 9\n\nA token in the context of web development is nothing more than an arbitrary value that represents a session.\r\nTokens can be strings like “abc123” or randomly generated IDs like “48ff796e-8c8a-46b9-9f25-f883c14734ea”.\r\nA token’s purpose is to help a server remember who somebody is. Take API services, for example: if you have an\r\nAPI key that lets you talk to an API service from your server-side application, that API key is what the API service\r\nuses to “remember” who you are, look up your account details, and allow (or disallow) you from making a\r\nrequest. In this example, your API key is your “token”, and it allows you to access the API.\r\nHowever, when most people talk about tokens today, they’re actually referring to JWTs (for better or worse).\r\nWhat is a JSON Web Token (JWT)?\r\nJSON Web Tokens are special types of tokens that are structured in such a way that makes them convenient to use\r\nover the web. They have a handful of defining traits:\r\nThey are represented as normal strings. Here’s a real JWT:\r\neyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlJhbmRhbGwgRGVnZ2VzIiwiaWF0Ijo\r\nBecause JWTs are just URL safe strings, they’re easy to pass around via URL parameters, etc.\r\nThey contain JSON-encoded data. This means you can have your JWT store as much JSON data as you\r\nwant, and you can decode your token string into a JSON object. This makes them convenient for\r\nembedding information.\r\nThey’re cryptographically signed. Understanding how this works is a topic unto itself. For now, just\r\nknow that it means any trusted party who has a JWT can tell whether or not the token has been modified or\r\nchanged. This means if your application or API service generates a token that says someone is a “free” user\r\nand someone later alters the token to say they are an “admin” user, you’ll be able to detect this and act\r\naccordingly. This property makes JWTs useful for sharing information between parties over the web where\r\ntrust is difficult to come by.\r\nHere’s a small code snippet which creates and validates a JWT in JavaScript using the njwt library. This example\r\nis purely here to show you at a glance how to create a JWT, embed some JSON data in it, and validate it.\r\nhttps://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen\r\nPage 2 of 9\n\nconst njwt = require(\"njwt\");\r\nconst secureRandom = require(\"secure-random\");\r\n// This is a \"secret key\" that the creator of the JWT must keep private.\r\nvar key = secureRandom(256, { type: \"Buffer\" });\r\n// This is the JSON data embedded in the token.\r\nvar claims = {\r\n iss: \"https://api.com\",\r\n sub: \"someuserid\",\r\n scope: \"freeUser\",\r\n favoriteColor: \"black\"\r\n};\r\n// Create a JWT\r\nvar jwt = njwt.create(claims, key);\r\n// Log the JWT\r\nconsole.log(jwt);\r\n// Jwt {\r\n// header: JwtHeader { typ: 'JWT', alg: 'HS256' },\r\n// body:\r\n// JwtBody {\r\n// iss: 'https://api.com',\r\n// sub: 'someuserid',\r\n// scope: 'freeUser',\r\n// favoriteColor: 'black',\r\n// jti: '903c5447-ebfd-43e8-8f4d-b7cc5922f5ec',\r\n// iat: 1528824349,\r\n// exp: 1528827949 },\r\n// signingKey: \u003cBuffer 9c e9 48 a7 b3 c9 87 be 5f 59 90 a5 08 02 9b 98 5c 5e 1c 29 3f b0 33 c5 8c c8 f9 c8 3e 3\r\n// The JWT in compacted form (ready for sending over the network)\r\nvar token = jwt.compact();\r\n// Log the compacted JWT\r\nconsole.log(jwt.compact());\r\n// eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL2FwaS5jb20iLCJzdWIiOiJzb21ldXNlcmlkIiwic2NvcGUiOiJm\r\n// Verify the JWT using the secret key\r\nnjwt.verify(token, key, (err, verifiedJwt) =\u003e {\r\n if (err) throw err;\r\n console.log(\"The JWT has been verified and can be trusted!\");\r\n // The JWT has been verified and can be trusted!\r\n});\r\nhttps://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen\r\nPage 3 of 9\n\nHow are JSON Web Tokens Used?\r\nJWTs are typically used as session identifiers for web applications, mobile applications, and API services. But,\r\nunlike traditional session identifiers which act as nothing more than a pointer to actual user data on the server-side, JWTs typically contain user data directly.\r\nThe principal reason JWTs have become popular in recent years (having only been around since 2014) is that they\r\ncan contain arbitrary JSON data. The touted benefit of a JWT over a traditional session ID is that:\r\nJWTs are stateless and can contain user data directly\r\nBecause JWTs are stateless, no server-side session needs to be implemented (no session database, session\r\ncache, etc.)\r\nBecause JWTs are stateless, when a server-side application receives a JWT, it can validate it using only the “secret\r\nkey” that was used to create it — thereby avoiding the performance penalty of talking to a database or cache on\r\nthe backend, which adds latency to each request.\r\nWith that said, let’s take a look at how a JWT would typically be used in a modern web application.\r\n1. A client (a browser or mobile client, typically) will visit some sort of login page\r\n2. The client will send their credentials to the server-side application\r\n3. The server-side application will validate the user’s credentials, typically an email address and password,\r\nthen generate a JWT that contains the user’s information. The information embedded in the JWT will\r\ntypically be:\r\n4. The user’s first and last name\r\n5. The user’s email address or username\r\n6. The user’s ID (for server-side lookups, if necessary)\r\n7. The user’s permissions (what are they allowed to do?)\r\n8. Any other data that is relevant to the application being used\r\n9. The server-side application will return this token to the client\r\nhttps://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen\r\nPage 4 of 9\n\n10. The client will then store this token so that it can be used to identify itself in the future. For web\r\napplications, this might mean the client stores the token in HTML5 Local Storage. For server-side API\r\nclients, this might mean storing the token on disk or in a secret store.\r\n11. When the client makes requests to the server in the future, it will embed the JWT in the HTTP\r\nAuthorization header to identify itself\r\n12. When the server-side application receives a new incoming request, it will check to see if an HTTP\r\nAuthorization header exists, and if so, it will parse out the token and validate it using the “secret key”\r\n13. Finally, the server-side application will process the request if the token is valid and the cycle will be\r\ncomplete\r\nIn short: JWTs are used to identify a client. They are keys to the kingdom as far as the client is concerned.\r\nWhat Happens if Your JSON Web Token is Stolen?\r\nIn short: it’s bad, real bad.\r\nBecause JWTs are used to identify the client, if one is stolen or compromised, an attacker has full access to the\r\nuser’s account in the same way they would if the attacker had instead compromised the user’s username and\r\npassword.\r\nFor instance, if an attacker gets ahold of your JWT, they could start sending requests to the server identifying\r\nthemselves as you and do things like make service changes, user account updates, etc. Once an attacker has your\r\nJWT it is game over.\r\nBUT, there is one thing that makes a stolen JWT slightly less bad than a stolen username and password: timing.\r\nBecause JWTs can be configured to automatically expire after a set amount of time (a minute, an hour, a day,\r\nwhatever), attackers can only use your JWT to access the service until it expires.\r\nIn theory, that sounds great, right? One of the ways token authentication is said to make authentication more\r\n“secure” is via short-lived tokens. That’s one of the core reasons token-based authentication has really taken off in\r\nrecent years: you can automatically expire tokens and mitigate the risk of relying on forever-cached “stateless”\r\ntokens.\r\nhttps://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen\r\nPage 5 of 9\n\nIn the security world, after all, relying on cached data to make sensitive decisions like who can log into a service\r\nand what they can do is considered a bad thing. Because tokens are stateless and allow for some speed\r\nimprovements over traditional session authentication, the only way in which they can remain somewhat “secure”\r\nis by limiting their lifespan so they don’t cause too much harm when compromised.\r\nThe only problem here is that if an attacker was able to steal your token in the first place, they’re likely able to do\r\nit once you get a new token as well. The most common ways this happens is by man-in-the-middling (MITM)\r\nyour connection or getting access to the client or server directly. And unfortunately, in these scenarios, even the\r\nshortest-lived JWTs won’t help you at all.\r\nIn general, tokens should be treated like passwords and protected as such. They should never be publicly shared\r\nand should be kept in secure data stores. For browser-based applications, this means never storing your tokens in\r\nHTML5 Local Storage and instead storing tokens in server-side cookies that are not accessible to JavaScript.\r\nIn general, token-based authentication does not provide any additional security over typical session-based\r\nauthentication relying on opaque session identifiers. While there are certainly a good number of use cases for\r\ntoken-based authentication, knowing how the technology works and where your weak spots are is essential.\r\nAnother interesting thing to consider is that in some cases, a stolen JWT can actually be worse than a stolen\r\nusername and password.\r\nLet’s pretend, for a moment, that your username and password have been compromised. In this scenario, if the app\r\nyou’re logging into is protected with multi-factor authentication, an attacker needs to bypass additional identity\r\nproofing mechanisms in order to gain access to your account.\r\nWhile guessing or brute-forcing a username and password is a very realistic scenario, being able to compromise a\r\nuser’s mutli-factor authentication setup can be quite difficult. Bypassing factors like app-based authorization, SMS\r\nverification, face ID, touch ID, etc., is a significantly more challenging than guessing a user’s password.\r\nBecause of this, a compromised JWT can actually be a greater security risk than a compromised username and\r\npassword. Imagine the scenario above where the app a user logs into is protected by multi-factor authentication.\r\nOnce the user logs in and verifies themselves via multi-factor, they are assigned a JWT to prove who they are. If\r\nthat JWT is stolen, the attacker no longer needs to bypass MFA directly (like they would have to if they only had\r\nthe user’s username and password)—they can now directly make requests as the user without additional identity\r\nproofing. Quite a big risk.\r\nhttps://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen\r\nPage 6 of 9\n\nOnce a JWT has been stolen, you’ll be in a bad situation: an attacker can now impersonate a client and access your\r\nservice without the client’s consent. But, even though you’re in a bad situation, you’ve still got to make the most\r\nout of it.\r\nHere are a number of steps to take if a client’s token has been stolen. These recommendations are not suitable for\r\nevery type of app, but should provide you with some good ideas to help you recover from this security incident:\r\nRevoke compromised tokens immediately. If you’re using a revocation list on your server to invalidate\r\ntokens, revoking a token can instantly boot the attacker out of your system until they get hold of a new\r\ntoken. While it is a temporary solution, it will make the attacker’s life slightly more difficult.\r\nForce your client to change their password immediately. In the context of a web or mobile app, force\r\nyour user to reset their password immediately, preferably through some sort of multi-factor authentication\r\nflow like the ones Okta provides. Forcing a user to change their password can potentially keep attackers\r\nout of their account in the event that an attacker tries to use a compromised token to modify user login\r\ncredentials. By requiring multi-factor authentication, you can have more confidence that the user resetting\r\ntheir credentials is who they say they are and not an attacker.\r\nInspect the client’s environment. Was the user’s phone stolen so an attacker has access to their pre-authenticated mobile app? Was the client accessing your service from a compromised device like a mobile\r\nphone or infected computer? Discovering how the attacker got a hold of the token is the only way to fully\r\nunderstand what went wrong.\r\nInspect your server-side environment. Was an attacker able to compromise the token from your end? If\r\nso, this might involve a lot more work to fix, but the earlier you get started the better.\r\nOnce you’ve gone through these steps, you should hopefully have a better understanding of how the token was\r\ncompromised and what needs to be done to prevent it from happening in the future.\r\nHow to Detect Token Compromise\r\nhttps://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen\r\nPage 7 of 9\n\nWhen token compromise does happen, it can cause major problems. Particularly if you (as a service provider)\r\naren’t able to quickly detect that an attacker has compromised a client’s token.\r\nWhat if you were able to automatically identify when a token was compromised? That would dramatically\r\nimprove your service’s security, as you could proactively prevent suspicious requests from being fulfilled, thereby\r\nprotecting your service and your users.\r\nWhile not easy, this is absolutely possible. Modern machine learning toolkits like TensorFlow allow you to build\r\nfunctional (although complex) pipelines to detect unusual patterns and proactively take charge of the situation.\r\nFor example, you could use machine learning to detect unusual client locations. Let’s say you run a website, and\r\nyour user has logged in from San Francisco and has been making requests for several hours. If you notice that\r\nrequests start coming from a different geographical region a short time later, you can immediately prevent those\r\nrequests from being fulfilled, revoke the tokens, and reach out to the user to reset their password, etc.\r\nIn a similar manner, you could use machine learning to detect unusual client behavior. If a token is compromised,\r\nit’s likely that an attacker will take steps to abuse your service in some way. If you have a user who typically\r\nmakes five requests per minute on your site, but all of a sudden you notice a massive uptick where the user is\r\nmaking 50+ requests per minute, that might be a good indicator that an attacker has gotten a hold of a user’s\r\ntoken, so you can revoke the tokens and reach out to the user to reset their password.\r\nPattern detection and recognition through machine learning is a fantastic, modern way to handle some of these\r\nmore complicated problems.\r\nThis is precisely what we do here at Okta — we run an API service that allows you to store user accounts in our\r\nservice, and we provide developer libraries to handle things like authentication, authorization, social login, single\r\nsign-on, multi-factor authentication, etc. When users log into apps powered by Okta, we analyze a number of data\r\npoints to detect if an account has been compromised, prompt for multi-factor authentication, perform user\r\noutreach, etc.\r\nThere’s a lot of complexity involved in being proactive about your security, but it’s far better to be prepared than\r\nunprepared.\r\nShameless Plug: If you haven’t checked out our API service, it’s free to use and really fun! You can create an\r\naccount here: https://developer.okta.com/signup/. And… If you do happen to give it a go, I’d love to hear your\r\nhttps://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen\r\nPage 8 of 9\n\nthoughts, so please hit me up with any feedback about Okta, token authentication, or JSON Web Tokens. And\r\nfinally, please follow @oktadev Twitter — we tweet about a lot of interesting security related topics like this.\r\nHappy hacking,\r\n-Randall\r\nPS: Since writing this article, we’ve built a new security site where we’re writing about all sorts of in-depth\r\nsecurity topics. If that sounds interesting, please check it out.\r\nRandall Degges runs Evangelism at Okta where he works on security research, development, and education. In his\r\nspare time, Randall writes articles and gives talks advocating for security best practices. Randall also builds and\r\ncontributes to various open-source security tools.\r\nRandall's realm of expertise include Python, JavaScript, and Go development, web security, cryptography, and\r\ninfrastructure security. Randall has been writing software for ~20 years and has built some of the most-used API\r\nservices on the internet.\r\nSource: https://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen\r\nhttps://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen\r\nPage 9 of 9",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://developer.okta.com/blog/2018/06/20/what-happens-if-your-jwt-is-stolen"
	],
	"report_names": [
		"what-happens-if-your-jwt-is-stolen"
	],
	"threat_actors": [
		{
			"id": "aa73cd6a-868c-4ae4-a5b2-7cb2c5ad1e9d",
			"created_at": "2022-10-25T16:07:24.139848Z",
			"updated_at": "2026-04-10T02:00:04.878798Z",
			"deleted_at": null,
			"main_name": "Safe",
			"aliases": [],
			"source_name": "ETDA:Safe",
			"tools": [
				"DebugView",
				"LZ77",
				"OpenDoc",
				"SafeDisk",
				"TypeConfig",
				"UPXShell",
				"UsbDoc",
				"UsbExe"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775439087,
	"ts_updated_at": 1775826751,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/bee818ac7729f47beeae7d4403b1229b90377b8b.pdf",
		"text": "https://archive.orkl.eu/bee818ac7729f47beeae7d4403b1229b90377b8b.txt",
		"img": "https://archive.orkl.eu/bee818ac7729f47beeae7d4403b1229b90377b8b.jpg"
	}
}