HackBlue

Tools · Web testing tools · 22 / 23

Application storage: cookies, local storage, and a stale draft

The Application panel (Storage in Firefox) shows what this origin keeps on disk: cookies, local storage, and session storage. Harbor Ledger’s draft note lives in local storage, and a leftover draft from another lab user is a front-end bug you can see without sending a single attack.

16 min read · practice only with authorization

Chrome’s Application panel, Firefox’s Storage panel

In Chrome DevTools the Application tab holds Cookies, Local Storage, and Session Storage, grouped by origin. In Firefox the Storage tab holds the same three. Select http://127.0.0.1:3000 and ignore every other origin in the tree. If the lab origin is missing, you have not loaded it in this tab yet, or you are on the wrong port.

The port is part of the origin. A cookie you set while experimenting on a different local port will not explain Harbor Ledger’s form, and clearing it will not fix the form. Say the origin out loud before you change anything: scheme, host, port.

The draft that is not a server note

Harbor Ledger saves the in-progress note field under the local storage key harbor.draftNote so a reload does not wipe the textarea. Local storage survives reloads, new tabs, and browser restarts. It is not sent as the POST body until you click Save. It is not the list of notes the API returns. If the form shows text the API does not, the key is the first place to look, and it will match the form.

A shared lab profile makes this look like a serious mix-up. Blake used the profile, typed a draft, and closed the tab. Avery signs in later. The script fills the textarea from harbor.draftNote without asking which account wrote it. The server never stored Blake’s draft. The browser did. The fix in the app is to key the draft by the signed-in account, or to clear it when the account changes. The fix in the lab habit is a profile per person, plus “clear site data” for this origin when you hand the machine on.

Worked case: plant a draft, find it, clear only it

In the lab profile, sign in as Avery and type a draft you do not save: “draft from this profile.” Reload. The form still shows it. Open Application storage, local storage, http://127.0.0.1:3000, and read harbor.draftNote. It matches. Open the Network panel and reload. The invoice JSON does not contain that sentence. You have separated the two stores.

Clear site data for http://127.0.0.1:3000 only. Reload. The form is empty, and you are signed out, because the session cookie lived in the same origin. Sign in again. The form stays empty. The invoices are still on the server. That is the boundary the panel is for: this browser’s memory of one origin, distinct from the app’s data, distinct from every other site in the profile.

Diagram

What this origin remembers

  1. Origin

    Storage is keyed by http://127.0.0.1:3000. Another port is a different box.

  2. Cookie

    The session cookie is visible here, including the HttpOnly flag the script cannot read.

  3. Local storage

    harbor.draftNote survives reloads and new tabs. It is not the server’s copy of the note.

  4. Clear

    Clear storage for this origin only, then reload, and the draft is gone. Avery’s server-side invoices are not.

A draft that survived the wrong user

Shared profile, leftover key

Storage. harbor.draftNote still holds the previous lab user’s text.

Screen. Avery’s form opens with someone else’s draft.

Mistake. You treat the draft as a server response and file it as a data breach in the API.

Origin cleared, key explained

Storage. You see the key, the value, and that it is local storage.

Screen. After you clear this origin, the form opens empty.

Fix. The app should namespace the draft by account, or clear it on sign-in.

What the Application panel should show
Origin: http://127.0.0.1:3000

Cookies
  session    HttpOnly    SameSite=Lax
  (value not copied into the note)

Local storage
  harbor.draftNote = (whatever text is in the form)

Session storage
  empty, in this lab build

Clear site data: this origin only

Check yourself

1. Avery’s note form contains a sentence Blake typed yesterday. The API response for the invoice does not contain that sentence. Where do you look?

2. The session cookie shows HttpOnly in the Application panel. What can the page’s script do with it?

3. You want a clean form without signing Avery out of every website on the machine. What do you clear?