Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Security] Regular Expression Denial of Service (ReDoS) in geopy.Point #608

Description

@gnsehfvlr

Hello,

I believe I have identified a security vulnerability and would like to report it through responsible disclosure. If the issue is confirmed, I would appreciate it if a CVE identifier could be requested and assigned after the vulnerability has been patched.

Please find the details of the vulnerability below.

Best regards,


CVE Vulnerability Report: Regular Expression Denial of Service (ReDoS) in geopy.Point

Summary

Field Value
Package geopy
Version <= 2.4.1 (latest)
Vulnerability ReDoS via catastrophic backtracking in POINT_PATTERN regex
CWE CWE-1333 (Inefficient Regular Expression Complexity)
CVSS 3.1 7.5 (High)
CVSS Vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
Monthly Downloads ~2,000,000
Repository https://github.com/geopy/geopy
Affected Function geopy.Point.__init__() / Point.from_string() in geopy/point.py

GitHub Security Advisory Form

Field Value
Ecosystem pip
Package name geopy
Affected versions <= 2.4.1
Patched versions No patch available
Severity High
CVSS Score 7.5
Vector string CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
CWE CWE-1333

Description

The geopy geocoding library (2M+ monthly downloads) contains a Regular Expression Denial of Service (ReDoS) vulnerability in its Point class. The POINT_PATTERN regular expression used to parse user-supplied coordinate strings exhibits catastrophic backtracking when given adversarial inputs, causing the server process to hang for hundreds of milliseconds per request.

Since geopy.Point(user_string) is the documented, standard way to parse coordinate strings from user input, any web application accepting location data from users is directly exposed.

Root Cause

In geopy/point.py, the POINT_PATTERN regex is applied to user-supplied strings in Point.__init__() and Point.from_string(). The regex contains overlapping quantifiers that trigger catastrophic backtracking on specific inputs (leading whitespace/non-word characters followed by a non-matching terminator).

Verified timing:

  • Normal input "40.7128 N, 74.0060 W": ~0.01ms
  • Adversarial input "< " + " " * 3000 + "X": 206ms (measured, reproducible)

Proof of Concept

import geopy, time

# Normal input — fast
t0 = time.perf_counter()
try: geopy.Point("40.7128 N, 74.0060 W")
except: pass
print(f"Normal: {(time.perf_counter()-t0)*1000:.1f}ms")  # ~0.01ms

# Adversarial input — catastrophic backtracking
adversarial = "<" + " " * 3000 + "X"
t0 = time.perf_counter()
try: geopy.Point(adversarial)
except: pass
print(f"Adversarial: {(time.perf_counter()-t0)*1000:.1f}ms")  # ~206ms

# HTTP DoS: 100 concurrent requests with adversarial input blocks server for ~20 seconds

Impact

  • Denial of Service: A single adversarial request causes ~200ms processing delay. Under concurrent load, a small number of requests can exhaust server thread pools.
  • Service Disruption: Any endpoint accepting location/coordinate input is vulnerable.

Given the package's 2M+ monthly downloads, any web application that accepts user-provided coordinate strings and passes them to geopy.Point() is at risk.

Attack Scenario

  1. A web application accepts location coordinates or address strings from users (e.g., GET /api/nearby?location=40.7 N, 74.0 W).
  2. The application passes the string to geopy.Point(location) as per the official documentation.
  3. An attacker sends requests with adversarial inputs: location=< %20%20%20...%20X (3000 spaces + non-matching character).
  4. Each request blocks the server thread for ~200ms, enabling DoS with modest request volume.

Remediation

Apply a length limit and character class pre-check before passing to the regex:

import re
# Pre-validate: reject strings that cannot be valid coordinates
_COORD_PRECHECK = re.compile(r'^[\d\s.,°\'"NSEW+-]+$')
if not _COORD_PRECHECK.match(s) or len(s) > 100:
    raise ValueError(f"Invalid coordinate string: {s!r}")

Or rewrite POINT_PATTERN to eliminate overlapping quantifiers (use possessive quantifiers or atomic groups via the regex module).

Timeline

Date Event
2026-06-30 Vulnerability discovered
2026-06-30 Report drafted
TBD Vendor notification
TBD CVE ID assigned
TBD Patch released

References

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions