VAITP Dataset

← Back to the dataset

CVE-2026-42351

pygeoapi STAC path traversal allows unauthenticated directory exposure.

  • CVSS 7.5
  • CWE-22
  • Input Validation and Sanitization
  • Remote

pygeoapi is a Python server implementation of the OGC API suite of standards. From version 0.23.0 to before version 0.23.3, a raw string path concatenation vulnerability in pygeoapi's STAC FileSystemProvider plugin can allow for requests to STAC collection based collections to expose directories without authentication. The issue manifests when pygeoapi is deployed without a proxy or web front end that would normalize URLs with .. values, along with a resource of type stac-collection defined in configuration. This issue has been patched in version 0.23.3.

CVSS base score
7.5
Published
2026-05-08
OWASP
A01 Broken Access Control
Orthogonal defect classification
Checking
Code defect classification
Missing Check
Category
Input Validation and Sanitization
Subcategory
Path Traversal
Accessibility scope
Remote
Impact
Information Disclosure
Affected component
pygeoapi
Fixed by upgrading
Yes

Solution

Upgrade pygeoapi to version 0.23.3 or later.

Vulnerable code sample

import os

def get_stac_collection_path(child_path, identifier):
    """
    Simplified representation of the vulnerable logic in the
    pygeoapi.provider.stac.STACProvider.get method before v0.23.3.

    This function insecurely joins a base path with a user-provided
    identifier, allowing for path traversal.
    """

    # The vulnerability: `os.path.join` is used with a raw `identifier`
    # from user input. If `identifier` is '../..', the resulting path
    # will point outside of the intended `child_path`.
    path = os.path.join(child_path, identifier)

    # In the real application, the code would proceed to check if `path`
    # is a directory and then list its contents, exposing them.
    # For this example, we just return the constructed path.
    return path

Patched code sample

import os
import logging

# This code is a self-contained representation of the logic used
# in the pygeoapi patch. In the actual patch, these components are
# integrated into the existing codebase structure.

LOGGER = logging.getLogger(__name__)

class ProviderConnectionError(Exception):
    """Provider connection error"""
    pass


def get_path_from_provider(data_path: str, safe_path: str) -> str:
    """
    Safely join a path to a provider's data path, preventing path traversal.

    This function resolves the absolute path of the combined path and ensures
    it is located within the intended 'data_path' directory.

    :param data_path: The provider's base data directory.
    :param safe_path: The user-provided path component to be joined.

    :raises ProviderConnectionError: If the resulting path is outside the
                                     base 'data_path' directory (path
                                     traversal detected).

    :returns: The safely resolved, absolute path.
    """

    LOGGER.debug(f'Safely joining {safe_path} to {data_path}')

    # Vulnerable approach (for comparison, not used in fix):
    # vulnerable_path = os.path.join(data_path, safe_path)
    # If safe_path is '../secrets', vulnerable_path could resolve
    # outside data_path.

    # Fixed approach:
    # 1. Join the paths.
    # 2. Get the real, absolute path, resolving any '..' components.
    resolved_path = os.path.abspath(os.path.join(data_path, safe_path))
    
    # 3. Ensure the base data_path is a common prefix of the resolved path.
    #    This confirms the resolved path is still inside the base directory.
    if os.path.commonprefix((resolved_path, data_path)) != data_path:
        msg = 'unsafe path detected'
        LOGGER.error(msg)
        raise ProviderConnectionError(msg)

    return resolved_path

Payload

/collections/my-stac-collection/items/../../../../../../etc/passwd

Cite this entry

@misc{vaitp:cve202642351,
  title        = {{pygeoapi STAC path traversal allows unauthenticated directory exposure.}},
  author       = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
  year         = {2026},
  note         = {VAITP Python Vulnerability Dataset, entry CVE-2026-42351},
  howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-42351/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.

The supreme art of war is to subdue the enemy without fighting.

Sun Tzu – “The Art of War”

:: Shaping the future through research and ingenuity ::