Security as a requirement
In short: Functional tests check what the customer can do. Security asks what a person who wants to do harm must NOT be able to do. So a security requirement is written as a scenario with a malicious user: who, what they try, and what must happen instead.
Problem
All tests pass, and the orders belong to everyone
A customer opens their order: the address ends in /orders/1042. Out of curiosity they change the number to 1041. They see someone else's order: name, address, phone, what was bought.
The shop has 400 tests. One of them checks that the customer sees their own order. It passes. No test asks whether they also see someone else's, because no requirement says they must not.
The idea
Security is a requirement like any other
In the quality model from the first module, security is one of the nine characteristics. It is how well the system protects data and actions from people who have no right to them. ISO/IEC 25010:2023 splits it into six:
| Sub-characteristic | In the shop |
|---|---|
| Confidentiality | The customer sees only their own orders. |
| Integrity | The price cannot be changed from the browser. |
| Non-repudiation | The customer cannot claim they did not place the paid order. |
| Accountability | Every change of the address is logged: who and when. |
| Authenticity | The logged-in person is who they claim to be. |
| Resistance | The shop withstands 10,000 promo code attempts a minute. |
A security requirement is written and accepted like any non-functional one: with behaviour that can be checked, and with a limit.
More precisely, if you are curious
Resistance is new in the 2023 edition: the ability to keep doing the job during an attack. ISO/IEC 25010 describes what is required, not how it is achieved. How it is achieved (passwords, sessions, tokens, untrusted input) is in the module Security for developers of the software engineering course, with code.
Try it
Which part of security?
The idea
The malicious user
A story says what the honest customer wants. Security asks about another role: a person who wants to do harm. So for every story the opposite is written too:
- story: "As a customer I want to see my orders";
- abuse case: "As a malicious customer I want to see someone else's order, to get their address and phone number".
The second says what must not be possible and what happens instead. It is written in the same words as the acceptance criteria:
Feature: The customer's orders
Scenario: A customer does not see someone else's order Given customer A is logged in to their account And order 1041 belongs to customer B When customer A opens order 1041 Then they see "No such order" And they do not see customer B's name, address and phone number And the attempt is written to the log"No such order", not "You have no access": the second tells the attacker that the order exists.
More precisely, if you are curious
In English you will meet both names: abuse case and misuse case, after "Misuse cases" by Sindre and Opdal (2005). OWASP maintains lists of typical attacks and of checkable security requirements for web applications (the Application Security Verification Standard, ASVS). Broken access control, like the other customer's order here, is number one in the 2021 edition of the OWASP Top 10.
Try it
What must not be possible?
The idea
Who thinks like an attacker
Malicious scenarios are not only for a security team at the end. They are found most cheaply in the same conversation where the rules of the story are written. At Example Mapping, next to the rules, examples and questions, add one more question: "Who would want to abuse this, and how?"
- the promo code: two paid orders at once; guessing codes;
- returns: someone else's order; returning a more expensive product than the one bought;
- the cart: a price changed in the browser; a negative quantity.
Risk orders which to write first: those where money or personal data is lost.
Acceptance works as with performance: the requirements are agreed with the business beforehand, and checking them is part of acceptance testing. A penetration test by outside people is a useful addition. But it finds what nobody asked for. A requirement makes security something that is checked every time.
More precisely, if you are curious
CT-AcT v1.0, chapter 4, includes security in acceptance testing of non-functional requirements: the requirements and measures are agreed in advance, and the business decides which risks it accepts. How threat modelling is done systematically (for example STRIDE) and how attacks are checked with code is in the "Security for developers" module.
Exercise
A security requirement
1. The orders. Review the security requirement for orders.
Mark the problems in the requirement and choose the kind of each.
Press the words that are a problem; press again to unmark. The arrow keys move from word to word.
The problems in the text
- “protected from hackers” unverifiable: From which attacks, and how is it checked? The requirement has to name the threat and the behaviour: "a customer does not see someone else's order, even after changing the number in the address".
- “authorised users” ambiguous: Who is authorised for which order? The customer only for their own, the warehouse for all paid ones, support read-only? Without this, anyone logged in can turn out to be "authorised".
- “encrypted with AES” solution instead of need: This is a solution, and a wrong one: passwords are not encrypted, they are stored with a slow hash and a salt. The need is "the password cannot be recovered from the database, even if someone steals it".
The last sentence is a good requirement: a behaviour and what is logged. The first is a wish. The second does not say who is authorised for which order, and that is exactly where the hole with the number in the address was. The third is a solution, and a wrong one: passwords are not encrypted, they are stored with a slow hash.
Test
Check yourself
Related lessons
Section titled "Related lessons"- Builds on: Acceptance criteria · Test levels · Test types · The plan and risk-based testing
- Tasks on this topic: Non-functional