During 2021 I had access to a facility equipped with an alarm system from Securitas Direct. I had access as a regular user to Securitas Direct’s My Pages at mypages-pro.securitas-direct.com, which is used to administer some aspects of one’s security alarm installation. That web application suffered a CWE-384Session Fixation vulnerability which can be used by an attacker in a so-called Man-In-The-Middle (MiTM) position.
In summary, if an attacker is on the same network as the victim or somewhere else between the victim and Securitas Direct’s server, and if the attacker can make the victim’s browser make an unencrypted HTTP request to a subdomain of securitas-direct.com, the attacker can impersonate the victim when they log in, even if that happens a long time afterwards. A requirement is that the attacker makes an HTTP request themself every half an hour to keep a session alive.
The session fixation problem is now allegedly fixed and it is important to note that as a regular user of the system, who does not have permissions to administer the alarm’s users, even if one became victim of this attack, it was not possible to disarm the alarm system with the hijacked session since that action requires a PIN as well. What a session hijacker could do with an administrative account has not been tested as I did not have such privileges.
Session Fixation is described by MITRE as:
Authenticating a user, or otherwise establishing a new user session, without invalidating any existing session identifier gives an attacker the opportunity to steal authenticated sessions.
Such a scenario is commonly observed when:
A web application authenticates a user without first invalidating the
existing session, thereby continuing to use the session already associated with
An attacker is able to force a known session identifier on a user so that,
once the user authenticates, the attacker has access to the authenticated
The application or container uses predictable session identifiers. In the
generic exploit of session fixation vulnerabilities, an attacker creates a new
session on a web application and records the associated session identifier. The
attacker then causes the victim to associate, and possibly authenticate,
against the server using that session identifier, giving the attacker access to
the user’s account through the active session.
The first time a user visits a dynamic page, such as the root page / served by index.php, the user’s browser does not have any cookies to present in that HTTP GET request. The server generates a session identifier which is set in a cookie named bwp_session. The cookie has the attributesSecure and HttpOnly, is valid for all pages on the mypages-pro.securitas-direct.com domain and expires in 30 minutes using both Max-Age and Expires attributes. So far, so good.
When logging in, however, the session identifier remains unchanged. This is the first problem.
Yes, the bwp_session cookie does not change and the expiration is set to another 30 minutes. It seems like an innocent bug that the same Set-Cookie: bwp_session=... header is repeated ten extra times with the same value, but we will soon see that it becomes a security problem, too.
When the user explicitly logs out, it seems like the logout actually takes place server-side, which is good. It also seems like the developers tries to do the right thing — to delete the session cookie from the browser. But here the repeating header bug strikes again.
That does not have any effect however since browsers process Set-Cookie headers in the order they are received (implicitly by sections 5.2 and 5.3 in RFC 6265HTTP State Management Mechanism) and the cookie is created again with the same value as before:
An attacker that gets hold of a session identifier for a logged-in user can use it to become that user and can keep the session alive by making new HTTP requests with that identifier at least once per 30 minutes. When the user explicitly logs out using a GET request to /logout however, the attacker is also logged out. But since the cookie is never deleted in the user’s browser and a new session identifier is not set, the session will become alive again on the next login. But only if that second login happens within 30 minutes after the last request by the user, as the browser will automatically purge expired cookies from its cookie store and a bwp_session cookie properly set by an authentic Securitas Direct server has both the Max-Age and Expires cookie attributes set to accomplish that.
Man-in-The-Middle Attack Using Plaintext HTTP
The cookie attribute Secure mentioned above specify when browsers shall transmit the cookie to the server, but the attributes themselves are never sent, so the server cannot know how the cookie was set in the first place (unless cookie prefixes are used as part of the cookie name).
A vulnerable application on a subdomain can set a cookie with the Domain attribute, which gives access to that cookie on all other subdomains. This mechanism can be abused in a session fixation attack. See session fixation for primary mitigation methods.
So, a Man-in-The-Middle attacker who can make the victim’s browser to send a request to for instance http://mypages-pro.securitas-direct.com/ can set a persistent cookie named bwp_session without expiration and which is valid for securitas-direct.com including all subdomains, such as mypages-pro.
That is not so hard once in the MiTM position. The attacker could inject some resource (an image for instance) on another plaintext HTTP page the victim is browsing to. The attacker could also trick the victim into visiting an attacker-controlled website (even over HTTPS) that will do the same. Or the attacker could send an innocent looking link that the victim might click.
If the attacker does not redirect the victim to the real My Pages site, the session identifier, which the attacker knows, will remain in the victim’s browser indefinitely. Once the victim visits the real site, the browser will pick upp the changed properties of the cookie, such as the expiry time (30 minutes). The cookie value will remain however, and that is the big problem. The attacker will be able to hijack the victim’s first login session, and any other subsequent login sessions as long as they are no longer than 30 minutes apart.
List of Problems
The session identifier is not changed when logging in
The session identifier is not changed when logging out
Cookie deletion ineffective
Domain not protected with HTTP Strict Transport Security (HSTS)
Unclear where to report security vulnerabilities: no Vulnerability Disclosure Policy (VDP) or security.txt
My recommendations, in order of importance:
Change the session identifier when logging in and out (required to overcome the session fixation problem)
Make sure that the header Set-Cookie: bwp_session=... is present only once per HTTP response
Publish a Vulnerability Disclosure Policy. See Internet.nl’s policy for a good example. Cybersecurity and Infrastructure Security Agency (CISA) within the Department of Homeland Security (DHS) in United States offer a VDP template.
2021-SEP-02 Session problems first sighted. Session Fixation described in a private Facebook Messenger chat with a former Verisure colleague who promised to investigate and create an internal ticket about the matter.
2021-NOV-23 Contacted Securitas Direct customer support (email@example.com) to ask where to report security problems.
2021-NOV-24 Contacted some former Verisure colleagues to speed up the process to find the proper security contact person, which ended up being the Information Security Manager for the north part of Verisure. Sent the vulnerability report.
2021-NOV-25 The Information Security Manager for the north part of Verisure confirmed the reception of the report.
2021-DEC-23 An IT-Dev Integration Analyst at Verisure contacts me to thank me for reporting, apologizing for the troubles in reaching the proper contact person and inform me that several internal tickets have been created to address my findings.
2022-JAN-11 I respond and inform about my intention to publish this blog post 90 days after the report was sent.
2022-FEB-18 The IT-Dev Integration Analyst contacts me again to inform that “the teams have deployed fixes to production for the core aspects of the session fixation”.
2022-FEB-22 Publication of this blog post.
2022-FEB-23 Fixed a typo.
2022-MAR-15 Removed some unnecessary information.
2022-APR-08 I was contacted about a typo in a company name. Published an update the 12th of March. See the Credit section for details.
I don’t have access to a My Pages account anymore, so I have just been able to verify some changes with anonymous access. I can’t know if the session identifier is changed on successful login. It’s not on unsuccessful login and not when trying to logout without being logged in either:
Verisure seems to have removed the duplicate Set-Cookie headers with identical cookie names, at least for the endpoints above.
I notice that there is now an HTTP Strict Transport Security (HSTS) header on the My Pages domain with a max-age of one year, as recommended. The whole top domain securitas-direct.com has HSTS as well (not preloaded), but probably nobody will visit it to pick up the policy.
I have previously worked for Verisure Innovation AB which together with Securitas Direct Sverige AB are part of Securitas Direct Verisure Group. I worked with IT operations and never with the physical alarm systems or the customers’ interaction with the service. No inside knowledge was used to find the session fixation vulnerability. It was discovered when I received a My Pages account myself while having access to the facility in question.
Kristofer Johansson for pointing out that I forgot the word “Direct” in “Securitas Direct Sverige AB”. “Securitas Sverige AB” is a Securitas company and not related to the article at all. The two companies are owned by different entities since 2006.