Kuboid
Open Luck·Kuboid.in
Security BSides2025
Open in YouTube ↗

Follow the Trace: How Traditional AppSec Tools Have Failed Us

Security BSides San Francisco179 views30:425 months ago

This talk demonstrates the limitations of traditional static and dynamic application security testing (SAST/DAST) tools and advocates for the adoption of runtime application self-protection (RASP) and distributed tracing. The speaker illustrates how RASP can effectively detect and block server-side request forgery (SSRF) attacks by analyzing application behavior and data flow in real-time. The presentation highlights that runtime context is essential for reducing false positives and prioritizing critical vulnerabilities. A practical demonstration shows how RASP blocks an SSRF attack on a vulnerable Python Flask application.

Beyond the Perimeter: Why Your WAF is Blind to SSRF

TLDR: Traditional WAFs and perimeter defenses often fail to stop Server-Side Request Forgery (SSRF) because they lack visibility into the internal execution flow of an application. By adopting Runtime Application Self-Protection (RASP) and leveraging distributed tracing, security teams can gain the necessary context to identify and block malicious requests that bypass edge controls. This shift from perimeter-based security to runtime observability is critical for modern, service-oriented architectures.

Security researchers and penetration testers have spent years perfecting the art of bypassing Web Application Firewalls (WAFs). We know the drill. If a WAF blocks a specific payload, we encode it, fragment it, or find a different entry point. The fundamental problem with relying on a WAF is that it sits outside the application. It sees the traffic, but it does not see the intent or the internal state of the code. When an application is vulnerable to Server-Side Request Forgery (SSRF), the WAF is often looking for signatures of known attacks rather than understanding that the application is being coerced into making unauthorized requests to internal services.

The Blind Spot in Perimeter Defense

SSRF is a classic example of a vulnerability that thrives in the gap between network security and application logic. An attacker forces the server to make a request to an unintended location, such as an internal metadata service or a private database. Because the request originates from the server itself, it often bypasses network-level access controls.

In a typical Python Flask application, an SSRF vulnerability might exist where a user-supplied URL is passed directly to a library like urllib. If the application does not validate this input, an attacker can point the request to http://127.0.0.1:5000/flag or other sensitive internal endpoints. A WAF might block common patterns like file:///etc/passwd, but it will struggle to distinguish between a legitimate request to an external image host and a malicious request to an internal service if the attacker uses a valid, albeit unauthorized, URL.

Gaining Visibility with Runtime Context

Runtime Application Self-Protection (RASP) changes the game by embedding security directly into the application runtime. Unlike a WAF, which operates at the edge, a RASP agent monitors the application's internal behavior. It sees the function calls, the database queries, and the file system access in real-time.

When you instrument an application with a RASP agent, you gain the ability to intercept calls to sensitive functions. For an SSRF attack, the RASP agent can monitor the urllib or requests library calls. If the application attempts to make a request to an internal IP address or a restricted port, the RASP agent can block that specific execution path before the request is ever sent.

Consider the following Python snippet, which is a common pattern for an SSRF-vulnerable endpoint:

import urllib.request

def fetch_image(url):
    # Vulnerable: No validation of the URL
    with urllib.request.urlopen(url) as response:
        return response.read()

A RASP tool monitors this function call. When the attacker provides a malicious URL, the RASP agent inspects the destination. If the destination matches a blocklist or violates a policy, the agent throws an exception, effectively killing the request. This is far more precise than a WAF rule because it is based on the actual execution context of the application.

The Power of Distributed Tracing

Distributed tracing is often viewed as a performance monitoring tool, but for a security researcher, it is a goldmine. By following the trace of a single transaction as it moves through various services, you can identify exactly where a request originated and what components it touched.

When you combine distributed tracing with security instrumentation, you can visualize the entire attack surface. You can see the initial HTTP request, the subsequent internal service calls, and the final database interaction. If an SSRF attack occurs, the flame graph will show the request branching off into an unexpected service call. This visual representation makes it trivial to identify the root cause of the vulnerability. It allows you to see that a request to /test_picture_url triggered an internal call to /flag, which is a clear indicator of an SSRF attempt.

Prioritizing What Matters

One of the biggest frustrations for any security professional is the sheer volume of alerts. Most critical vulnerabilities identified by static analysis tools are never actually reachable in a production environment. RASP and runtime observability allow you to filter out the noise. If a vulnerability is identified in a piece of code that is never executed, or if the execution path is protected by runtime controls, you can deprioritize it.

Recent industry data suggests that only a small fraction of critical vulnerabilities are truly worth immediate prioritization. By using runtime context to adjust your risk assessment, you can focus your limited time on the vulnerabilities that are actually being exploited or that pose a genuine risk to your infrastructure.

Moving Forward

The future of application security lies in observability. We need to stop treating applications as black boxes and start instrumenting them to provide the data we need to defend them. If you are a pentester, start looking for ways to leverage the application's own runtime behavior during your engagements. If you are a developer, consider how you can build more observability into your services. The goal is not just to find bugs, but to understand how your application behaves under pressure. Stop relying on the perimeter and start looking at what is happening inside the code.

Premium Security Audit

We break your app before they do.

Professional penetration testing and vulnerability assessments by the Kuboid Secure Layer team. Securing your infrastructure at every layer.

Get in Touch
Official Security Partner
kuboid.in