Add Secure and httpOnly Flags to Every Set-Cookie Response in Apache httpd
Six years later, I may have solved this.
The Header
directive is provided by mod_headers
, and is structured as Header {condition} {action} {header name} {match} {replacement}
. The key that I haven't seen anybody bring up in other answers is the first variable, condition
.
condition
can be always
or onsuccess
, per the description in the link above, but -- and this is why it took so long to crack -- always
does not actually mean "always":
always
is not a superset ofonsuccess
with respect to existing headers
More specifically, there are two tables of headers called "always" and "onsuccess" and a given module can put a value in either or both of them, and all values from both tables will be written in the response.
TL;DR: always be sure to edit headers in both tables:
Header always edit Set-Cookie (.*) "$1; HTTPOnly"
Header onsuccess edit Set-Cookie (.*) "$1; HTTPOnly"
The Header edit
directive runs before your application produces a response, so if the application is producing the header you want to edit, that header won't yet exist at the time the directive runs, and there'll be nothing for it to edit.
You can fix this by using Header always edit
(which runs after your application produces a response) instead:
Header always edit Set-Cookie (.*) "$1; HTTPOnly"
An example header, before applying the directive:
Set-Cookie: foo=bar; domain=.example.com; path=/
The same header after applying the directive:
Set-Cookie: foo=bar; domain=.example.com; path=/; HTTPOnly
I'm not sure what the directives in your question are meant to do exactly; what they actually result in when changed to Header always edit
(assuming the same Set-Cookie
header as in my example above) is e.g.
Set-Cookie: f ;HTTPOnlyo=bar; domain=.example.com; path=/
If you understand how regexes and backreferences work, it's obvious what's happening there, but presumably it's not what you want. The directive I've given at the top of this answer ought to work for you if, as you say, you want to add the flag to every Set-Cookie
header; if your needs are more complex and I've misunderstood what you're trying to do with that search/replace, let me know.
EDIT: In case it isn't obvious: to add both flags, you can either modify the directive like so:
Header always edit Set-Cookie (.*) "$1; HTTPOnly; Secure"
... or use two directives:
Header always edit Set-Cookie (.*) "$1; HTTPOnly"
Header always edit Set-Cookie (.*) "$1; Secure"
The first approach seems more sensible to me, but it's largely a matter of taste.
I was trying to set http, secure and samesite=strict on cookies.
This worked for me:
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure
Samesite=strict provides protection againsts XSRF.
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=strict
Hope it helps.