SEN2008 · Week 14 · Software Security (II): Secure software construction techniques, Security-related verification and validation

Security testing and the OWASP Top 10

You learn what static analysis, dynamic scanning, fuzzing, penetration testing and code review find and when, plus the OWASP Top 10 (2021) list. The exam asks 'which category is this scenario' and tool metrics (precision, recall).

security testingstatic analysis (SAST)dynamic analysis (DAST)fuzzingmutation-based fuzzinggeneration-based fuzzingpenetration testingblack-boxwhite-boxgrey-boxfalse positivefalse negativeprecisionrecallcode reviewOWASP Top 10broken access controlIDORSSRF

You wrote secure code, but is it really secure? The only way to know is to test. This page is the verification and validation leg of the secure SDLC: which testing technique finds which vulnerability, and which one misses what. The second half has the OWASP Top 10 (2021). The two most common types on the exam: “what does this technique do / which one doesn’t execute the code” and “which OWASP category is this scenario”. In between, small calculations such as precision/recall or a fuzzing probability may appear.

Golden rules:

  1. One technique isn’t enough. Static analysis, dynamic testing and human review find different flaws.
  2. Early testing is cheap. SAST and code review work while the code is being written.
  3. Tool output is raw data. Every finding must be verified; a false positive is noise, a false negative is a blind spot.
  4. No testing without permission. A pentest is done with written permission and a clear scope.
  5. Recognize the OWASP list from the scenario. Memorizing category names is not enough, match them with examples.

Security testing techniques

TechniqueWhenHowWhat it finds wellWeak side
Code reviewevery commita human reads, with a checklistlogic and design flaws, missing authorization checksslow, depends on the person
SASTduring build, CIdata flow analysis without running the codeinjection, dangerous APIs, hard-coded passwordsmany false positives, doesn’t see the runtime environment
DASTa running application in a test environmentsends HTTP requests from outsideconfiguration errors, reflected XSS, missing headerscan’t say which line of code it is, limited coverage
Fuzzingtest, continuousthousands of malformed inputscrashes, memory errors, parser vulnerabilitiesdoesn’t find logic errors
Penetration testingbefore release, periodican authorized expert thinks like an attackerchained vulnerabilities, business logic flawsexpensive, a snapshot in time
SCACIcompares dependency versions with the CVE databaselibraries with known vulnerabilitiesdoesn’t look at flaws in your own code

Static analysis (SAST)

SAST marks the place where input comes in as the source, and the place where it is used dangerously as the sink, and checks whether there is sanitization on the path in between. This is called taint analysis.

String id = request.getParameter("id");              // source: untrusted
String sql = "SELECT * FROM orders WHERE id = " + id;
stmt.executeQuery(sql);                               // sink: SQL engine
// SAST warning: tainted data flows from getParameter to executeQuery

Advantage: it doesn’t need a running system yet, and it examines every path. Disadvantage: it can’t always tell that a value is actually harmless, so it produces false alarms.

Measuring a tool’s success: precision and recall

Say a tool reports 60 findings and 45 of them are real. Say the code has 50 real vulnerabilities in total.

ConceptMeaningValue
TP (true positive)a correct finding45
FP (false positive)a false alarm60 − 45 = 15
FN (false negative)a real vulnerability that was missed50 − 45 = 5

precision=TPTP+FP=4560=0.75recall=TPTP+FN=4550=0.90\text{precision} = \frac{TP}{TP+FP} = \frac{45}{60} = 0.75 \qquad \text{recall} = \frac{TP}{TP+FN} = \frac{45}{50} = 0.90

In security a false negative is more dangerous (the vulnerability goes live), but a very low precision makes the developer switch the tool off. A balance is struck between the two.

Dynamic analysis (DAST)

DAST tests the running application without seeing the source code: it fills in forms, puts special characters in parameters, and looks in the response for error messages, reflected input and missing security headers (Content-Security-Policy, Strict-Transport-Security). Since it tests the real environment, it sees configuration errors; but it tests only the pages it can reach. IAST combines the two by placing an agent inside the application.

Fuzzing

A fuzzer gives the program unexpected input and looks for crashes, infinite loops and memory errors. It is especially effective for file format parsers, network protocols and C/C++ code.

TypeHow it generates input
Mutation-basedcorrupts valid sample files by flipping bits, inserting and deleting bytes
Generation-basedproduces from scratch from a format definition (grammar, protocol schema)
Coverage-guidedkeeps inputs that open a new code path and mutates them (AFL, libFuzzer)

Why are many inputs needed? If a bug is triggered with probability pp per input, the probability that it is triggered at least once in nn independent inputs is:

P=1−(1−p)n≈1−e−npP = 1 - (1-p)^n \approx 1 - e^{-np}

For p=10−4p = 10^{-4}, n=10 000n = 10\,000 gives P≈0.6321P \approx 0.6321. To catch the same bug with high probability, the number of inputs has to be increased several times. Coverage-guided fuzzing tries precisely to increase this pp.

PITFALL · fuzzing doesn’t find every vulnerability. Bugs that don’t produce a crash (e.g. IDOR, a wrong authorization check) are invisible to a fuzzer. The program returns the “right” response but shows someone else’s data. These are found by code review and pentest.

Penetration testing

A pentest is an authorized expert testing the system through an attacker’s eyes, but with written permission and within a defined scope. The goal is to find the vulnerability and report it to the owner.

TypeTester’s knowledge
Black-boxno inside information, like an outside attacker
Grey-boxpartial information, e.g. a normal user account
White-boxsource code, architecture, administrator accounts

Typical phases: scope and rules of engagement → information gathering → vulnerability scanning → controlled verification of findings → reporting (with risk level and remediation advice) → retest after the fix. The report is the real product of the test.

OWASP Top 10 (2021)

OWASP (Open Worldwide Application Security Project) publishes the most critical risk categories in web applications every few years. The 2021 list:

CodeCategoryTypical exampleCore countermeasure
A01Broken Access Controlchanging the id in the URL to see someone else’s record (IDOR)server-side authorization check on every request, default deny
A02Cryptographic Failuresstoring a password with MD5, card data over HTTPstrong algorithms, TLS, bcrypt/Argon2 for passwords
A03InjectionSQLi, XSS, OS command injectionparameterized queries, output encoding, allowlist
A04Insecure Designunlimited attempts on a password resetthreat modeling, secure design patterns
A05Security Misconfigurationdefault password, open directory listing, verbose errorshardening, automatic configuration
A06Vulnerable and Outdated Componentsa library with a CVE for which a patch existsdependency inventory, SCA, regular updates
A07Identification and Authentication Failuresa login open to brute force, weak session managementMFA, rate limiting, secure session ID
A08Software and Data Integrity Failuresunsigned updates, insecure deserializationdigital signatures, integrity checks, a trusted CI/CD
A09Security Logging and Monitoring Failuresfailed logins aren’t logged, no alertscentral logging, alerts, incident response plan
A10Server-Side Request Forgery (SSRF)the server sends a request into the internal network to a user-supplied URLdestination allowlist, block internal addresses

Important changes from 2017 to 2021: Broken Access Control rose from fifth to first; XSS stopped being a separate category and was merged into Injection; Insecure Design, Software and Data Integrity Failures and SSRF were added as new categories.

TIP · finding the category from the scenario. First ask: is the identity correct? If so, but unauthorized data is being accessed, it is A01; if the identity itself is the problem, A07. If data goes to an interpreter as code, A03. If the setting is wrong, not the code, A05. If the hole is in someone else’s library, A06. If the server goes to an address given by the user, A10.

Which test catches which category well? SAST is strong on A03, SCA is a perfect fit for A06, and DAST is good on A05. A01 and A04 are mostly human work: code review, threat modeling and pentest.

Common mistakes

Wrong ideaCorrect
SAST runs the programIt doesn’t; DAST and fuzzing do
DAST looks at the source codeIt doesn’t; it sends requests to the running application from outside
Fuzzing finds logic errors tooIt looks for crashes and hangs; it can’t see bugs like IDOR
precision = TP/(TP+FN)That is recall; precision = TP/(TP+FP)
A pentest can be done without permission, there’s no problem if I mean wellA test without written permission and scope is illegal
First in OWASP 2021 is InjectionA01 is Broken Access Control; Injection is A03
XSS is a separate category in 2021It is inside A03 Injection
A logged-in user sees someone else’s invoice → A07Identity is correct, authorization is wrong: A01
A logging library with a CVE → A09It is A06; A09 is the lack of logs and monitoring
One pentest is enoughIt is a snapshot; repeat it after every major change

Test yourself

Exam-style questions. Solve them on paper first, then reveal the answer.

Question 1easy

Which technique analyzes source code or bytecode for vulnerabilities without executing the program?

  1. DAST
  2. Fuzzing
  3. SAST
  4. Penetration testing
Show answer
C) SAST

SAST (static application security testing) reads the code without running it: it follows the data flow and checks whether unsanitized input reaches a dangerous point such as executeQuery. DAST and fuzzing send input to the running program, and a pentest is done on a running system.

Question 2easy

What does a fuzzer primarily do?

  1. Reads the code and reports insecure functions
  2. Feeds large numbers of malformed or random inputs to a program and watches for crashes or hangs
  3. Encrypts test data
  4. Generates documentation from code
Show answer
B) Feeds large numbers of malformed or random inputs to a program and watches for crashes or hangs

Fuzzing gives a program a large number of malformed, boundary or random inputs and looks for crashes, hangs and memory errors. A mutation-based fuzzer corrupts valid samples, and a generation-based fuzzer produces inputs from the grammar of the format. Modern fuzzers (AFL, libFuzzer) steer the input by code coverage.

Question 3easy

In the OWASP Top 10 (2021), which category is ranked #1?

  1. Injection
  2. Broken Access Control
  3. Cryptographic Failures
  4. Security Misconfiguration
Show answer
B) Broken Access Control

In the 2021 list, A01 is Broken Access Control. Injection, which was first in 2017, dropped to A03 in 2021. It rose to the top because some kind of access control flaw was found in a large share of the tested applications.

Question 4medium

A logged-in user views /invoice?id=1043, changes the URL to /invoice?id=1044, and sees another customer's invoice. Which OWASP 2021 category is this?

  1. A03 Injection
  2. A01 Broken Access Control
  3. A07 Identification and Authentication Failures
  4. A10 Server-Side Request Forgery
Show answer
B) A01 Broken Access Control

The user's identity is correct (logged in), but the server doesn't check whether the invoice belongs to this user. This is IDOR (insecure direct object reference), the typical example of A01. The fix: check invoice.ownerId == currentUser.id on every request (complete mediation).

Question 5medium

In OWASP Top 10 2021, cross-site scripting (XSS) is included in which category?

  1. It has its own category, A07 XSS
  2. A03 Injection
  3. A05 Security Misconfiguration
  4. It was removed from the list
Show answer
B) A03 Injection

In 2017, XSS was a separate category (A7). In 2021 it was merged into the Injection category, because the root cause is the same: untrusted data reaches an interpreter (the SQL engine, the browser) as code.

Question 6medium

An application stores user passwords as unsalted MD5 hashes. Which OWASP 2021 category best fits?

  1. A02 Cryptographic Failures
  2. A06 Vulnerable and Outdated Components
  3. A09 Security Logging and Monitoring Failures
  4. A04 Insecure Design
Show answer
A) A02 Cryptographic Failures

A weak hash that is unsuitable for passwords (MD5, unsalted) falls under A02. MD5 is very fast, and without salt identical passwords give the same hash and can be cracked with precomputed tables. The right way: a slow, salted password hash function such as bcrypt, scrypt or Argon2.

Question 7easy

A production server still has the vendor's default admin password and directory listing enabled. Which OWASP 2021 category is this?

  1. A05 Security Misconfiguration
  2. A01 Broken Access Control
  3. A08 Software and Data Integrity Failures
  4. A03 Injection
Show answer
A) A05 Security Misconfiguration

There is no bug in the code, the settings are wrong: default password, open directory listing, verbose error pages, unnecessary open services. All are A05. Countermeasure: a hardening checklist and automatic, repeatable configuration across environments.

Question 8hard

A SAST tool reports 40 findings; 28 of them are real vulnerabilities. The code actually contains 35 real vulnerabilities. What are the tool's precision and recall?

Show answer
precision = 0.70, recall = 0.80

True positives TP = 28, false positives FP = 40−28=1240 - 28 = 12, missed FN = 35−28=735 - 28 = 7.precision=TPTP+FP=2840=0.70\text{precision} = \frac{TP}{TP+FP} = \frac{28}{40} = 0.70recall=TPTP+FN=2835=0.80\text{recall} = \frac{TP}{TP+FN} = \frac{28}{35} = 0.80If precision is low, developers get tired of the false alarms; if recall is low, vulnerabilities slip through. Their harmonic mean is F1 ≈ 0.747.

Question 9hard

A mutation fuzzer triggers a particular crash with probability 1/50001/5000 per input, independently. It runs 20 000 inputs. What is the expected number of crashing inputs, and the probability of at least one crash (4 decimals)?

Show answer
4 expected, P ≈ 0.9817

Expected value np=20000/5000=4n p = 20000 / 5000 = 4.
At least one crash: 1−(1−p)n=1−(1−1/5000)20000≈0.98171 - (1 - p)^n = 1 - (1 - 1/5000)^{20000} \approx 0.9817.
Check: for small pp, 1−e−np=1−e−4≈0.98171 - e^{-np} = 1 - e^{-4} \approx 0.9817. To find low-probability bugs a large number of inputs is needed; the power of fuzzing comes from automation.

Question 10medium

A penetration tester is given full source code, architecture diagrams and credentials before testing. What type of test is this?

  1. Black-box
  2. White-box
  3. Grey-box
  4. Red-team without scope
Show answer
B) White-box

In a white-box (clear-box) test the tester knows everything: code, architecture, accounts. In black-box they know nothing, like an outside attacker. Grey-box is in between, for example only a normal user account is given. In every case written permission and a scope (rules of engagement) are required.

Question 11easy

An application uses a third-party logging library version with a publicly known critical CVE that has had a patch available for a year. Which OWASP 2021 category is this?

  1. A06 Vulnerable and Outdated Components
  2. A09 Security Logging and Monitoring Failures
  3. A02 Cryptographic Failures
  4. A04 Insecure Design
Show answer
A) A06 Vulnerable and Outdated Components

The hole is not in your code but in a component you use, and a patch exists but has not been applied: A06. Don't let the word "logging" in the name mislead you; A09 is about events not being logged and monitored. Countermeasure: a dependency inventory (SBOM) and SCA (software composition analysis) tools.

Question 12hard

A feature lets users enter a URL so the server fetches a preview image. An attacker enters http://169.254.169.254/ and the server returns internal cloud metadata. Which OWASP 2021 category is this, and what is the core fix?

  1. A03 Injection; escape HTML
  2. A10 SSRF; validate the destination against an allowlist and block internal address ranges
  3. A07 Authentication Failures; add MFA
  4. A05 Misconfiguration; disable directory listing
Show answer
B) A10 SSRF; validate the destination against an allowlist and block internal address ranges

The server sends a request on its own behalf to an address given by the user and reaches a service on the internal network: SSRF (server-side request forgery). The root fix is to limit the destinations the server can go to with an allowlist, block internal network and link-local ranges, and not follow redirects. Egress restrictions at the network level are the second layer.

Verification: Precision, recall, F1 and fuzzing probabilities (1 - (1 - p)^n) were computed with node (verify/SEN2008/14.mjs). The OWASP ranking was checked against the official 2021 list.

Review card

SAST: without running the code, early, all paths, many false positives. DAST: running application, from outside, also sees environment mistakes Fuzzing: many malformed/random inputs → crashes. mutation (corrupt a sample) | generation (produce from a grammar) | coverage-guided P(at least 1) = 1 - (1-p)^n ≈ 1 - e^(-np) expected = n·p Pentest: black (no information) | grey (partial) | white (code+architecture). Written permission + scope REQUIRED Phases: scope → discovery → scanning → validation → reporting → retest precision = TP/(TP+FP) recall = TP/(TP+FN) OWASP 2021: A01 Broken Access Control | A02 Cryptographic Failures | A03 Injection (includes XSS) A04 Insecure Design | A05 Security Misconfiguration | A06 Vulnerable & Outdated Components A07 Identification & Authentication Failures | A08 Software & Data Integrity Failures A09 Security Logging & Monitoring Failures | A10 SSRF IDOR (change an id and see someone else's data) → A01 default password → A05 MD5 password → A02