Most application attacks are not clever. They are ordinary requests your app was never meant to receive: a DELETE on an object the caller doesn't own, an unauthenticated hit on an admin route, a request shape that only appears when someone is probing. A signature WAF looks for known-bad patterns. It has no idea what your app's normal looks like, so it misses the abuse that is specific to your code — and it flags a lot of legitimate traffic that merely looks unusual.
Nemesis Application Shield inverts the model. Instead of a list of attacks to block, it learns a per-tenant baseline of how your application actually behaves, then enforces it: this app only ever serves these request shapes; block the rest. That is a positive-security (allow-list) model, and it catches zero-days and business-logic abuse a signature never will, because the exploit request simply isn't in the baseline.
Why this works on legacy code too
You don't have to patch anything. An old Django app, a Laravel monolith, a Spring service behind on updates — the SDK sits in front of the routes and learns what they normally do. When the React2Shell-class exploit request arrives (an unauthenticated POST with a strange body to an endpoint), it doesn't match any learned shape, so it's blocked — even though the underlying framework is still vulnerable. Protection at the app layer, because an attack is not the app's default behavior.
Get started in two minutes
The flow is the same in every language: add one line, let it learn, approve, enforce. Nothing about your routes changes.
flowchart LR A["① Add one line<br/>drop-in SDK middleware"] --> B["② Observe<br/>learns your app's<br/>normal request shapes"] B --> C["③ Approve<br/>review the baseline<br/>in the console"] C --> D["④ Enforce<br/>off-baseline requests<br/>blocked in-process"] D -. no redeploy .-> C
A. Install the SDK and paste your app token. The SDK computes a privacy-preserving shape of each request locally — method, normalized route, whether the caller was authenticated — and never ships your bodies, secrets, or source.
# Python (FastAPI / Flask / Django) · Node · Go · Ruby · PHP · Java · .NET · Rust
pip install nemesis-shield# FastAPI — one line
from nemesis_shield.asgi import SentinelMiddleware
app.add_middleware(SentinelMiddleware, token="nsk_your_app_token")// Node / Express — one line
import { sentinel } from "@nemesis-shield/sentinel/express";
app.use(sentinel({ token: process.env.NEMESIS_TOKEN }));B. Let it observe. Ship it. For a day or two the SDK watches real traffic and builds the baseline. It never blocks in observe mode, so there is zero risk to production.
C. Approve the baseline. In the console you see every learned behavior — GET /orders/{int} (auth required), POST /checkout, and so on. Approve the legitimate ones (most auto-approve during the learning window); flag anything that looks wrong.
D. Flip to enforce. From that point, any request whose shape isn't in the approved baseline is blocked in-process, in real time, and reported as a finding. The console flips observe ↔ enforce with no redeploy — the SDK picks up the change on its next poll.
What it blocks that a WAF doesn't
- Broken object-level authorization (BOLA/IDOR) — an authenticated user reaching another tenant's object, when your baseline only ever saw first-party access.
- Auth bypass — an unauthenticated request to a route that is always authenticated.
- Unusual verbs — a
DELETEorPUTon a route your app only everGETs. - Scanner and recon traffic —
/.env,/wp-login.php,/phpmyadmin, path traversal — none of it is in your baseline. - N-day and zero-day exploit requests — the exploit is a request shape your app never legitimately serves.
For developers
One line, zero route changes, fail-open (if Nemesis is unreachable your app is unaffected), and the same model across Python, Node, Go, Ruby, PHP, Java, .NET, and Rust — including the frameworks banks and older shops actually run. You approve or block behaviors from the console; the SDK enforces without a redeploy.
For the business
It closes the gap between "we have a WAF" and "we're actually protected against the attacks that target our app." It protects legacy and unpatched systems at the app layer, it produces proof (a blocked finding, not just an alert), and it starts free — one app, learn-and-alert — so a developer can prove the value before anyone signs anything.
Two minutes to protect an app. A day to trust the baseline. Then it's enforcing, quietly, on every request.