How HTTP Works

Request header

> Sec-Fetch-User: ?1

Sec-Fetch-User Header: ?1 and User Activation

Sec-Fetch-User is always ?1 and appears only on user-activated navigations, like a link click. When it is absent and why Safari does not send it.

Reviewed 2 min readintermediate3 sourcesTry itMarkdown
Direction
Request
Category
Security
Spec
W3C Fetch Metadata
JS can set it
No: forbidden header name
Note
Safari does not send it
On this page

TL;DR: Sec-Fetch-User: ?1 is sent only on navigation requests the user caused with a click, keypress or similar activation. It is absent otherwise, never ?0. Safari does not send it, so use it as a soft signal, never a requirement.

What it looks like

GET /dashboard HTTP/1.1
Host: example.com
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-Dest: document
Sec-Fetch-User: ?1

The value comes from structured-field booleans: ?1 is true. The Fetch Metadata spec (section 2.4) says the header is set only when a request is a navigation and its user-activation flag is true; in every other case the browser omits it. It is a forbidden request header, so scripts cannot add it.

When you will see it

ActionSent
Click a linkYes
Submit a form with a click or EnterYes
Type a URL or use a bookmarkYes, with Sec-Fetch-Site: none
Page script sets location.href with no gestureNo
<img>, fetch(), <script>, iframe subresourcesNo

The spec scopes it to navigation requests, which is why it is of limited use on its own. It matters when you want to separate “user clicked through to my page” from “a page redirected the browser to mine automatically”.

Uses

  • Logging and analytics. Tell real clicks from auto-redirects and prefetch-like navigations in access logs. Log it with Sec-Fetch-Site.
  • Tightening a cross-site navigation rule. The standard resource isolation policy allows any cross-site GET navigation. If you want stricter, require Sec-Fetch-User: ?1 for cross-site navigations to sensitive pages and send others to a landing page. Accept that Safari users, who do not send the header, will always take the landing page, so this is only suitable where that is acceptable.
  • Clickjacking and drive-by navigation hints. A navigation to your sensitive URL without user activation, from another site, is suspicious. It is a signal, not a defence. frame-ancestors in Content-Security-Policy is the defence.

Browser support

Chrome and Edge 76, Firefox 90. Safari: no support in MDN’s compatibility data, with WebKit bug 247697 open for it. This differs from Sec-Fetch-Site, Sec-Fetch-Mode and Sec-Fetch-Dest, which Safari has sent since 16.4. Sent only on requests to potentially trustworthy URLs (HTTPS, localhost).

Frequently asked questions

What does Sec-Fetch-User: ?1 mean?

?1 is the structured-field syntax for boolean true. The browser sends it only when a navigation request was triggered by user activation, such as a click or a keypress. The header has no other value: when the navigation was not user-activated, the browser leaves the header out entirely instead of sending ?0.

Is Sec-Fetch-User sent on fetch() or image requests?

No. The spec defines it for navigation requests only, so subresource requests never carry it. A navigation made by a script, such as location.href set outside a user gesture, or a redirect the page performs on load, will not have it.

Does Safari send Sec-Fetch-User?

Not as of MDN browser-compat-data today. Chrome and Edge 76 and Firefox 90 send it; Safari sends the other three Sec-Fetch headers from 16.4 but has no Sec-Fetch-User support, and WebKit tracks the work in bug 247697. Never make it a required signal.

Can I use Sec-Fetch-User to block bots?

No. Only unmodified browsers are bound by the Sec- prefix. Any script or HTTP client can send Sec-Fetch-User: ?1 with a hand-written request. It is a hint about how a genuine browser got to your URL, not proof of a human.

Sources

  1. MDN Web Docs: Sec-Fetch-Userdeveloper.mozilla.org
  2. W3C Fetch Metadata Request Headers, section 2.4w3c.github.io
  3. WebKit bug 247697: implement Sec-Fetch-Userwebkit.org

Keep going

Browse /search