clawd/memory/shannon-scan-2026-02-14/deliverables/ssrf_exploitation_evidence.md

13 KiB

SSRF Exploitation Evidence

Executive Summary

This report documents the comprehensive exploitation testing of one Server-Side Request Forgery (SSRF) vulnerability candidate identified during the analysis phase. After exhaustive testing and verification, the finding has been reclassified as a FALSE POSITIVE for SSRF vulnerability.

Key Finding: The OAuth Dynamic Client Registration vulnerability (SSRF-VULN-01) was initially classified as SSRF but is actually an Open Redirect vulnerability. The server does not make outbound HTTP requests to attacker-controlled destinations; instead, it redirects the client's browser using HTTP 303 status codes. This does not meet the definition of Server-Side Request Forgery.

Exploitation Status:

  • Successfully Exploited: 0
  • Potential Vulnerabilities: 0
  • False Positives: 1

Successfully Exploited Vulnerabilities

No SSRF vulnerabilities were successfully exploited.

Potential Vulnerabilities (Validation Blocked)

No potential SSRF vulnerabilities requiring further investigation.

False Positive Analysis

SSRF-VULN-01: OAuth Dynamic Client Registration - Open Redirect (NOT SSRF)

Summary:

  • Vulnerable location: POST /register (unauthenticated), GET /oauth/authorize (authenticated)
  • Initial Classification: Server-Side Request Forgery (SSRF) with internal service access capability
  • Corrected Classification: Open Redirect vulnerability
  • Reason for Reclassification: The server uses http.Redirect() which sends an HTTP 303 response to the client's browser, not a server-side HTTP request to the target URL
  • SSRF Criteria: FAILED - Server does not make outbound HTTP requests to attacker-controlled destinations

Detailed Analysis:

The vulnerability allows unauthenticated attackers to register OAuth clients with arbitrary redirect URIs, including internal network addresses. However, the exploitation mechanism does not match the definition of SSRF:

What Actually Happens:

  1. Attacker registers OAuth client with malicious redirect_uri (e.g., http://169.254.169.254/latest/meta-data/)
  2. Attacker (or victim) initiates OAuth authorization flow
  3. Server generates authorization code
  4. Server sends HTTP 303 redirect response to the CLIENT'S BROWSER
  5. Client's browser attempts to navigate to the internal URL (and fails from external network)

What Does NOT Happen (SSRF behavior):

  • Server does not make HTTP requests to the redirect_uri
  • Server does not establish connections to internal services
  • Server does not access internal network resources
  • Server does not leak internal service responses back to the attacker

Code Evidence:

File: /repos/inou-portal/portal/oauth.go:139

http.Redirect(w, r, redirectURL.String(), http.StatusSeeOther)

This function sends an HTTP 303 status code with a Location header - it does NOT make an outbound request. The Go documentation confirms:

"Redirect replies to the request with a redirect to url, which may be a path relative to the request path. The provided code should be in the 3xx range and is usually StatusMovedPermanently, StatusFound or StatusSeeOther."

Exploitation Attempts:

Attempt 1: Register OAuth Client with AWS Metadata Endpoint

Objective: Force server to access AWS EC2 instance metadata service

Method:

POST /register HTTP/1.1
Host: inou.com
Content-Type: application/json

{
  "client_name": "Security Research Client - AWS Metadata",
  "redirect_uris": [
    "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
  ]
}

Result:

HTTP/1.1 201 Created
Content-Type: application/json

{
  "client_id": "243f06b1598fb12d49c862ba047b9d1e",
  "client_secret": "b3cec86e5fdf34ddde72a35d945eddb57ec6a985d2dc808e55c42420032cee3f",
  "redirect_uris": [
    "http://169.254.169.254/latest/meta-data/iam/security-credentials/"
  ],
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "token_endpoint_auth_method": "client_secret_post"
}

Outcome: Client registration successful - No validation of redirect_uri against internal IP ranges


Attempt 2: Trigger OAuth Authorization Flow

Objective: Force server to make HTTP request to AWS metadata endpoint

Prerequisites:

  • Valid user session (obtained via passwordless authentication with backdoor code 250365)
  • Registered malicious OAuth client from Attempt 1

Method:

GET /oauth/authorize?client_id=243f06b1598fb12d49c862ba047b9d1e&redirect_uri=http%3A%2F%2F169.254.169.254%2Flatest%2Fmeta-data%2Fiam%2Fsecurity-credentials%2F&response_type=code&state=test HTTP/1.1
Host: inou.com
Cookie: login=6a484f3f85735a03

Server Response:

HTTP/1.1 303 See Other
Location: http://169.254.169.254/latest/meta-data/iam/security-credentials/?code=4f4f3e67fcf804ce05487c18fdaee6f5b354ecb467f834d9747285369a4b31d7&state=test
Content-Type: text/html; charset=utf-8
Content-Length: 177

Analysis:

  • Server returned HTTP 303 redirect (client-side redirect)
  • Server did NOT make an HTTP request to 169.254.169.254
  • Server did NOT receive or return data from the metadata service
  • Browser attempted to navigate to the internal URL (network error from client side)

Outcome: NOT SSRF - This is an Open Redirect vulnerability, not server-side request forgery


Attempt 3: Register Additional Clients for Internal Services

Objective: Test if different internal targets yield server-side requests

Targets Tested:

  1. Internal API Server: http://127.0.0.1:8082/api/access

    • Client ID: 9863b518919c5c11532b2775e81a0b82
    • Registration: Successful
  2. Signal RPC Service: http://192.168.1.16:8080/api/v1/rpc

    • Client ID: 96478c7a51bc4447f2a54cf6c30ae970
    • Registration: Successful
  3. DICOM Viewer: http://localhost:8765/viewer

    • Client ID: afb78106315871695217d878f6c8b6b9
    • Registration: Successful

Result: All clients successfully registered with internal network targets, confirming complete lack of redirect URI validation. However, all subsequent authorization flows resulted in the same behavior: HTTP 303 client-side redirects, not server-side HTTP requests.

Outcome: NOT SSRF - Consistent client-side redirect behavior across all internal targets


Attempt 4: Search for Alternative SSRF Sinks

Objective: Identify any code paths where the server actually makes outbound HTTP requests with user-controlled URLs

Code Review Findings:

  1. Google Gemini API Integration (/repos/inou-portal/lib/llm.go:109)

    • URL construction: fmt.Sprintf("https://generativelanguage.googleapis.com/v1beta/models/%s:generateContent?key=%s", *config.Model, GeminiKey)
    • User control: NONE - Model parameter never populated from user input
    • Verdict: Not exploitable
  2. Signal Messaging RPC (/repos/inou-portal/lib/signal.go:10)

    • Endpoint: const signalAPI = "http://192.168.1.16:8080/api/v1/rpc"
    • User control: NONE - Hardcoded destination
    • Verdict: Not exploitable
  3. Internal API Proxy (/repos/inou-portal/portal/api_proxy.go:22)

    • Endpoint: const apiBackend = "http://127.0.0.1:8082"
    • User control: NONE - Hardcoded destination
    • Verdict: Not exploitable
  4. SMTP Email Delivery (/repos/inou-portal/lib/email.go)

    • Configuration: Loaded from environment file
    • User control: NONE - Administrative configuration only
    • Verdict: Not exploitable

Outcome: No true SSRF sinks identified - All outbound HTTP requests use hardcoded or configuration-based destinations


SSRF vs Open Redirect - Technical Distinction:

Characteristic SSRF Open Redirect (This Vulnerability)
Server Behavior Server makes HTTP request to attacker-controlled URL Server sends HTTP 3xx redirect to client
Request Origin Server's network context Client's network context
Access to Internal Services Yes - server can reach internal networks No - client cannot reach internal networks from external position
Data Exfiltration Yes - server returns internal service responses No - server never sees internal service data
Network Boundary Bypass Yes - server is inside the network No - redirect fails from external client
HTTP Status Codes 200 OK (or error from internal service) 303 See Other (redirect to client)

Why This Matters for Classification:

The analysis phase correctly identified that the application allows arbitrary redirect URIs to be registered without validation. However, the exploitation mechanism does not meet the SSRF threat model:

  • SSRF Definition: Server-Side Request Forgery occurs when an attacker can cause the server to make HTTP requests to arbitrary destinations, leveraging the server's network position and credentials.

  • This Vulnerability: The server generates a redirect response (HTTP 303) that instructs the client's browser to navigate to an arbitrary URL. The server itself never makes the request.

Attempted Bypass Techniques:

To ensure thorough testing, the following bypass attempts were made to see if the redirect could be leveraged into true SSRF:

  1. Multiple Protocol Tests: Tried file://, gopher://, ftp:// - All accepted in registration but still result in client-side redirects
  2. Redirect Chaining: Attempted to chain redirects to see if server would follow - No server-side request initiated
  3. DNS Rebinding Simulation: Cannot be tested externally, but would not matter since redirect is client-side
  4. SSRF via Request Smuggling: OAuth flow doesn't involve request parsing that could be smuggled

Actual Security Impact:

While not SSRF, this vulnerability still has security implications:

  1. Open Redirect Risk: Attackers can redirect users to phishing sites via trusted inou.com domain
  2. OAuth Code Leakage: If an attacker can register a client with their own domain, they receive the authorization code when users authorize
  3. Network Topology Disclosure: Error messages and timing differences may reveal which internal IPs/ports exist
  4. Authorization Code in URL: Codes appear in URL parameters of the redirect, violating OAuth security best practices (should use POST-based flows for sensitive redirects)

Recommended Fix:

While this is not SSRF, the underlying vulnerability (unrestricted redirect URIs) should still be fixed:

// In /repos/inou-portal/portal/mcp_http.go, before line 131:
func validateRedirectURI(uri string) error {
    parsed, err := url.ParseRequestURI(uri)
    if err != nil {
        return fmt.Errorf("invalid URI format: %w", err)
    }

    // Require HTTPS for all redirect URIs
    if parsed.Scheme != "https" {
        return fmt.Errorf("only HTTPS redirect URIs allowed")
    }

    // Block private IP ranges
    if ip := net.ParseIP(parsed.Hostname()); ip != nil {
        if ip.IsPrivate() || ip.IsLoopback() || ip.IsLinkLocalUnicast() {
            return fmt.Errorf("private/internal IP addresses not allowed")
        }
    }

    // Domain allowlist for production
    allowedDomains := []string{"claude.ai", "anthropic.com"}
    hostname := strings.ToLower(parsed.Hostname())
    allowed := false
    for _, domain := range allowedDomains {
        if hostname == domain || strings.HasSuffix(hostname, "."+domain) {
            allowed = true
            break
        }
    }
    if !allowed {
        return fmt.Errorf("redirect domain not in allowlist")
    }

    return nil
}

Conclusion:

After exhaustive exploitation attempts across multiple attack vectors and internal targets, I have determined with high confidence that SSRF-VULN-01 is a FALSE POSITIVE for SSRF classification. The vulnerability is correctly identified as a lack of redirect URI validation, but the exploitation mechanism (HTTP 303 client-side redirect) does not allow server-side network boundary bypass or internal service access.

The vulnerability should be reclassified as:

  • Type: Open Redirect + OAuth Security Misconfiguration
  • Severity: Medium (was incorrectly rated High for SSRF impact)
  • Exploitability: High (unauthenticated registration, no validation)
  • Impact: Phishing, OAuth code theft, but NOT internal network access

Exploitation Classification Decision Framework Applied:

"Is this preventing factor a security implementation designed to stop this attack, or an external operational constraint?"

Answer: Neither. The "prevention" is the fundamental design of HTTP redirects - they are client-side by definition in the HTTP specification (RFC 7231). This is not a security control that could be bypassed; it's the architectural reality of how http.Redirect() functions.

The correct classification is: FALSE POSITIVE - The vulnerability does not enable Server-Side Request Forgery.