VYPR
Moderate severityNVD Advisory· Published Aug 25, 2023· Updated Feb 13, 2025

Pyramid static view path traversal up one directory

CVE-2023-40587

Description

Pyramid 2.0.0/2.0.1 path traversal via null-byte truncation in Python 3.11's os.path.normpath allows disclosure of index.html one directory above static view path.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Pyramid 2.0.0/2.0.1 path traversal via null-byte truncation in Python 3.11's os.path.normpath allows disclosure of index.html one directory above static view path.

Vulnerability

Overview

CVE-2023-40587 is a path traversal vulnerability in the Pyramid web framework (versions 2.0.0 and 2.0.1) that specifically affects users running Python 3.11. The root cause lies in a behavioral change in Python 3.11's os.path.normpath function, which truncates paths at the first null byte (\x00). When Pyramid's static view processes a crafted path containing a null byte, the truncated path can traverse one directory upward, potentially exposing an index.html file located exactly one level above the static view's configured filesystem path [1][2].

Exploitation

Conditions

To exploit this vulnerability, an attacker must have access to a Pyramid static view configured with a full filesystem path (e.g., config.add_static_view(name='static', path='/usr/src/app/static')). The attacker sends a request with a path containing a null byte, such as ..\x00/, which after truncation resolves to the parent directory. The attack only works if an index.html file exists in that parent directory; no other files can be accessed [2]. No authentication is required if the static view is publicly accessible.

Impact

The impact is limited to the disclosure of a single index.html file located one directory above the static view's root. While this may seem minor, it could leak sensitive information if the file contains configuration details, API keys, or other secrets. The vulnerability does not allow arbitrary file traversal or remote code execution [1][2].

Mitigation and

Patches

Pyramid version 2.0.2 rejects any path containing a null byte as a precaution [4]. The underlying Python issue (CPython #106242) has been fixed in Python 3.11.5 and 3.12.0rc2, restoring the pre-3.11 behavior where null bytes are not truncated [3]. Users unable to upgrade immediately can downgrade to Python 3.10 or wait for the patched Python versions [2].

AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
pyramidPyPI
>= 2.0.0, < 2.0.22.0.2

Affected products

2

Patches

1
347d7750da6f

fix: reject NUL character as path element

https://github.com/Pylons/pyramidTres SeaverAug 21, 2023via ghsa
3 files changed · +19 5
  • src/pyramid/static.py+5 5 modified
    @@ -260,12 +260,12 @@ def _add_vary(response, option):
         response.vary = vary
     
     
    -_seps = {'/', os.sep}
    +_invalid_element_chars = {'/', os.sep, '\x00'}
     
     
    -def _contains_slash(item):
    -    for sep in _seps:
    -        if sep in item:
    +def _contains_invalid_element_char(item):
    +    for invalid_element_char in _invalid_element_chars:
    +        if invalid_element_char in item:
                 return True
     
     
    @@ -279,7 +279,7 @@ def _secure_path(path_tuple):
             # unless someone screws up the traversal_path code
             # (request.subpath is computed via traversal_path too)
             return None
    -    if any([_contains_slash(item) for item in path_tuple]):
    +    if any([_contains_invalid_element_char(item) for item in path_tuple]):
             return None
         encoded = '/'.join(path_tuple)  # will be unicode
         return encoded
    
  • tests/fixtures/index.html+1 0 added
    @@ -0,0 +1 @@
    +<h1>DON'T GO HERE</h1>
    
  • tests/test_static.py+13 0 modified
    @@ -104,6 +104,19 @@ def test_oob_os_sep(self):
     
             self.assertRaises(HTTPNotFound, inst, context, request)
     
    +    def test_oob_nul_char(self):
    +        import os
    +
    +        inst = self._makeOne(f'{os.getcwd()}/tests/fixtures/static')
    +        dds = '..\x00/'
    +        request = self._makeRequest(
    +            {'PATH_INFO': f'/{dds}'}
    +        )
    +        context = DummyContext()
    +        from pyramid.httpexceptions import HTTPNotFound
    +
    +        self.assertRaises(HTTPNotFound, inst, context, request)
    +
         def test_resource_doesnt_exist(self):
             inst = self._makeOne('tests:fixtures/static')
             request = self._makeRequest({'PATH_INFO': '/notthere'})
    

Vulnerability mechanics

Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

10

News mentions

0

No linked articles in our index yet.