w3resource

SQL Injection Firewall & Rewriter


SQL Injection Firewall & Rewriter : A Reverse Proxy Database Security

SQL injection remains one of the most persistent and dangerous vulnerabilities in web application security. Despite decades of awareness and the widespread adoption of ORMs and parameterized queries, injection flaws continue to appear—in legacy code, in dynamically constructed queries, in ORMs with subtle bugs, and in third-party libraries that fail to sanitize input properly. A single successful injection can expose an entire database, allowing attackers to read sensitive data, modify records, or escalate privileges.

Traditional defenses operate at the application layer: parameterized queries, input validation, and ORM abstractions. These are essential, but they share a common limitation—they depend on the application code being correct. When a developer makes a mistake, or when a library introduces a vulnerability, the defenses fail silently. There is no independent layer that catches what the application misses.

The SQL Injection Firewall & Rewriter addresses this gap. It is a reverse-proxy middleware that sits between the application and the database, intercepting every SQL query before execution. It parses queries into an Abstract Syntax Tree (AST), analyzes their structure for injection patterns, rewrites suspicious queries to neutralize attacks, enforces row-level security policies, rate-limits abusive query patterns, and logs all attempts to an admin dashboard. The result is defense-in-depth: even if the application has a bug, the firewall catches and neutralizes the attack.

What It Does

The firewall operates as a transparent layer between the application and the database. Applications connect to the firewall's proxy port instead of the database directly, and the firewall forwards validated queries while blocking malicious ones. From the application's perspective, nothing changes—the same SQLAlchemy connections, the same query patterns, the same results. The security layer operates invisibly.

Query interception and parsing: Every SQL statement passes through the firewall, which parses it into an AST using tools like sqlparse for dialect-agnostic parsing or pglast for PostgreSQL-specific parsing. The AST represents the query's structure—its clauses, expressions, and tokens—rather than its text, making analysis more robust than pattern matching against strings.

Injection detection and rewriting: The firewall analyzes the AST for structural anomalies that indicate injection. A query that should have a simple WHERE id = 1 but instead has WHERE id = 1 OR 1=1 exhibits a structural deviation—an additional OR branch that was not present in the expected query shape. When such anomalies are detected, the firewall can rewrite the query to remove the injected clause or reject it entirely.

Row-level security enforcement: Beyond injection detection, the firewall enforces PostgreSQL Row-Level Security (RLS) policies. Even if an application query is structurally valid, it may violate access control rules—attempting to read rows belonging to other tenants, for example. The firewall can inject additional WHERE clauses or reject queries that violate policy.

Rate limiting: Suspicious query patterns—repeated failures, unusual query shapes, high-frequency requests—trigger rate limiting. Redis-backed counters track query rates per application, per user, or per query pattern, and the firewall blocks or throttles requests that exceed thresholds.

Logging and live alerts: Every query that triggers a security rule is logged to an admin dashboard. WebSockets stream alerts in real time, allowing security teams to respond to attacks as they happen rather than reviewing logs after the fact.

How It Works: The Query Lifecycle

Interception

The firewall runs as a reverse proxy in front of the database. Applications connect to the firewall's port instead of the database's native port. The firewall accepts connections, forwards them to the database, and interposes itself in the query stream. This architecture is transparent to the application—no code changes are required, only a configuration change to point the database connection at the firewall.

For PostgreSQL, the firewall can use the PostgreSQL wire protocol to intercept queries. For applications using SQLAlchemy, the interception can also occur at the driver level, capturing queries as they are emitted.

Parsing into AST

Once a query is intercepted, it is parsed into an AST. The choice of parser matters:

sqlparse is a non-validating SQL parser that accepts any input, making it suitable for analyzing queries that may be malformed (which is itself a signal of attack). It tokenizes SQL and groups tokens into a tree of statements, clauses, identifiers, and expressions. It is dialect-agnostic, supporting PostgreSQL, MySQL, SQLite, and others.

pglast is a PostgreSQL-specific parser that produces a detailed AST closely matching PostgreSQL's internal parse tree. It exposes parse_sql() to obtain the parse tree as Python objects, parse_sql_json() for JSON serialization, and fingerprint() for generating a hash that can compare different SQL statements structurally.

The AST provides a structural view of the query that is robust to obfuscation. An attacker might encode OR 1=1 as OR/**/1/**/=/**/1 to evade pattern matching, but the AST represents both the same way—as an additional boolean expression in the WHERE clause. This is the key advantage of AST-based detection over regex-based filtering.

Injection Detection

The firewall detects injection by comparing the structure of incoming queries against expected patterns. Several techniques contribute:

Structural anomaly detection: A normal query has a predictable AST shape. A query for a specific user by ID might have a WHERE clause with a single equality comparison. An injected version has an additional OR branch, or a UNION clause, or a subquery that was not present before. The branch count and node types of the AST reveal these anomalies.

Tautology detection: Injection payloads like OR 1=1 or OR 'a'='a' create always-true conditions that bypass authentication or return all rows. The AST reveals these as boolean expressions where both sides are constants, which is structurally suspicious in a WHERE clause.

Stacked query detection: Multiple statements separated by semicolons—SELECT * FROM users; DROP TABLE users—appear as multiple root nodes in the AST. Legitimate application queries rarely use stacked queries; their presence is a strong injection signal.

UNION-based detection: A UNION SELECT clause in a query where none is expected indicates an attempt to extract data from other tables. The AST shows the UNION node and its target list, revealing the injected columns.

Time-based and out-of-band detection: Functions like SLEEP(), pg_sleep(), or xp_cmdshell() in query expressions are red flags. The AST identifies these function calls and their arguments.

Query Rewriting

When injection is detected, the firewall has several options:

Reject: Refuse to execute the query and return an error. This is the safest response but may break legitimate functionality if the detection is a false positive.

Rewrite: Modify the AST to remove or neutralize the injected portion, then serialize it back to SQL. For a tautology injection, the firewall can remove the injected OR branch, restoring the query to its intended form. This preserves functionality while eliminating the attack.

Sanitize: Replace dangerous constructs with safe equivalents. For example, a stacked query could be split into its constituent statements, with only the first (legitimate) statement executed.

The rewriting capability is what distinguishes a firewall from a filter. A filter blocks attacks; a firewall neutralizes them, allowing the application to continue functioning while the attack is defused.

Row-Level Security Enforcement

Beyond injection detection, the firewall enforces access control policies. PostgreSQL's native RLS allows policies to be defined on tables, with the database enforcing them for every query. The firewall can complement this by:

Injecting policy predicates: For applications that do not use native RLS, the firewall can add WHERE clauses to queries, restricting rows based on session context (user ID, tenant ID, role).

Validating query scope: Even with native RLS, the firewall can verify that queries do not attempt to bypass policies through functions, views, or other constructs.

Managing policy definitions: Using tools like sqlalchemy-pg-access or rlsalchemy, policies can be defined declaratively in SQLAlchemy models and deployed through Alembic migrations, ensuring that access control is version-controlled and auditable.

Rate Limiting

Suspicious queries—those that trigger injection rules, fail repeatedly, or exhibit unusual patterns—are rate-limited. Redis provides the backing store for counters, with sliding window algorithms ensuring that limits are enforced precisely. A sliding window counter considers all requests within the last N seconds, regardless of window boundaries, preventing the burst-at-boundary evasion that plagues fixed windows.

Rate limits can be applied per application, per user, per IP address, or per query pattern. When limits are exceeded, the firewall returns an error or delays the response, slowing attackers while legitimate traffic continues.

Modern Technology Stack

sqlparse and pglast for AST Parsing

sqlparse provides dialect-agnostic parsing suitable for analyzing queries across database systems. Its non-validating nature is an advantage—it can parse malformed queries, which are themselves indicators of attack.

pglast provides PostgreSQL-specific parsing with a detailed AST that closely matches PostgreSQL's internal representation. It supports JSON and Protocol Buffer serialization, making it suitable for detailed structural analysis.

FastAPI Middleware

FastAPI serves as the application framework for the firewall's control plane—the admin dashboard, API endpoints for policy management, and WebSocket connections for live alerts. The firewall itself operates at the database proxy level, but FastAPI manages the surrounding infrastructure.

Redis for Rate Limiting

Redis provides high-performance counters for rate limiting. Sorted sets and Lua scripts enable atomic sliding window implementations that handle high throughput with minimal latency. The Redis tutorial on rate limiting provides reference implementations for fixed and sliding window algorithms.

PostgreSQL RLS Policies

PostgreSQL's native Row-Level Security provides the foundation for access control. Policies define which rows are visible to which users, and the database enforces them automatically. Tools like sqlalchemy-pg-access and rlsalchemy integrate policy definition with SQLAlchemy models and Alembic migrations, making access control declarative and version-controlled.

WebSockets for Live Alerts

WebSockets enable real-time streaming of security alerts to the admin dashboard. When a query triggers a rule, the firewall pushes an alert through a WebSocket connection, updating the dashboard immediately. This real-time visibility is essential for incident response—security teams can see attacks as they happen and respond before damage occurs.

User Benefits

Last Line of Defense

The primary benefit is defense-in-depth. The firewall is not a replacement for parameterized queries or ORM best practices—it is an additional layer that catches what those defenses miss. Even if an ORM has a bug, or a developer constructs a query unsafely, or a third-party library introduces a vulnerability, the firewall intercepts the resulting query and neutralizes the attack. This redundancy is the essence of defense-in-depth.

No Application Code Changes

The firewall operates as a reverse proxy. Applications connect to it instead of the database directly. No code changes, no library updates, no refactoring. The security layer is transparent to the application, making it practical to deploy in existing systems.

Row-Level Security Without Application Complexity

Enforcing access control in the application requires every query to include the right WHERE clauses. Miss one, and data leaks. The firewall centralizes this enforcement, applying policies at the database boundary. Applications can be written without security concerns, knowing that the firewall will enforce them.

Visibility into Attack Attempts

The logging and alerting features provide visibility that applications typically lack. Developers and security teams can see attempted injections, failed queries, and rate-limit violations in real time. This visibility supports incident response and provides data for improving application security.

Compliance Support

For organizations subject to regulatory requirements—PCI DSS, HIPAA, GDPR—the firewall provides evidence of security controls. Logs show that queries are inspected, policies are enforced, and attacks are blocked. This documentation supports compliance audits.

Conclusion

The SQL Injection Firewall & Rewriter represents a pragmatic approach to application security: assume the application will have bugs, and build defenses that catch them. By intercepting queries at the database boundary, parsing them into ASTs, detecting structural anomalies, and rewriting malicious queries, it provides protection that operates independently of application code quality.

The technology stack—sqlparse and pglast for parsing, FastAPI for orchestration, Redis for rate limiting, PostgreSQL RLS for access control, and WebSockets for live alerts—is composed of mature, well-understood tools. The architecture is transparent, requiring no application changes. And the benefits—defense-in-depth, centralized access control, real-time visibility—are concrete and valuable.

In a world where SQL injection remains a top vulnerability, tools that provide independent protection are essential. The SQL Injection Firewall & Rewriter is not a silver bullet—no security tool is. But as one layer in a defense-in-depth strategy, it catches what other layers miss, neutralizing attacks before they reach the database.



Follow us on Facebook and Twitter for latest update.