security
Your HAR File Has Your Login Session in It — And So Does Every Support Ticket
A HAR export is a verbatim transcript of every request your browser made — cookies, Authorization headers, passwords in POST bodies and all. Attackers hijacked real Okta customer sessions from exactly these files. What is in a HAR, how to read one, and how to sanitize it before it lands in a ticket.
A support engineer asks you to “export a HAR file and attach it to the ticket,” and it sounds about as sensitive as sending a screenshot. It isn’t, because a HAR file is a verbatim recording of every request your browser made — including the session cookies, Authorization headers, and form-posted passwords that are your login. Whoever holds that file can replay your session without your password and without tripping MFA, because from the server’s point of view they simply are you, mid-session. This is not hypothetical: it’s precisely how attackers hijacked real customer sessions in Okta’s October 2023 support-system breach.
Most articles about HAR files walk you through a viewer’s buttons. This one starts from the part that actually bites people — what’s inside the file — and works outward to how to read one safely.
The breach that made this concrete
Okta’s support process, like many vendors’, routinely asked customers to upload HAR files to troubleshoot login issues. In its root-cause analysis, Okta reported that from September 28 to October 17, 2023, a threat actor had unauthorized access to its support case management system — via a service account whose credentials had been saved into an employee’s personal Google profile on a company laptop — and viewed files belonging to 134 customers. Some of those files were HAR files containing session tokens, and the attacker used them to hijack the live Okta sessions of 5 customers.
The detail worth sitting with comes from Krebs on Security’s coverage: BeyondTrust uploaded a HAR file to Okta support on October 2 and saw an attacker attempt to use a session token from that very file — trying to create an administrator account in their tenant — about 30 minutes later. Cloudflare and 1Password later disclosed they’d been targeted through the same channel. Okta’s own advisory at the time recommended sanitizing “all credentials and cookies/session tokens” inside a HAR before sharing it.
Note what did not happen here. Nobody cracked a password. Nobody phished an MFA code. The tokens sat in files that users were asked to upload, in a system that a support organization reasonably considered internal. That’s the general lesson: a HAR file attached to a ticket is only as safe as every system, contractor, and inbox that ticket ever touches — and its contents stay valid until the captured session expires or is revoked.
What a HAR file actually contains
HAR (“HTTP Archive”) is a JSON format, defined by a W3C draft spec. The structure is a log with an entries array — one entry per request the browser made while DevTools was recording. Per the spec, each entry’s request object carries method, url, httpVersion, cookies, headers, queryString, postData…, and each response carries status, statusText, httpVersion, cookies, headers, content, redirectURL….
Map that onto where secrets actually live in an authenticated web session and the picture is uncomfortable:
| Secret | Where it lands in the HAR |
|---|---|
| Session cookie | request.headers (Cookie), duplicated in request.cookies[] as parsed name/value pairs |
| Bearer / API token | request.headers (Authorization, X-Api-Key, and friends) |
| The password you typed at login | request.postData.text — the login form’s POST body, verbatim |
| Newly issued tokens | response.headers (Set-Cookie) and response.content.text — token endpoints answer in JSON, and the spec stores the full response body, base64-encoded when binary |
| Tokens in URLs | request.url and request.queryString[] (password-reset links, signed URLs, ?token=…) |
| Everything you looked at | response.content.text again — account pages, emails, documents, whatever rendered during the capture |
Two properties make this worse than most people’s mental model of a “log file.”
First, the capture is not scoped to the site you’re debugging. DevTools records every request the tab makes while recording is on — third-party APIs, analytics, that other origin your SSO redirected through. Cookies for all of them come along.
Second, HttpOnly does not protect you. The HttpOnly cookie flag exists to keep JavaScript from reading a cookie, which is why it defeats most XSS token theft. But a HAR export isn’t JavaScript reading cookies — it’s the browser writing down its own network traffic, which it sees in full. The spec’s cookie object even records the flags: name, value, path, domain, expires, httpOnly, secure. Your most-protected cookie appears in plaintext with a polite annotation saying it was supposed to be hard to steal.
Here’s a trimmed entry from a real-shaped capture — this is the kind of thing sitting in ticket attachments everywhere:
{
"request": {
"method": "POST",
"url": "https://app.example.com/api/login",
"headers": [
{ "name": "Cookie", "value": "session=eyJhbGciOi..." },
{ "name": "Authorization", "value": "Bearer sk_live_..." }
],
"postData": {
"mimeType": "application/json",
"text": "{\"email\":\"[email protected]\",\"password\":\"hunter2\"}"
}
},
"response": {
"headers": [
{ "name": "Set-Cookie", "value": "session=eyJuZXci...; HttpOnly; Secure" }
],
"content": { "mimeType": "application/json", "text": "{\"token\":\"eyJ0eXAi...\"}" }
}
}
A session token is a bearer credential: the server honors whoever presents it. It’s the finished product of your password plus your MFA challenge — which is exactly why attackers prefer stealing sessions to stealing passwords, the same economics that drive the token-theft side of browser fingerprinting and bot detection. Replaying one usually requires nothing more exotic than a curl command with a -H 'Cookie: …' flag — the mechanics are all in our curl flags guide.
Sanitizing a HAR before it goes anywhere
The good news: HAR is just JSON, so sanitizing it is entirely doable. The workable approaches, in descending order of preference:
1. Don’t capture the secrets in the first place. Reproduce the problem in a private/incognito window, ideally with a throwaway test account. Start recording after login unless login itself is the bug — the single worst entry in any HAR is the login POST, because it carries the raw password. Keep the capture short: start recording, do the one failing action, stop, export.
2. Kill the session after capturing. A stolen token is only useful while the server honors it. Logging out of the captured session — or revoking it from your account’s active-sessions page — turns the tokens in the file into inert strings. Okta’s remediation for affected customers was exactly this: revoking the embedded session tokens. Do it before the file leaves your machine, not after the breach notification.
3. Actually edit the file. Open the .har in a text editor and replace the values (never the JSON structure) of anything credential-shaped:
- every
CookieandSet-Cookieheader value, and everyvalueinsidecookies[]arrays Authorization,Proxy-Authorization,X-Api-Key,X-Auth-Tokenand similar header valuespostData.texton any login, token, or form-submit requestresponse.content.textfor token endpoints and any page containing personal data- tokens embedded in
urlandqueryStringvalues
A find-and-replace of the literal token string is the reliable move, since the same cookie value appears in dozens of entries. Re-check the file afterward — which brings us to reading it.
Reading a HAR without creating a second copy of the problem
There’s an irony in most “how to read a HAR” advice: it points you at an online viewer, and uploading the file to a random website is a miniature version of the Okta incident — you’ve now handed your session transcript to one more party you can’t audit.
Our HAR file viewer was built around that exact objection. The file is parsed with JavaScript in your browser tab; there is no upload and no server call, so the HAR never leaves your machine. You get the summary, filters, and a per-request timing waterfall (blocked → DNS → connect → TLS → send → wait → receive), and clicking any request shows its headers and body.
Two behaviors matter for this article’s purposes:
- Credential headers are hidden by default.
Cookie,Set-Cookie,Authorization,Proxy-Authorization,X-Api-Key, andX-Auth-Tokendisplay asREDACTEDwith a “hidden” badge until you deliberately toggle them visible — so you can screen-share a debugging session without broadcasting your session token. - “Copy as cURL” redacts by default, too. The generated command replaces those same header values with
REDACTED, so the thing most likely to get pasted into a ticket, a Slack thread, or a GitHub issue is safe as generated. Untick the redaction box and the tool warns you, in so many words, that real credentials are now in your clipboard. (If you then want that curl command as Python or JavaScript, the curl converter will translate it.)
And the honest caveats, because display redaction is not sanitization: the viewer masks a known list of credential headers — it doesn’t rewrite the file, and it can’t know that ?access_token=… in a query string or a JWT inside a JSON response body is sensitive. Those render as captured. Use the viewer to find what’s in the file; use the checklist above to actually clean it before the file is shared.
The short version
| Assumption | Reality |
|---|---|
| ”A HAR is a log of URLs and timings” | It’s a verbatim capture: cookies, auth headers, POST bodies, and full response bodies (per the HAR spec’s request/response/content objects) |
| “It’s fine, my session cookie is HttpOnly” | HttpOnly blocks JavaScript, not the browser’s own export — the flag is recorded next to the plaintext value |
| ”They’d still need my password and MFA” | A session token is the product of password + MFA; replaying it needs neither — that’s how 5 Okta customer sessions were hijacked in 2023 |
| ”The support portal is internal” | Okta’s support system was accessed for ~3 weeks and files of 134 customers were viewed; BeyondTrust saw its uploaded token abused ~30 minutes after upload |
| ”I’ll just upload it to a HAR viewer to check it” | An upload is one more copy in one more place — read it in a viewer that parses in your browser instead |
| ”Redacted in the viewer = safe to send” | Sanitize the JSON itself (headers, cookies, bodies, URLs), capture post-login on a test account, and log out of the captured session |