✳ Field lesson AT3 / 10 min

Software testing: SAST, DAST, IAST, SCA, fuzzing, and coverage math

No single software scanner catches every class of bug: a static analyzer sees dead code paths but misses runtime authentication misconfigurations, while a dynamic web scanner sees live HTTP responses but cannot see unreached branches in source code. Combining SAST, DAST, IAST, SCA, fuzzing, and branch-coverage metrics creates a layered verification pipeline.

Assessment & TestingCISSP Domain 6AppSec TestingFuzzingCISSP D6CySA+ (CS0-003) D2CISA D3

Helpful first: Direct and transitive dependencies: inherited code in your runtime · Penetration testing, Rules of Engagement, and vulnerability validation

Key points

  • Contrast SAST (white-box source/bytecode), DAST (black-box running app), IAST (gray-box runtime sensor), RASP, and SCA (open-source dependencies)
  • Compare Mutation-Based ("dumb") Fuzzing vs Generation-Based ("smart" protocol/grammar-aware) Fuzzing
  • Calculate and order Statement Coverage, Branch/Decision Coverage, and Path Coverage in software test suites

SAST, DAST, IAST, SCA, and RASP across the build pipeline

Modern application security testing layers five distinct analysis engines across the Software Development Life Cycle (SDLC). Static Application Security Testing (SAST) is a White-Box method that parses source code, bytecode, or compiled binaries without executing the program. Because SAST runs directly in the IDE or on every pull request before a build is even deployed, it catches injection sinks, hardcoded secrets, and insecure API calls at the cheapest possible moment - though it can produce false positives when it cannot prove whether a code path is reachable at runtime.

Dynamic Application Security Testing (DAST) is a Black-Box method that tests a running application from the outside by sending crafted HTTP requests and inspecting responses. DAST excels at finding runtime server misconfigurations, missing security headers, authentication flow bugs, and environment-specific flaws that static source analysis cannot see, but DAST cannot tell you which line of source code caused the bug.

Interactive Application Security Testing (IAST) bridges both worlds (Gray-Box): an instrumentation sensor runs inside the application server (JVM, .NET, Node, Python) while functional or DAST tests execute, observing real data flows, SQL queries, and memory calls to report verified vulnerabilities with exact file-and-line precision. Meanwhile, Software Composition Analysis (SCA) inventories open-source dependencies and transitive lockfiles against known vulnerability databases, and Runtime Application Self-Protection (RASP) hooks into the production runtime to detect and block exploit payloads in flight.

Application security testing methods compared
Tool categoryBox model & stateWhat it finds best
SAST (Static)White-Box / Non-running source or bytecodeTainted data flows, unsafe functions, hardcoded secrets, exact file/line numbers early in coding.
DAST (Dynamic)Black-Box / Running application over networkRuntime misconfigurations, TLS/header gaps, authentication and session state flaws.
IAST (Interactive)Gray-Box / Instrumented runtime during QA testsVerified exploitable data paths combining runtime HTTP context with exact source line numbers.
SCA (Software Composition)Manifests, lockfiles, container layers, SBOMVulnerable direct and transitive third-party open-source packages and license risks.
Fuzzing (Mutation / Generation)Automated malformed input injectionMemory corruption, buffer overflows, integer overflows, parser crashes, and assertion panics.

Fuzz testing: mutation-based vs generation-based fuzzers

Written unit tests only check the inputs a developer remembered to write. Fuzzing (Fuzz Testing) discovers unknown edge cases, memory corruption (buffer overflows, use-after-free), and unhandled parser panics by automatically feeding thousands of invalid, unexpected, or semi-random inputs into a target interface while monitoring for crashes or sanitizer violations (such as AddressSanitizer / ASan).

Fuzzers fall into two main designs. A Mutation-Based ("Dumb") Fuzzer takes corpus samples of real, valid inputs (such as a recorded satellite telemetry packet or a valid PDF file) and randomly flips bits, truncates bytes, or inserts boundary integers (0, -1, MAX_INT). Mutation fuzzing is fast to set up because it requires no prior knowledge of the file format.

However, if the target protocol starts with a strict magic header or cryptographic checksum, a purely random bit-flip is rejected on line 1 of the parser and never reaches deep state logic. A Generation-Based ("Smart") Fuzzer (and modern coverage-guided fuzzers like libFuzzer/AFL++) understands the exact grammar, state machine, and checksum rules of the protocol, generating structurally valid packets with malicious field values that penetrate deep into the application’s execution paths.

Test coverage math (Statement, Branch, Path) and synthetic monitoring

When evaluating how thoroughly a test suite exercises source code, engineers use Structural Code Coverage metrics. Statement (Line) Coverage is the weakest metric: it measures the percentage of executable lines of code that ran at least once (Executed Statements / Total Statements). Consider a single guard if (isAuthorized) {transferFunds();} with no else clause: a single test where isAuthorized == true achieves 100% Statement Coverage, yet completely fails to test what happens when isAuthorized == false!

Branch (Decision) Coverage is stronger: it requires every boolean decision (true AND false outcomes of every if, while, and switch) to be exercised at least once (Executed Branches / Total Branches). Therefore, 100% Branch Coverage always guarantees 100% Statement Coverage, but 100% Statement Coverage does NOT guarantee 100% Branch Coverage. Even stronger are Condition Coverage (testing each individual boolean sub-expression) and Path Coverage (testing every possible combinatorial route through the function).

Finally, in production, teams pair Passive Monitoring (real user monitoring / network tap observation that adds zero synthetic load) with Active / Synthetic Monitoring (scheduled headless transactions that continuously verify login, API latency, and security controls before real users notice an outage).

CHECK YOUR JUDGMENT

Dax Mercer wants to analyze Meridian’s (chronos.orbital) raw TypeScript and Rust source code directly inside the pull-request CI pipeline - before the code is compiled or deployed to a staging server - to identify SQL string concatenation and unsafe memory blocks along with their exact file and line numbers. Which testing methodology should he configure for this stage?

NEXT FIELD LESSON

Digital forensics: order of volatility, chain of custody, and legal evidence

↗

Find your next idea.

Tip: press / to open search. Escape closes this window.