Optional Password Protection Added To Incident Commander
Now that I've rebuilt my Incident Commander triage app in ColdFusion, I've been trying to incrementally improve it. First I added the ability to use markdown in the incident description and status updates; then I added the ability to upload supporting screenshots; and now, I've added the ability to include an optional password to satisfy particularly security-minded teams.
Run this app at www.incident-commander.com
.
View this code in my Incident Commander project on GitHub.
Considering Risk Appetite In Security
There is no "one way" to do security in a ColdFusion web application. All security is a collection of trade-offs that balance the strength of the security against the user experience (UX). The better the security, the worse the user experience; the better the user experience, the weaker the security.
The goal is to find a compromise that feels commensurate with the sensitivity of the data being stored. In the case of incident triage, the data is sensitive; but not that sensitive. Yes, it may deal with the proprietary information about software architectures and system landscapes; and, it may contain screenshots of internal logs and metrics graphs; but, it's unlikely to contain information about credit cards or personally identifiable information (PII) about the users.
It's important to remember the context in which incident triage is being performed. Things are on fire! Users are freaking out! Systems are down! Engineers may be getting paged in the middle of the night! People are in panic mode; and will almost certainly be operating in a degraded state.
Because of this fraught context, I needed there to be no barrier to entry when starting an incident. No mucking around with Single Sign-On (SSO) workflows. No having to create accounts ahead of time. No connecting to VPNs (Virtual Private Networks). No waiting for magic passwordless email links to arrive. No futzing with Two-Factor Authentication (2FA) tokens.
When an incident needs to be opened, the incident commander (IC) needs to be able to open the site, quickly initiate the incident triage session, and get to work!
The Baseline Security of an Incident
When the incident commander opens an incident triage session, a new incident record is created in the database. This record has two core parts:
The
id
, which is an auto-incrementingBigInt
.The
slug
, which is a randomly generated, 64 byte alpha-numeric string.
When you access an incident in the browser, both the id
and the slug
need to be provided in the URL (which is done using a single compound "token"). The id
is used for the database look-up; and then, the slug
is used to provide security against the brute-force guessing of incident IDs.
Aside: In theory, I could have only required the
slug
to be provided in the URL. But then, I'd have to index theslug
column; and either define it using a case-sensitive collation or author the SQL query to use a case-sensitive text comparison. Since I already had an index on theid
(the primary key), it seemed simpler to just pull the record back based on theid
and then use thecompare()
function on the ColdFusion side for a case-sensitive comparison.
The slug
is 64 characters long and is built using an alphabet that contains 62 possibilities (a-zA-Z0-9
). Which makes the "key space" for the slug
astronomically large at 62^64
possible combinations. Adding on top of that the fact that I have rate-limiting in the application layer and the slug
alone is enough to make a brute-force attack virtually impossible.
The incident commander should feel confident that when they start an incident triage session, they are immediately dropped into a safe and secure context.
A Non-URL Authentication Mechanism
That said, having nothing but a URL-based authentication mechanism will raise some eyebrows for teams that are obsessively security-minded. While the slug
is very strong, it is—as I mentioned above—ultimately a set of trade-offs. The ease-of-use does come with some disadvantages:
A URL-based security token will show up in the browser's history API.
A URL-based security token can show up in
Http-Referer
logging for any links that link from the incident triage content.Aside: In the incident commander app, I'm using JSoup to enforce
noopener
andnoreferrer
directives on all anchor links to help prevent anyHttp-Referer
logging. As such, that should be less of a concern for people using modern browsers.A URL-based security token will be logged in much of the network infrastructure that routes the request from the user's browser to the ColdFusion server.
A URL-based security token will likely be logged in any error tracking, both on the client-side and on the server-side.
A URL-based security token could accidentally show up in a URL or screenshot that is shared publicly.
A URL-based security token may not have a manual rotation mechanism to help remediate any accidental information leakage.
None of this makes the URL-based authentication mechanism a "bad" or "weak" option—it only means that is has both advantages and disadvantages when used in isolation.
For teams that want an additional layer of security to hedge against the aforementioned trade-offs, I've added an optional password feature. Once an incident triage session has been started, the incident commander can go into the "Password" section and set the password:
When the password is set, it's stored in an encrypted state using AES/CBC encryption with a 256-bit secret key. If a user goes to access an incident that is password protected, they are redirected to an authorization form where they must enter this password:
Upon successful entry of the correct password (a workflow that is, itself, rate-limited), I set an authorization cookie that is signed using ColdFusion's hmac()
function with the HmacSHA256
algorithm and a 512-bit secret key. The cookie contains nothing but a manifest of id
values that the user can access. Each id
entry in this manifest is valid for 24-hours (after which the password will need to be re-entered).
This cookie is defined using the HttpOnly
and Secure
flags which prevent them from being accessed via JavaScript or transmitted over a non-SSL/TLS connection, respectively. As such, the chances that the cookie value is logged or intercepted are vastly reduced when compared to the core URL-based slug
authorization.
On top of that, the cookie itself is set to expire in 7-days. And, uses a SameSite="strict"
policy to help prevent cross-site request forgery (CSRF) attacks.
When the incident commander sets a password for the triage session, the Slack-ready message is updated to include the password in the copy-paste text:
For people who are concerned with "Security Theater", rendering the password in plain-text will certainly ruffle a few feathers. Generally speaking, this is something you want to avoid.
But, you must remember that security is a set of trade-offs, not a set of absolutes. The primary goal of the Incident Commander application is to make it easier for teams to communicate during incident triage. In order to make it easier for everyone on the team to participate in a way that adds the most value, the password must be something that is accessible. If the password were only known to the IC, the IC becomes the limiting factor and a bottleneck in the flow of information.
The password isn't there to prevent your team from accessing the incident details; the password is there to prevent malicious actors from accessing the incident. The password is there to minimize the risk of information leakage, not to eliminate it. Again, security is a set of trade-offs, balancing user ergonomics and risk appetite.
When faced with an outage—especially one in the middle of the night—the last thing you want to do is deal with complex authentication schemes, VPNs, or other draconian security measures. You need to be able to open an incident triage session and start investigating root cause problems immediately. As such, I've tried to design the Incident Commander application experience to have no barriers to entry. That said, for those of you that want a little extra security peace-of-mind, I'm hoping that the optional password protection will do the trick.
Reader Comments
Post A Comment — ❤️ I'd Love To Hear From You! ❤️
Post a Comment →