Recommended resources
The freely available resources this lesson will direct you to.
Hello! Welcome to the next lesson in our course on architecting security products.
In our last lesson, we designed the crucial front-end component of our WAF: the request interception and parsing engine. We established how to terminate connections, parse ambiguous HTTP into a clean internal representation, and normalize it to defeat evasions. We now have a trusted, structured request object ready for inspection.
Today, we will design the inspection engine itself. This lesson directly addresses the learning outcome: Design a modular inspection pipeline that chains multiple security modules (e.g., signature, anomaly) with configurable execution order. We'll move from the 'what' (a clean request) to the 'how' (the system that finds attacks within it).
1. The Case for a Modular Pipeline
A modern WAF is not a single, monolithic function that inspects a request. It's a collection of specialized security services. For example, you might want to check the source IP against a reputation list, scan for known attack signatures, and analyze the request's structure for anomalies.
Architecting this as a modular pipeline is the standard, effective design pattern. This means treating each security check as an independent module and chaining them together.
Why is this a superior design?
- Flexibility & Maintainability: You can add, remove, or update individual security modules (e.g., add a new bot detection module) without rewriting the entire engine.
- Performance: It allows for strategic ordering. Cheap, high-impact checks can run first, potentially blocking a request before it consumes resources on more expensive, deeper analysis.
- Composability: Different customers or applications might require different sets of protections. A modular design makes it easy to assemble custom pipelines.
Let's look at a couple of real-world examples that illustrate this pattern.


2. A First-Principles View of the Pipeline
Before we design the WAF pipeline, let's step back and consider the abstract model. Thinking about this from first principles will give us a solid theoretical foundation, which is a core goal of your learning.
A research paper on runtime security enforcement provides an excellent conceptual model. It breaks the process into independent stages, which we can adapt for our WAF design.
A Modular Pipeline for Optimal Enforcement of Security Properties at ...
The paper 'A Modular Pipeline for Optimal Enforcement of Security Properties' presents a formal model for a security pipeline. We won't focus on the mathematical formalisms, but on the high-level architectural separation of concerns it proposes.
Please read the following sections to grasp the core concepts: Read the Abstract and the last three paragraphs of the Introduction (starting from 'The present paper offers an alternative solution...'). This introduces the three-stage model. Skim Section 6.1, 'Pipeline Description', and study Figure 12. This figure is the key takeaway. It visually separates the pipeline into distinct components: a monitor (µ), a proxy (π), a ranking transducer (ρ), and a gate. Finally, read Section 7.6, 'Discussion', focusing on the paragraphs contrasting the proposed modular pipeline with classical monolithic enforcement monitors. This reinforces the 'why' behind our modular approach.
The paper's model (visualized in its Figure 12) proposes a separation of concerns that we can map directly to our WAF architecture:
- Proxy (π): Generates possibilities. In the paper's context, it suggests corrections. In our WAF, this corresponds to the set of available inspection modules. Each module (SQLi, XSS, IP reputation) "proposes" a view on the request—is it malicious or not?
- Monitor (µ): Evaluates against a policy. This is our rule evaluation engine. It takes the findings from the inspection modules and determines if a policy has been violated. For example, did the SQLi module find a match with a severity score of 'critical'?
- Ranking Transducer (ρ) & Gate: Selects an outcome and acts. This is our decision and enforcement engine. Based on the evaluation, it decides what to do: block the request, log it, or simply increment a risk score and pass it to the next module. The "gate" is the component that executes this action.
This abstract model provides a powerful mental framework: our WAF pipeline is a system that passes a request through a series of modules, evaluates the findings from each, and makes a final decision.
3. Designing the WAF Inspection Pipeline
Now, let's translate this conceptual model into a concrete software architecture.
Our pipeline will be an ordered list of Inspector interfaces. Each Inspector module takes the structured request object and returns a result.
// Simplified conceptual interface
enum ActionResult { PASS, LOG, BLOCK };
interface InspectionResult {
ActionResult getAction();
String getRuleId();
int getRiskScoreContribution();
// ... other metadata
}
interface Inspector {
InspectionResult inspect(StructuredRequest request);
}
The core engine would look something like this in pseudocode:
// The main WAF inspection logic
List<Inspector> pipeline = loadPipelineConfiguration(); // Load modules in configured order
int totalRiskScore = 0;
for (Inspector module : pipeline) {
InspectionResult result = module.inspect(request);
totalRiskScore += result.getRiskScoreContribution();
if (result.getAction() == ActionResult.BLOCK) {
blockRequest(request, result.getRuleId());
return; // Terminate pipeline
}
}
// If we finished the loop without blocking, make a final decision
if (totalRiskScore > ANOMALY_THRESHOLD) {
blockRequest(request, "ANOMALY_SCORE_EXCEEDED");
} else {
passRequestToBackend(request);
}
This simple structure already reveals two fundamental operating modes:
- Blocking Mode: A single rule can terminate the pipeline and block the request immediately. This is efficient. The
RuleCachepaper refers to this as "self-contained mode". - Scoring Mode (or Anomaly Mode): All rules run, each contributing to a cumulative risk score. A final decision is made based on the total score. This is more flexible for detecting complex, low-and-slow attacks but has a higher performance cost as more rules are processed.
A robust WAF should support both models and make them configurable.
4. The Challenge: Configurable Execution Order
The order of modules in the pipeline is critical for performance. The principle is to fail fast: run the cheapest and most effective checks first.
- Good ordering:
IP Reputation Check->HTTP Protocol Compliance->Signature Matching->Anomaly Scoring. - Bad ordering:
Anomaly Scoring->Signature Matching->IP Reputation Check.
Running an expensive regex-based signature scan on a request from a known-bad IP address is a waste of CPU cycles. The RuleCache paper provides empirical evidence for this.
RuleCache: Accelerating Web Application Firewalls by On-line ...
The paper 'RuleCache: Accelerating Web Application Firewalls by On-line Rule-based Caching' dives into the performance implications of rule ordering and the complexities of designing a reconfigurable pipeline.
Please read the following sections: Start with Section III.C, 'Redundant Rule Processing'. Focus on the 'Motivation' and 'Insights' subsections, including Figure 2 and Figure 3. This clearly demonstrates that rule hit-frequency is skewed and that rule location directly impacts performance. Next, read Section IV.B.1, 'Rule Dependency'. This is the most critical part for our design. It explains the 'data hazards' and 'control hazards' that prevent us from reordering rules arbitrarily. Pay attention to how it categorizes these dependencies.
The RuleCache paper highlights the primary obstacle to a fully configurable pipeline: rule dependencies. You, as a software engineer, will recognize these as analogous to instruction hazards in a CPU pipeline.
- Data Hazards: One rule depends on the output of another. The paper gives the example of a rule that increments a
DOS_COUNTERand a subsequent rule that checks if that counter has exceeded a threshold. Reversing their order would break the logic. This is a classic Read-After-Write (RAW) dependency. - Control Hazards: A rule conditionally skips a block of other rules (e.g., using ModSecurity's
skipAfteraction). Moving a rule into or out of this block, or moving the initial rule itself, would alter the control flow and break the intended logic.
Design Solution: Atomic Rule Groups
The architectural solution is to not treat every single rule as independently movable. Instead, you analyze the dependencies and group rules that must execute together in a fixed order into atomic blocks or sub-groups.
Conceptual illustration of rule dependencies. Rules A, B, and C must run in that specific order, forming an atomic group. This group, however, can be moved relative to other independent rules (like D) or other atomic groups in the main pipeline.
Your WAF's configuration would then define the execution order of these atomic groups and other independent modules. The internal order of an atomic group remains immutable. This design provides a safe and effective balance between configurability and correctness.
5. Advanced Design: Dynamic Pipeline Optimization
A static, manually configured pipeline order is a great start. But the optimal order depends on the specific traffic an application is receiving. For example, if you are suddenly under a massive SQL injection attack, moving the SQLi detection module earlier in the pipeline would be more efficient.
This leads to an advanced design: a system that dynamically optimizes the pipeline order based on live traffic patterns. The RuleCache paper outlines a fantastic architecture for this.
This is a simplified representation of the architecture from Figure 1 of the 'RuleCache' paper. It shows an online engine processing traffic and an offline analyzer that computes optimal configurations.
- Online Engine: The WAF pipeline that processes live requests. It uses the current "best" rule ordering. It also logs metadata about rule execution (e.g., which rules matched, how long each took).
- Offline Analyzer: A separate system (or a background process) that ingests these logs. It analyzes the frequency and cost of each rule group based on recent traffic.
- Optimization Algorithm: The analyzer uses this data to solve a combinatorial optimization problem: "Given the current traffic statistics, what is the rule order with the lowest expected processing cost?" The paper suggests using a Genetic Algorithm, a powerful technique for such problems.
- Feedback Loop: The newly computed optimal order is periodically pushed to the online engine, which updates its pipeline for the next time window.
This architecture creates a self-tuning system that adapts to changing traffic and threat patterns, which is a hallmark of a sophisticated, modern security product.
Conclusion
In this lesson, we have designed the heart of our WAF: a modular inspection pipeline. We've moved from a simple, linear sequence of checks to a sophisticated, configurable, and dynamically optimizable system.
Key Takeaways:
- Modularity is Key: A WAF's inspection logic should be built as a pipeline of independent modules (e.g., IP reputation, signature matching, anomaly detection).
- Execution Order Matters: Running cheap, high-hit-rate checks first ("fail fast") is critical for performance.
- Dependencies are the Constraint: You cannot reorder rules arbitrarily. Data and control dependencies must be identified and encapsulated into atomic rule groups.
- Dynamic Optimization is the Goal: The most advanced WAFs can analyze live traffic to continuously re-calculate and deploy the most efficient pipeline order.
- Blocking vs. Scoring: The pipeline must support both immediate blocking for clear threats and cumulative scoring for more nuanced anomaly detection.
Preview of Next Lesson:
We've designed the pipeline that holds the security modules. Now, we'll build one of those modules. In the next lesson, we will tackle the learning outcome: Architect a signature-based detection engine, including rule storage strategies and string matching algorithm selection (e.g., Aho-Corasick). This will be a deep dive into the most common type of WAF inspection.