Auto Virtual Patching

Sectora's killer feature: deploy a WAF rule that blocks the exact attack a finding describes, in under 30 seconds, while engineering ships the real fix.

The problem this solves

A scanner finds a SQLi at POST /api/v1/users/search. Cool. Now what?

Without virtual patching, your options are:

  • Wait for engineering to fix it. Best case: hours. Worst case: weeks for legacy code.
  • Take the endpoint offline. Breaks the product.
  • Hand-write a WAF rule in ModSecurity / Cloudflare Rules. Slow + error-prone + you might get the syntax wrong and block legitimate traffic.

Sectora's virtual patching is option 4: click a button on the finding, Shield deploys a rule that blocks the exact request shape that triggers the bug, globally in <30 seconds. Real fix ships later — when it's ready, you delete the patch.

How it works under the hood

When you click Virtual-patch on a finding, Sectora derives a request signature from the exploit:

Finding: SQLi at POST /api/v1/users/search, param "name"
Original exploit: name="' OR '1'='1"

Generated rule:
  - URL: /api/v1/users/search
  - Method: POST
  - When parameter "name" matches /['"]\s*(OR|UNION|;|--|\*)/i → BLOCK
  - When parameter "name" exceeds 200 bytes → BLOCK
  - When request has no Authorization header → CHALLENGE
  - Audit: log all blocked requests to /__shield/data/audit

The rule is conservative on purpose — better to allow some attacks through than to break a legit user with a SQL-looking name (the famous "O'Brien" problem). Sectora's rule generator is tuned to the matched payload class.

Per-finding patch deployment

  1. Open any DAST / SAST / API finding marked confirmed-exploitable.
  2. Click Virtual-patch. A preview shows the generated rule.
  3. (Optional) Refine — narrow the URL pattern, tighten the payload regex, change action (Block / Challenge / Log).
  4. Pick scope — "just this site" or "all my sites" (useful for shared-codebase vulns).
  5. Click Deploy. Rule lands globally in <30 seconds.

What happens at the edge

The deployed rule is stored in Cloudflare KV (per-customer namespace) and read by the Worker on every request. Decision flow:

  1. Worker resolves which customer this hostname belongs to (config lookup).
  2. Loads the customer's virtual-patch rules from KV (cached in-Worker for 60s).
  3. For each rule, evaluates URL match → method match → parameter regex.
  4. On match, takes the rule's action: 403 Block, Turnstile Challenge, or audit-only Log.
  5. Audit log entry written to __shield/data/audit — appears in Shield analytics.

Response-layer patches

Not every finding is fixed by blocking a request. Because Shield sits in the response path too, it virtual-patches a class of issues most WAFs only report on:

  • CORS misconfiguration (CWE-942) — an Access-Control-Allow-Origin: * (or null, or a reflected origin) combined with Access-Control-Allow-Credentials: true is neutralized at the edge. The credentials grant is stripped on the unambiguous wildcard / null cases; an optional origin allow-list reflects only your trusted origins and revokes the rest. Legitimate single-origin CORS is never touched.
  • Insecure cookiesSet-Cookie headers are rewritten to add Secure automatically (always correct on an HTTPS-only site). HttpOnly / SameSite are surfaced as one-click suggestions, since they can change app behavior.
  • Missing security headers — safe, non-app-specific headers (X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, …) are filled in when absent, never overriding ones your origin already sets.

These response patches are safe-by-design: each acts only on the unambiguous misconfiguration and is built to never break a working configuration.

Verified protection

A rule existing isn't proof it works. After a patch is armed, Sectora replays the exact request that triggered the finding back through the edge and checks whether it would be blocked in production. Only patches that come back verified-blockedare counted as "Protected" on the closed-loop dashboard; ones that merely match in monitor mode show as "Observing," and ones that don't match are flagged for review. The dashboard reports mean-time-to-mitigate from that verified data, not an estimate — and a patch retires itself once a re-scan confirms the underlying bug is fixed.

Suggestions mode (change control)

By default, high/critical findings auto-arm. For change-controlled or compliance environments, switch Auto-apply patches off on the site page to run in suggestions-only mode: patches are still generated from your findings, but stay disabled until a human reviews and approves each one. Combine with Monitormode to watch a patch's would-be blocks before it ever enforces.

Rule lifecycle

Every patch has metadata:

  • linked_finding_id — the finding that motivated the patch.
  • auto_remove — when set, the patch deletes itself once the linked finding's verify-fix returns "Fixed".
  • expires_at — optional hard expiry. Default 90 days. Patches approaching expiry trigger a Slack reminder.
  • block_count + last_block_at — analytics on actual hits.

Bulk patching

For zero-day vulnerabilities affecting your dependency graph (e.g. log4shell), select all findings of the same CVE and click Bulk virtual-patch. Generates one optimized rule covering all matched endpoints — typically a 5-minute job that would otherwise take hours to hand-code.

CI/CD integration

# Auto-deploy a virtual patch when a Critical finding lands on main
- name: Auto-patch on critical
  run: |
    CRITS=$(curl -sf -H "Authorization: Bearer $SECTORA_API_KEY" \
      "https://api.sectora.io/api/v1/vulnerabilities?severity=critical&status=open" \
      | jq -r '.data[] | select(.virtual_patched == false) | .id')

    for id in $CRITS; do
      curl -sf -X POST -H "Authorization: Bearer $SECTORA_API_KEY" \
        "https://api.sectora.io/api/v1/vulnerabilities/$id/virtual-patch?auto_remove=true"
    done

Limitations

  • Most virtual patches act at the request level. Response-layer patches cover specific response misconfigurations (CORS, cookie flags, missing security headers), but deeper logic bugs that leak data in the response body still need a real code fix.
  • Encrypted payloads (e.g. JWE bodies) can't be inspected — virtual patches on encrypted endpoints are limited to URL/method/header matching.
  • The patch is only effective if traffic actually goes through Shield. If an attacker reaches your origin directly (e.g. via the public IP), the patch is bypassed. Allow-list Cloudflare IPs only on your origin firewall.

What's next

  • Shield overview — the 9-layer architecture.
  • Managed Rulesets — pre-built rules complementing your virtual patches.
  • DAST — the most common source of virtual-patch-eligible findings.