Basis Lab

Answers · Keeping it safe

Is it actually OK to look at a risk and decide not to fix it?

In shortYes, if the decision not to fix it is written down with a reason, a named owner and a date or trigger for looking again; otherwise it is just an oversight.

Yes. Deciding not to fix a risk is legitimate and usually correct, but only when the decision is written down as a decision: a reason, a named person who answers for the loss, and a date or trigger at which it is looked at again.

FIG 1The accepted part is the remainder
findings accepted, which is most of them and the part that needs writing down
findings the enumeration pass produced
findings actually scheduled for a fix
For 36 findings and 9 fixes, a = 36 - 9 = 27. The accepted share is 27/36 = 0.75, so three quarters. The nine fixes get written up carefully; the 27 accepted items are the part that matters later, because they are the risks the organisation chose to carry while conditions held.

Most of the list is accepted

If a pass produces 36 findings and 9 are actually scheduled for repair, then 36 - 9 = 27 are accepted. The accepted share is 27/36 = 0.75, or three quarters. That is the ordinary shape of a findings list, not a failure. A plan that schedules all 36 will be abandoned around item nine, and the remaining 27 will still be unfixed; the only difference is that they are now unfixed silently, with no reason, no owner and no record. The arithmetic does not change when the plan does. What changes is whether the 27 exist as decisions or as an absence.

What makes it a decision

The natural guess is that leaving a risk unfixed is the same as ignoring it. It is not, but the difference is entirely in the record. Later, an unwritten non-fix and a risk nobody ever considered look identical: both are a blank where a decision should be. The test is whether a new engineer reading the record can tell that somebody considered the risk. A written acceptance carries the loss if the risk happens and the rate at which it is expected, plus a real reason, a named owner and a revisit condition. Remove the owner and it becomes the security team's private opinion. Remove the revisit condition and it becomes a permanent state. Remove the reason, or write 'we did not get to it', and it becomes a description of what happened rather than a decision. With a field missing it decays into an oversight.

FIG 2An accepted risk, written down
plaintext
accepted: no record of who read a customer record

what           an operator can read any account, unlogged
loss and rate  copied from the ranked entry
why accepted   the logging work needs the console rewrite,
               which is already scheduled for next quarter
owner          head of customer operations
revisit        when the console rewrite starts, or at the next
               quarterly review
would change   any regulated customer onboarding, or a further
               incident of this kind
The record is the object that separates a decision from an oversight. The last two fields are the ones most often left off.

Who answers for it

The owner is not the person who wrote the code, and not the person who found the finding. The owner is whoever would answer for the loss if it happened: whoever stands in front of the customer, the board or the regulator. That is usually not an engineer, and finding out who it is often takes a conversation. Finding the owner is often the most valuable minute of the exercise because it tests whether the acceptance is real. Often the named person has never heard of the finding and does not agree with the acceptance. That disagreement is useful. It converts an item at the bottom of the list into funded work, or it produces a better reason for carrying the risk. To have that conversation the acceptance must be offered in the owner's language: the loss, the rate, what is proposed instead, and the single question of whether they are content. Not the mechanism. A short paragraph.

When it stops being true

Every acceptance rests on conditions. The loss is this size because the table holds this much. The rate is this low because nobody outside can reach the service. The fix is expensive because the console is being rewritten anyway. None of those conditions announces the day it fails. A date is the weakest useful backstop. A quarter is a reasonable default: 365/4 = 91.25, so roughly 91 days, which is about as long as a reason stays remembered and inside the planning cycle that would fund the fix. 365 days is not a review period; it is a polite way of making the acceptance permanent. The stronger form is a trigger attached to the event that would invalidate the decision, such as the console rewrite starting or the first regulated customer signing. Use both. The event is right, and the date catches the event that nobody noticed.

It stops being a decision when any of the load-bearing fields is missing, when the owner is an engineer who cannot answer for the loss, when the reason is 'we did not get to it', or when the revisit date is so far out that nobody expects to reach it. It also stops being valid when its conditions move and the trigger is missed. The record can remain perfectly formatted while the decision behind it has expired. An accepted risk is not a promise that nothing will go wrong. It is a named decision to carry a known loss, with somebody answerable and a moment at which the answer is checked. Without that, not fixing is just ignoring with extra steps.

Worth keeping

  • An accepted risk is a decision only when it records the loss, the rate, a real reason, a named owner and a revisit condition.
  • A plan that fixes everything is a plan that accepts everything by default once it is abandoned.
  • A revisit date is a weak backstop; a trigger attached to the event that would invalidate the acceptance is stronger, and using both catches what neither catches alone.

Where this goes next

This question is one step of Thinking Like an Attacker, a course that works through its subject from the beginning. The page that teaches this part of it is Deciding Not to Fix It, and it reads the whole way through whether or not you have an account.

What an account changes is the practice: problems standing under every idea, marked with a reason rather than a tick, in a copy of the course that is yours.

Read that pageThe whole course

Other questions people ask about this

  1. Isn't threat modelling just brainstorming what could go wrong?No. It is a fixed checklist of six questions asked at every boundary, which gives a list with a known shape and a record of what was examined.
  2. How does text I saved in a comment end up running as JavaScript in someone else's browser?The comment stayed text in storage; a page that later pasted it into its own markup made the browser read it as code.
  3. Why does escaping the quotes in user input not stop SQL injection?Escaping quotes only cleans one context; SQL injection stops only when query text and values travel separately, so the value is never parsed as code.
  4. Why isn't encrypting the password enough to keep it safe if the database leaks?Because encryption can be undone by your own login code, so the key that lets you check a password usually sits near the database, and anyone who copies both can read every password.
  5. How do I stop one service from reading another service's password?Give every service its own identity, grant only the credentials it uses, and test that it cannot read another service's password.
  6. Why does storing a random salt with each hash stop rainbow tables?Because the salt is different for every account, a table built once from common passwords matches at most one row, so the work has to be redone account by account.

Read alongside