The Developer Problem: Unchecked Prompt Vulnerabilities in Production
As Large Language Model (LLM) applications move from simple internal experiments into customer-facing production systems, user-provided text inputs become an unmonitored attack vector. Unlike traditional SQL queries or REST API parameters that follow strict structural schemas, natural language inputs are inherently unconstrained.
Exposing raw LLM endpoints directly to end users introduces severe security vulnerabilities:
Direct and Indirect Prompt Injections: Adversaries craft inputs that override system prompts (direct) or inject malicious payload instructions into retrieved external documents or vector databases (indirect).
System Prompt and Context Leakage: Attackers coerce the model into dumping proprietary instructions, internal API tokens, or embedded enterprise state.
Data Exfiltration and PII Exposure: Unfiltered model responses can leak sensitive Personally Identifiable Information (PII), proprietary source code, or internal database records.
Jailbreaking and Toxic Output Generation: Malicious inputs bypass safety filters to force models into generating inappropriate, illegal, or brand-damaging outputs.
Denial of Wallet (DoW) and Resource Exhaustion: Maliciously oversized inputs or recursive prompt loops deplete API budgets and cause application latency spikes.
An Enterprise Prompt Firewall acts as an inline security boundary between client applications and downstream AI models. It enforces policy checks, sanitizes inputs, detects injection attacks, redacts PII, and validates outputs before returning data to the caller.
Architecture: Inline Gateway vs. Direct Model Execution
An enterprise prompt firewall runs as a lightweight, low-latency API gateway or pipeline middleware. It intercepts both incoming prompts (ingress) and outgoing completions (egress).
┌────────────────────────────────┐
│ Untrusted User / API │
└───────────────┬────────────────┘
│
Incoming Prompt
│
▼
┌────────────────────────────────┐
│ Enterprise Prompt Firewall │
│ (Regex, Heuristics, Small AI) │
└───────┬────────────────┬───────┘
│ │
Blocked │ │ Passed & Sanitized
┌────────────────┘ └────────────────┐
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ Reject Request (403) │ │ AI Model / LLM Endpoint │
│ Log Security Incident │ │ (Azure OpenAI / Foundry)│
└─────────────────────────┘ └───────────┬─────────────┘
│
Model Completion
│
▼
┌─────────────────────────┐
│ Egress Response Guard │
│ (PII Redaction & Egress)│
└─────────────────────────┘
The table below contrasts unmonitored model calls with firewall-protected prompt execution:
| Security Dimension | Direct Model Execution | Prompt Firewall Protected Execution |
|---|---|---|
| Input Validation | None; trusts user input completely. | Deterministic regex, heuristic bounds, and semantic classifier inspection. |
| Injection Defense | Vulnerable to system prompt overrides. | Ingress intent classification blocks direct and indirect jailbreaks. |
| Data Protection | Risk of outputting raw internal PII or context leaks. | Automatic real-time token redaction on both ingress and egress. |
| Audit Compliance | Fragmented application logs without security tagging. | Centralized immutable audit trails with threat classification tags. |
| Latency & Cost | Low upfront overhead; high risk of costly runaway prompts. | Sub-20ms evaluation overhead; prevents resource consumption attacks. |
Implementing an Enterprise Prompt Firewall in .NET
The following step-by-step walkthrough demonstrates how to build an inline prompt firewall in ASP.NET Core using Microsoft.Extensions.AI and custom pipeline middleware.
Step 1: Install Required Package Dependencies
Add the required ASP.NET Core and AI packages:
Bash
dotnet add package Microsoft.Extensions.AI
dotnet add package Microsoft.Extensions.AI.OpenAI
dotnet add package System.Text.RegularExpressions
Step 2: Define Firewall Policy Models and Request Context
Define structures for threat scoring, firewall configuration rules, and policy outcomes.
C#
public enum ThreatSeverity
{
None = 0,
Low = 1,
Medium = 2,
High = 3,
Critical = 4
}
public record SecurityEvaluationResult(
bool IsAllowed,
ThreatSeverity Severity,
string DetectedRule,
string SanitizedContent);
public class PromptFirewallOptions
{
public int MaxInputLength { get; set; } = 2000;
public bool EnablePiiRedaction { get; set; } = true;
public List<string> SystemOverridePatterns { get; set; } = new()
{
@"(?i)ignore\s+previous\s+instructions",
@"(?i)system\s*:\s*override",
@"(?i)you\s+are\s+now\s+a",
@"(?i)reveal\s+your\s+system\s+prompt"
};
}
Step 3: Implement Ingress and Egress Inspection Engines
Construct the firewall engine containing fast regex pattern matchers, heuristics, and PII anonymization rules.
C#
using System.Text.RegularExpressions;
public class PromptFirewallEngine
{
private readonly PromptFirewallOptions _options;
// Regex pattern for basic PII identification (e.g., SSN, Email)
private static readonly Regex EmailRegex = new(@"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}", RegexOptions.Compiled);
private static readonly Regex SsnRegex = new(@"\b\d{3}-\d{2}-\d{4}\b", RegexOptions.Compiled);
public PromptFirewallEngine(PromptFirewallOptions options)
{
_options = options;
}
public SecurityEvaluationResult InspectIngressPrompt(string rawPrompt)
{
// 1. Check Input Length (Denial of Wallet Prevention)
if (rawPrompt.Length > _options.MaxInputLength)
{
return new SecurityEvaluationResult(
IsAllowed: false,
Severity: ThreatSeverity.High,
DetectedRule: "LengthConstraintExceeded",
SanitizedContent: string.Empty);
}
// 2. Scan for Direct Prompt Injection / Jailbreak Patterns
foreach (var pattern in _options.SystemOverridePatterns)
{
if (Regex.IsMatch(rawPrompt, pattern))
{
return new SecurityEvaluationResult(
IsAllowed: false,
Severity: ThreatSeverity.Critical,
DetectedRule: $"InjectionPatternMatched: {pattern}",
SanitizedContent: string.Empty);
}
}
// 3. Apply Ingress PII Redaction
string sanitizedPrompt = rawPrompt;
if (_options.EnablePiiRedaction)
{
sanitizedPrompt = EmailRegex.Replace(sanitizedPrompt, "[REDACTED_EMAIL]");
sanitizedPrompt = SsnRegex.Replace(sanitizedPrompt, "[REDACTED_SSN]");
}
return new SecurityEvaluationResult(
IsAllowed: true,
Severity: ThreatSeverity.None,
DetectedRule: "CleanPass",
SanitizedContent: sanitizedPrompt);
}
public string InspectEgressResponse(string rawResponse)
{
if (!_options.EnablePiiRedaction) return rawResponse;
// Anonymize outbound sensitive data leaks
string sanitized = EmailRegex.Replace(rawResponse, "[REDACTED_EMAIL]");
return SsnRegex.Replace(sanitized, "[REDACTED_SSN]");
}
}
Step 4: Wire Firewall Middleware into ASP.NET Core Pipeline
Inject the prompt firewall as a middleware pipeline delegator surrounding your model calls.
C#
using Microsoft.Extensions.AI;
public class FirewallChatClientMiddleware : DelegatingChatClient
{
private readonly PromptFirewallEngine _firewallEngine;
public FirewallChatClientMiddleware(IChatClient innerClient, PromptFirewallEngine firewallEngine)
: base(innerClient)
{
_firewallEngine = firewallEngine;
}
public override async Task<ChatCompletion> CompleteAsync(
IList<ChatMessage> chatMessages,
ChatOptions? options = null,
CancellationToken cancellationToken = default)
{
// 1. Intercept latest user input for ingress evaluation
var userMessage = chatMessages.LastOrDefault(m => m.Role == ChatRole.User);
if (userMessage != null && !string.IsNullOrEmpty(userMessage.Text))
{
var result = _firewallEngine.InspectIngressPrompt(userMessage.Text);
if (!result.IsAllowed)
{
Console.WriteLine($"[SECURITY FIREWALL BLOCK]: Rule={result.DetectedRule}, Severity={result.Severity}");
throw new InvalidOperationException($"Security Policy Violation: Prompt blocked by enterprise firewall ({result.DetectedRule}).");
}
// Replace input message text with sanitized version
userMessage.Text = result.SanitizedContent;
}
// 2. Proceed with model execution
var completion = await base.CompleteAsync(chatMessages, options, cancellationToken);
// 3. Intercept egress response for PII leakage filtering
if (!string.IsNullOrEmpty(completion.Message.Text))
{
completion.Message.Text = _firewallEngine.InspectEgressResponse(completion.Message.Text);
}
return completion;
}
}
Architectural Advantages and Disadvantages
Advantages
Centralized Policy Enforcement: Security teams update prompt injection rules and data loss prevention (DLP) filters centrally without touching application code.
Low Latency Defense: Fast regex and rule heuristic evaluation checks execute in sub-millisecond times before making expensive network calls to the LLM.
Defensive In-Depth Protection: Protects applications against both direct malicious prompts and indirect injections hidden inside third-party documents.
Disadvantages
False Positive Risks: Overly aggressive pattern matching may block legitimate complex user prompts that happen to include restricted keywords.
Maintenance Overhead: Attack techniques evolve continuously, requiring regular security updates to injection pattern libraries.
Enterprise Best Practices
Use Multi-Layered Inspection: Combine deterministic rules (regex, length limits) with fast lightweight classifier models (e.g., small local transformers) for intent evaluation.
Isolate System Prompts Using XML Delimiters: Enclose system instructions and untrusted user inputs inside distinct XML tags (e.g.,
<user_input>...</user_input>) to help the LLM maintain boundary awareness.Log All Blocked Events to SIEM: Stream security violation events directly to central enterprise SIEMs (such as Azure Sentinel or Splunk) for real-time threat analysis.
Enforce Rate Limits per Client Identity: Implement sliding-window rate limiting on firewall endpoints to mitigate automated brute-force jailbreak attempts.
Common Mistakes to Avoid
Relying Solely on the System Prompt for Security: Adding "Do not allow prompt injection" to system instructions is insufficient. Always enforce policy programmatically outside the model context window.
Inspecting Ingress Only: Ignoring output completions allows the model to accidentally leak internal PII or database structures to clients.
Hardcoding Firewall Rules in Controller Methods: Placing security logic inside API endpoints creates duplicate code across services. Always use centralized middleware handlers.
Troubleshooting Guide
Issue 1: High False-Positive Block Rates for Valid User Queries
Root Cause: Ingress regex patterns are too broad (e.g., blocking any query containing the word "system" or "ignore").
Resolution: Refine regex rules to check for complete phrases (e.g.,
\bignore\s+all\s+previous\s+instructions\b) and require higher threat confidence scores before triggering hard blocks.
Issue 2: Indirect Injection Bypasses Ingress Filters
Root Cause: The malicious payload was retrieved dynamically from a RAG database document rather than submitted directly in the initial user request.
Resolution: Run retrieved context chunks through the
InspectIngressPromptfirewall engine before concatenating them into prompt context windows.
Issue 3: PII Redaction Corrupts Code Snippets
Root Cause: Regex patterns misinterpret software code structures (e.g., variable names containing
@) as email addresses.Resolution: Configure contextual PII scanners that distinguish plain text blocks from markdown code blocks before applying anonymization replacements.
Frequently Asked Questions (FAQs)
1. What is the difference between an API Gateway and a Prompt Firewall?
A standard API Gateway handles traditional network traffic concerns like TLS termination, rate limiting, and route mapping. A Prompt Firewall performs deep content inspection on natural language inputs and LLM completions to detect injection attacks, toxicity, and PII leaks.
2. Should a Prompt Firewall run as a sidecar or middleware in .NET?
For monolithic .NET applications, running the firewall as custom ASP.NET Core middleware (DelegatingChatClient) provides sub-millisecond latency. For microservice or multi-language architectures, deploying a dedicated sidecar or proxy gateway (e.g., YARP or Azure API Management) is recommended.
3. How do prompt firewalls defend against indirect prompt injection?
Prompt firewalls scan both direct user prompts and external data sources (such as web search results or vector database chunks) prior to assembling the final LLM prompt payload, stripping hidden execution commands.
Conclusion
Deploying generative AI applications without an Enterprise Prompt Firewall exposes systems to prompt injections, data exfiltration, and compliance failures. By building inline middleware in .NET that sanitizes inputs, scans for malicious overrides, and redacts outgoing PII, engineering teams can safely deploy production AI features with confidence.
Join the conversation! Your thoughts help the community grow.