application security

Implementing Runtime Application Self-Protection

Deploy Runtime Application Self-Protection (RASP) agents to detect and block attacks from within application runtime, covering OpenRASP integration, attack pattern detection, and security policy configuration for Java and Python web applications.

application-securitydevsecopsopenrasprasprceruntime-protectionsqlixss
Install this skill
npx skills add mukul975/Anthropic-Cybersecurity-Skills
Framework mappings

Overview

Runtime Application Self-Protection (RASP) instruments application code at runtime to detect and block attacks by examining actual execution context rather than relying solely on network traffic patterns. Unlike WAFs that inspect HTTP requests externally, RASP agents intercept dangerous operations (SQL queries, file operations, command execution, deserialization) at the function level inside the application, achieving near-zero false positives. This skill covers deploying OpenRASP for Java applications, configuring detection policies for OWASP Top 10 attacks, tuning alerting thresholds, and integrating RASP telemetry with SIEM platforms.

When to Use

  • When deploying or configuring implementing runtime application self protection capabilities in your environment
  • When establishing security controls aligned to compliance requirements
  • When building or improving security architecture for this domain
  • When conducting security assessments that require this implementation

Prerequisites

  • Java 8+ application server (Tomcat, Spring Boot, or JBoss) or Python Flask/Django application
  • OpenRASP agent package (rasp-java or equivalent)
  • OpenRASP management console for centralized policy management
  • SIEM integration endpoint (Splunk HEC, Elasticsearch, or syslog)
  • Application staging environment for RASP testing before production

Steps

Step 1: Deploy RASP Agent

Install the RASP agent into the application server runtime using JVM agent attachment for Java or middleware hooks for Python.

Step 2: Configure Detection Policies

Define detection rules for SQL injection, command injection, SSRF, path traversal, XXE, and deserialization attacks with block or monitor actions.

Step 3: Tune and Baseline

Run the agent in monitor mode during normal operations to establish baseline behavior and tune policies to reduce false positives before switching to block mode.

Step 4: Integrate with SIEM

Forward RASP alerts to the SIEM for correlation with WAF, IDS, and authentication events to build comprehensive attack timelines.

Expected Output

JSON report containing RASP policy audit results, detected attack attempts with stack traces, blocked requests summary, and coverage assessment against OWASP Top 10.

Source materials

References and resources

Everything below is rendered for inspection. Script files are read-only and never run.

References 1

api-reference.md2.6 KB

API Reference: Implementing Runtime Application Self-Protection

OpenRASP Deployment

# Java agent attachment (Tomcat)
export CATALINA_OPTS="-javaagent:/opt/rasp/rasp.jar"
 
# Spring Boot
java -javaagent:/opt/rasp/rasp.jar -jar app.jar
 
# Verify agent loaded
curl -s http://localhost:8080/rasp/status

OpenRASP Configuration (rasp.yaml)

# Detection plugin settings
plugin:
  timeout: 100        # Plugin execution timeout (ms)
  maxstack: 100       # Max stack frames to capture
 
# Block vs monitor mode
block:
  status_code: 302    # HTTP status on block
  redirect_url: /blocked.html
 
# Log settings
log:
  maxstack: 50
  syslog:
    enable: true
    url: "udp://siem.example.com:514"
    tag: openrasp

Detection Hooks

Hook Point Attack Type OWASP
sql_query SQL Injection A03:2021
command_exec OS Command Injection A03:2021
file_open / file_read Path Traversal A01:2021
http_request SSRF A10:2021
xml_parse XXE A05:2021
deserialize Insecure Deserialization A08:2021
response_write XSS (reflected) A03:2021
ldap_query LDAP Injection A03:2021
code_eval Remote Code Execution A03:2021

Attack Log Format (JSON)

{
  "attack_type": "sqli",
  "action": "block",
  "client_ip": "192.168.1.50",
  "request_url": "/api/users?id=1 OR 1=1",
  "attack_params": {"id": "1 OR 1=1"},
  "stack_trace": "com.app.UserDAO.findById(UserDAO.java:42)",
  "plugin_name": "sql_injection",
  "timestamp": "2025-06-15T10:30:00Z"
}

RASP vs WAF Comparison

Feature WAF RASP
Inspection point Network perimeter Inside application
Context HTTP request only Request + execution context
False positive rate Higher Near-zero
Encrypted traffic Requires TLS termination Sees plaintext
Deployment Network device/proxy Application library

Python RASP (Flask Middleware Example)

from flask import request, abort
import re
 
SQL_INJECTION_PATTERN = re.compile(
    r"(\b(union|select|insert|update|delete|drop|alter)\b.*\b(from|into|table|set)\b)",
    re.IGNORECASE
)
 
@app.before_request
def rasp_check():
    for value in request.values.values():
        if SQL_INJECTION_PATTERN.search(str(value)):
            abort(403, description="RASP: SQL injection blocked")

References

Scripts 1

agent.py6.7 KB
Display-only source. This catalog never executes bundled scripts.
#!/usr/bin/env python3
"""RASP Agent - audits runtime application protection config, attack logs, and coverage."""

import json
import argparse
import logging
from collections import defaultdict
from datetime import datetime

logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger(__name__)

OWASP_TOP10_CHECKS = {
    "sqli": {"name": "SQL Injection", "owasp": "A03:2021", "hook": "sql_query"},
    "cmdi": {"name": "Command Injection", "owasp": "A03:2021", "hook": "command_exec"},
    "ssrf": {"name": "Server-Side Request Forgery", "owasp": "A10:2021", "hook": "http_request"},
    "path_traversal": {"name": "Path Traversal", "owasp": "A01:2021", "hook": "file_open"},
    "xxe": {"name": "XML External Entity", "owasp": "A05:2021", "hook": "xml_parse"},
    "deserialization": {"name": "Insecure Deserialization", "owasp": "A08:2021", "hook": "deserialize"},
    "xss": {"name": "Cross-Site Scripting", "owasp": "A03:2021", "hook": "response_write"},
    "ldap_injection": {"name": "LDAP Injection", "owasp": "A03:2021", "hook": "ldap_query"},
    "rce": {"name": "Remote Code Execution", "owasp": "A03:2021", "hook": "code_eval"},
}


def parse_rasp_config(config_file):
    """Parse OpenRASP or RASP agent configuration."""
    with open(config_file) as f:
        return json.load(f)


def audit_rasp_policy(config):
    """Audit RASP detection policies against OWASP Top 10 coverage."""
    findings = []
    enabled_checks = config.get("detection_plugins", {})
    for check_id, check_info in OWASP_TOP10_CHECKS.items():
        plugin = enabled_checks.get(check_id, {})
        if not plugin.get("enabled", False):
            findings.append({
                "check": check_id, "name": check_info["name"],
                "owasp": check_info["owasp"], "status": "disabled",
                "severity": "high",
                "recommendation": f"Enable {check_info['name']} detection plugin",
            })
        elif plugin.get("action", "log") != "block":
            findings.append({
                "check": check_id, "name": check_info["name"],
                "owasp": check_info["owasp"], "status": "monitor_only",
                "severity": "medium",
                "recommendation": f"Switch {check_info['name']} from monitor to block mode",
            })
    block_mode = config.get("global_action", "log")
    if block_mode == "log":
        findings.append({
            "check": "global_mode", "status": "monitor_only",
            "severity": "high",
            "recommendation": "Switch RASP from monitor to block mode after baseline period",
        })
    return findings


def analyze_attack_logs(log_file, limit=10000):
    """Analyze RASP attack detection logs."""
    attacks = []
    by_type = defaultdict(int)
    by_source = defaultdict(int)
    blocked = 0
    try:
        with open(log_file) as f:
            for i, line in enumerate(f):
                if i >= limit:
                    break
                try:
                    event = json.loads(line)
                    attack_type = event.get("attack_type", "unknown")
                    by_type[attack_type] += 1
                    by_source[event.get("client_ip", "")] += 1
                    if event.get("action") == "block":
                        blocked += 1
                    attacks.append(event)
                except json.JSONDecodeError:
                    continue
    except FileNotFoundError:
        logger.warning("RASP log file not found: %s", log_file)
    return {
        "total_attacks": len(attacks),
        "blocked": blocked,
        "block_rate": round(blocked / max(len(attacks), 1) * 100, 1),
        "by_attack_type": dict(sorted(by_type.items(), key=lambda x: x[1], reverse=True)),
        "top_sources": dict(sorted(by_source.items(), key=lambda x: x[1], reverse=True)[:10]),
    }


def check_agent_health(config):
    """Verify RASP agent deployment health."""
    findings = []
    if not config.get("agent_version"):
        findings.append({"issue": "Agent version unknown", "severity": "medium"})
    if config.get("cpu_limit_percent", 100) > 10:
        findings.append({
            "issue": f"CPU limit set to {config.get('cpu_limit_percent')}% (recommend < 5%)",
            "severity": "low",
        })
    if not config.get("siem_integration", {}).get("enabled"):
        findings.append({
            "issue": "SIEM log forwarding not configured",
            "severity": "high",
            "recommendation": "Enable syslog or webhook forwarding to SIEM",
        })
    return findings


def calculate_coverage(config):
    """Calculate OWASP Top 10 coverage percentage."""
    enabled_checks = config.get("detection_plugins", {})
    covered = sum(1 for check_id in OWASP_TOP10_CHECKS if enabled_checks.get(check_id, {}).get("enabled"))
    return {
        "total_checks": len(OWASP_TOP10_CHECKS),
        "enabled": covered,
        "coverage_percent": round(covered / len(OWASP_TOP10_CHECKS) * 100, 1),
    }


def generate_report(policy_findings, attack_analysis, health_findings, coverage, config):
    all_findings = policy_findings + health_findings
    return {
        "timestamp": datetime.utcnow().isoformat(),
        "rasp_agent": config.get("agent_type", "openrasp"),
        "agent_version": config.get("agent_version", "unknown"),
        "global_mode": config.get("global_action", "log"),
        "owasp_coverage": coverage,
        "policy_findings": policy_findings,
        "attack_analysis": attack_analysis,
        "health_findings": health_findings,
        "total_findings": len(all_findings),
        "critical_findings": sum(1 for f in all_findings if f.get("severity") == "critical"),
    }


def main():
    parser = argparse.ArgumentParser(description="RASP Security Audit Agent")
    parser.add_argument("--config", required=True, help="RASP agent config JSON file")
    parser.add_argument("--attack-log", help="RASP attack log file (JSON lines)")
    parser.add_argument("--output", default="rasp_audit_report.json")
    args = parser.parse_args()

    config = parse_rasp_config(args.config)
    policy_findings = audit_rasp_policy(config)
    attack_analysis = analyze_attack_logs(args.attack_log) if args.attack_log else {}
    health_findings = check_agent_health(config)
    coverage = calculate_coverage(config)
    report = generate_report(policy_findings, attack_analysis, health_findings, coverage, config)
    with open(args.output, "w") as f:
        json.dump(report, f, indent=2, default=str)
    logger.info("RASP audit: %.1f%% OWASP coverage, %d findings, mode: %s",
                coverage["coverage_percent"], report["total_findings"], config.get("global_action", "log"))
    print(json.dumps(report, indent=2, default=str))


if __name__ == "__main__":
    main()
Keep exploring