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:

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 DimensionDirect Model ExecutionPrompt Firewall Protected Execution
Input ValidationNone; trusts user input completely.Deterministic regex, heuristic bounds, and semantic classifier inspection.
Injection DefenseVulnerable to system prompt overrides.Ingress intent classification blocks direct and indirect jailbreaks.
Data ProtectionRisk of outputting raw internal PII or context leaks.Automatic real-time token redaction on both ingress and egress.
Audit ComplianceFragmented application logs without security tagging.Centralized immutable audit trails with threat classification tags.
Latency & CostLow 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

Disadvantages

Enterprise Best Practices

  1. Use Multi-Layered Inspection: Combine deterministic rules (regex, length limits) with fast lightweight classifier models (e.g., small local transformers) for intent evaluation.

  2. 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.

  3. 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.

  4. 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

Troubleshooting Guide

Issue 1: High False-Positive Block Rates for Valid User Queries

Issue 2: Indirect Injection Bypasses Ingress Filters

Issue 3: PII Redaction Corrupts Code Snippets

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.