squirrelscan
GitHub

Session IDs in URLs: duplicate pages and shareable sessions

A session ID in the URL gives every visit its own address for the same page. squirrel finds PHPSESSID, jsessionid, sid and friends in the page URL and in internal links.

What a session ID in a URL costs

Some servers fall back to putting the session in the URL (?PHPSESSID=... or ;jsessionid=...) when a client does not accept cookies. A crawler does not, so every crawler visit gets its own session and every link it follows carries a new one. The same page then exists at an unlimited number of addresses, which wastes crawl budget and splits ranking signals across duplicates.

The URL is also the credential. A link copied from the address bar and sent to someone else can hand them the visitor’s session, and the ID leaks through the Referer header to other sites and into server and analytics logs. url/parameters counts parameters and flags tracking ones, but does not recognise session IDs.

What squirrel checks

The rule runs on every crawled page and reads the page URL and its internal links. It never requests anything.

A parameter counts as a session ID when its name is one of PHPSESSID, jsessionid, sid, sessionid, session_id or starts with ASPSESSIONID (any letter case), or it is the ColdFusion pair CFID with CFTOKEN (the token at least 8 characters), and its value looks generated rather than written or counted. The query form (?PHPSESSID=...) and the path form (/page;jsessionid=...) are both detected.

The value test depends on the name, in two classes.

  • Unambiguous names (PHPSESSID, jsessionid, session_id, ASPSESSIONID*): these only ever mean a session, so any value of 8 or more characters is flagged unless it is all digits (a counter or timestamp) or a human phrase, meaning all-lowercase words joined by - or _ (summer-collection). That accepts the shapes real servers send: 16 to 24 uppercase letters (ASP), 26 to 32 character alphanumerics, base64url tokens that happen to contain abc-def, dotted ids such as ABCDEF0123456789.node1, and ids ending in !12345.

  • Weak names (sid, sessionid): these are ordinary words in other systems, so the value has to look generated: 16 or more characters, with a letter and a digit, not all digits, and no pair of words of three or more letters joined by - or _. category-12345, item20241105, summer2024, summer-collection-2024 and 1234567890123456 are not flagged; a 32-character hex value and a 26-character alphanumeric are.

  • The ColdFusion pair CFID with CFTOKEN keeps its own test: both present, the token at least 8 characters. A lone CFID is never flagged.

  • Warn session-id-in-url: Page URL carries a session ID (PHPSESSID). The item is the page URL with the value replaced by ….

  • Warn session-id-links: 12 internal link(s) carry a session ID (jsessionid). Distinct links are counted, ten are listed, and details.additional counts the rest. Links to other hosts are not reported.

  • Pass session-ids: No session IDs in URLs.

The session value is masked wherever it appears: in the item, the message and the details. The rest of the URL is kept so you can find the link.

How to fix it

Keep the session in a cookie and stop the server from rewriting URLs.

  • PHP: session.use_only_cookies=1 and session.use_trans_sid=0.
  • Java servlet containers: set the tracking mode to cookie only, or disable URL rewriting.
  • ASP.NET: cookieless="false" in the session state settings.

Redirect the old URLs to the clean ones, and add a self-referencing canonical on the clean page.

Rule IDurl/session-ids
CategoryURL Structure
ScopePer-page
Severitywarning
Weight5/10

Enable / disable

Disable this rule

[rules]
disable = ["url/session-ids"]

Disable all URL Structure rules

[rules]
disable = ["url/*"]

Enable only this rule

[rules]
enable = ["url/session-ids"]

enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.

URL Structure findings ship in every audit next to the SEO, performance and agent experience rules. See Fix SEO issues with AI for how an agent works through a report.

References

Check your site

Run squirrel audit https://example.com and open the URL Structure section of the report. Each affected page is listed with the masked URLs of its session-carrying links. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.

Type to search…

↑↓ navigate↵ openesc close