Runtime Application Self-Protection for Java โ self-hosted, inspectable, and validated against real exploits.
OhMyRASP instruments the JVM from inside with ASM bytecode hooks, watches every
dangerous sink (Runtime.exec, JDBC, JNDI, deserialization, file I/O, โฆ), and
decides โ using request-parameter correlation and call-stack analysis layered
on top of signature detection โ whether the call is an attack. Detections can be
observed in monitor mode or stopped cold in block mode, switchable at runtime
without restarting the JVM.
Languages: English | ็ฎไฝไธญๆ
Most RASP products are black boxes. OhMyRASP is the opposite: every hook, every detection algorithm, and every test that proves it works is in this repository.
| Instrumented sink families | 27 ASM hook modules โ process exec, SQL, JNDI, deserialization (native, Hessian, XStream, Fastjson-style typed payloads, OpenWire), file I/O, SSRF, XXE, expression engines, JWT/session, archives, class loading, โฆ |
| Detection algorithms | 53 engine capabilities, 43 of them asserted by tests |
| End-to-end validation | 136 acceptance scenarios replayed against real Vulhub images; 130 Java/JVM CVEs tracked in the coverage ledger |
| Real CVEs blocked | Log4Shell (CVE-2021-44228), Spring4Shell (CVE-2022-22965), Fastjson autoType โ including the 1.2.83 getResourceAsStream resource-URL gadget, Shiro rememberMe (CVE-2016-4437), 19 Struts2 advisories (S2-001 โฆ S2-067), Tomcat Ghostcat (CVE-2020-1938), ActiveMQ OpenWire (CVE-2023-46604), WebLogic XMLDecoder, Spring Cloud Gateway SpEL (CVE-2022-22947), GeoServer (CVE-2024-36401), XStream gadgets, DataEase (2024โ2025), โฆ |
| Runtime coverage | Dedicated agent builds for Java 8, 11, 17, and 25; one binary covers both javax.servlet and jakarta.servlet (Tomcat 8.5 โ 11) |
| Measured precision | Public false-positive report generated against the live engine, regenerated by CI โ including the cases we still get wrong |
What makes the detection engine different from pattern matching:
- Request-taint correlation โ a SQL string or shell command only escalates to attack severity when it provably contains attacker-controlled request input, checked at the sink against the live request context.
- Call-stack analysis โ a
StackWalkertrace at the sink distinguishes how execution got there: the sameProcessBuilder.startis classified differently arriving via Struts2 OGNL, Spring SpEL, an XStream unmarshaller, or plain application code. - Six-form path decoding โ URI confusion attacks (double-encoding, overlong
UTF-8,
%uUnicode, ghost bits) are normalized into six decoded forms and compared, catching Shiro/Nexus/GlassFish/Jetty bypass tricks with one generic detector. - Cryptographic verification, not string matching โ default-secret JWTs are
actually HMAC-verified against known keys; Shiro
rememberMecookies are decrypted to confirm they contain a Java object stream. - Fastjson 1.2.83 class-resource boundary โ the agent hooks only the
ClassLoader.getResourceAsStream(resource)calls insideParserConfig.checkAutoType, after Fastjson has built the class resource but before the ClassLoader can perform I/O. It blockshttp(s)://,jar:http(s)://, and the PoC'sjar:file:/proc/self/fd/resources; normal classpath types and Spring Boot localjar:nested:resources remain quiet. - Response-side leak detection โ Luhn-validated card numbers, national ID and phone-number checks on the way out, not just attacks on the way in.
- Zero network on the hot path โ events go to a local NDJSON spool; a Rust daemon tails and forwards them. Off / monitor / block mode changes arrive via a polled control file, no JVM restart.
Read the full story in docs/detection.md.
Requires only Docker. This starts one Tomcat 11 with the agent in block mode plus the daemon's live console:
cd java-agent
docker compose -f docker-compose.daemon.yml up -d --build
# fire a SQL injection โ the agent blocks it mid-request
curl -L "http://localhost:18090/rasp/sqli?id=1+OR+1=1"
# โ redirected to /rasp/blocked
# watch live: attack log, per-hook latency, mode switching
open http://localhost:7070The demo app defaults to port
18090, which is also the control-plane API port โ setOHMYRASP_DEMO_PORTif you run both at once.
There is also a full comparative playground (baseline vs. protected Tomcat 9, 10, and 11 side by side) โ see docs/getting-started.md.
cp .env.example .env
# fill every empty password โ use URL-safe values:
openssl rand -hex 18
docker compose --env-file .env -f docker-compose.yml up -d --build| Service | URL |
|---|---|
| Web console | http://<host>:18091 |
| API | http://<host>:18090 |
| Grafana | http://<host>:13000 |
| Prometheus | http://<host>:19090 |
| Alertmanager | http://<host>:19093 |
| ClickHouse HTTP | http://<host>:18123 |
Log in to the console as admin@ohmyrasp.local with the password you set in
OHMYRASP_BOOTSTRAP_ADMIN_PASSWORD.
No local JDK needed:
cd java-agent
docker run --rm -v "$PWD":/workspace -w /workspace gradle:9.6.1-jdk25 \
gradle --no-daemon :agent-jdk25:agentJar
# โ agent-jdk25/build/libs/ohmyrasp-agent.jarFor older runtimes build :agent-java8:agentJava8Jar,
:agent-java11:agentJava11Jar, or :agent-java17:agentJava17Jar.
Standalone (no control plane required):
java -javaagent:/opt/ohmyrasp/ohmyrasp-agent.jar=mode=monitor \
-Dohmyrasp.log=/var/log/ohmyrasp/events.jsonl \
-jar your-app.jarConnected to the control plane (create the application in the console first to get its id and secret):
java -javaagent:/opt/ohmyrasp/ohmyrasp-agent.jar=backend_url=http://<host>:18090,app_id=<app-id>,app_secret=<secret>,environment_id=<env-id>,mode=block \
-jar your-app.jarAttacks then show up in the console under Threats, with severity, hook, algorithm, and request context. Full walkthrough: docs/getting-started.md.
โโโโโโโโโโโโโโโโโโโโโโโโ
โ Web Console โ
โ React 19 + Vite โ
โโโโโโโโโโโโฌโโโโโโโโโโโโ
โ
โโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโผโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโ
โ Host Daemon โโโโบโ Control API โโโโโ Prometheus rules โ
โ Rust โ โ Go + OpenAPI โ โ Alertmanager โ
โโโโโฒโโโโโโโโโโฌโโโโ โโโโโฌโโโโโโโฌโโโโโโโโฌโโโโ โ Grafana โ
โ spool โ control โ โ โ โโโโโโโโโโโโโโโโโโโโโโโ
โ (NDJSON)โ file โผ โผ โผ
โโโโโดโโโโโโโโโโผโโโโ PostgreSQL ClickHouse Valkey
โ Java Agent โ control telemetry cache
โ ASM sink hooks โ state
โโโโโโโโโโโโโโโโโโโ
- Java agent (
java-agent/) โ ASM bytecode hooks at 27 sink families, in-process detection, async NDJSON event spool, control-file mode switching. Builds for Java 8 / 11 / 17 / 25. - Host daemon (
daemon/) โ Rust; tails agent spools, forwards events to the control plane, serves a local live console, manages workload bind/unbind and agent injection. - Control API (
api/) โ Go; authentication, RBAC, application and agent inventory, policy lifecycle (draft โ active โ canary โ rollback), telemetry ingestion, artifact catalog, audit log. OpenAPI 3.1 contract. - Web console (
console/) โ React 19; overview dashboards, threat triage, application and fleet management, policy editing and testing, hook-latency observability, dependency (SCA) and posture views, RBAC and audit. English, ไธญๆ, and ๆฅๆฌ่ช. - Deploy (
deploy/) โ Helm chart, Prometheus rules, Alertmanager config, Grafana dashboards, smoke tests, runbooks.
More detail: docs/architecture.md.
OhMyRASP is under active development and should not yet be treated as a production security boundary. APIs, policy semantics, and packaging may change quickly. It is ready for experimentation, evaluation, and contribution โ and the test evidence above is real and reproducible.
Near-term focus:
- Tune the known JNDI false-positive gap (
java:comp/env/*allowlisting) โ see the false-positive report. - Keep growing the exploit corpus beyond the current 53 Vulhub component roots, and use LLM-assisted analysis of cyber-range attack paths to draft new detection rules for human review.
- Published release artifacts (pre-built agent jars and images).
api/ Go control-plane API, migrations, OpenAPI contract
console/ React 19 + Vite web console
java-agent/ Java agents (8/11/17/25), detection engine, Tomcat playgrounds
daemon/ Rust host daemon (spool forwarding, live console, injection)
deploy/ Helm chart, observability assets, smoke tests
docs/ User and operator docs; development ledgers; runbooks
.github/ CI and release workflows
# Go control plane
docker run --rm -v "$PWD/api":/src -w /src golang:1.26.5 go test ./...
# Console
cd console && npm ci && npm run build && npm test
# Java agent unit tests + full acceptance (6 Tomcats, ~136 scenarios)
cd java-agent && bash scripts/acceptance.sh
# Deployment validation
./deploy/scripts/smoke-control-plane.sh
./deploy/scripts/validate-helm-manifests.shSee CONTRIBUTING.md for the full developer guide, and SECURITY.md for how to report vulnerabilities โ detection bypasses are explicitly in scope and especially valued.
- Getting started โ install, run, protect an app
- Detection deep-dive โ how the engine works, with numbers
- Architecture โ control plane, daemon, data stores
- Java agent ยท Console ยท API reference
- Operations runbooks โ Helm, backup/restore, upgrades, observability, release
- Development ledgers โ per-algorithm coverage, Vulhub replay checklist
The agent is built on the ASM bytecode engineering library โ precise JVM instrumentation would not be practical without it.
OpenRASP defined many of the ideas and operational expectations around open runtime application self-protection and remains an important reference for the ecosystem. Vulhub makes reproducible exploit validation possible.
Apache License 2.0. See LICENSE.