Skip to main content
Vulnerability Database/CVE-2026-77401

CVE-2026-77401: Zope AccessControl Information Disclosure

CVE-2026-77401 is an information disclosure flaw in Zope AccessControl that allows untrusted users to bypass security restrictions through Python string formatting methods, potentially exposing sensitive objects and data. This article covers technical details, affected versions, impact assessment, and mitigation strategies.

Published:

CVE-2026-77401 Overview

CVE-2026-77401 affects Zope AccessControl, the security framework that enforces policy-restricted attribute access in Zope applications. Versions prior to 7.4 fail to guard str.format and str.format_map when those methods are reached through a str subclass. Applications that allow untrusted users to create and execute AccessControl-controlled Python code are exposed. A controlled format string can traverse attributes and subscriptions using unrestricted getattr and getitem operations instead of the policy-restricted variants. The flaw is categorized under [CWE-693] Protection Mechanism Failure and is fixed in version 7.4.

Critical Impact

Attackers with the ability to submit format strings can disclose sensitive objects reachable from values passed to the formatting operation, bypassing AccessControl's security policy.

Affected Products

  • Zope AccessControl versions prior to 7.4
  • Zope applications permitting untrusted users to author AccessControl-controlled Python code
  • Downstream frameworks embedding vulnerable AccessControl builds

Discovery Timeline

  • 2026-09-16 - CVE-2026-77401 published to the National Vulnerability Database
  • 2026-09-16 - Last updated in NVD database

Technical Details for CVE-2026-77401

Vulnerability Analysis

Zope AccessControl enforces a security policy by mediating attribute and item access through guarded_getattr and guarded_getitem. These functions apply role and permission checks before returning objects. The vulnerability arises because Python's str.format and str.format_map internally traverse attributes ({obj.attr}) and items ({obj[key]}) using the standard, unrestricted CPython descriptors. When a format method is reached via a str subclass, AccessControl's checks in ImplPython.py and cAccessControl.c do not intercept those traversals. An attacker who can supply a format string reaches any object graph rooted in the format arguments, disclosing values that the security policy would otherwise block.

Root Cause

The policy layer treated format and format_map as ordinary string methods rather than as recursive accessors. On a str subclass, name resolution bypassed the guarded branch entirely, leaving format-time attribute and subscription lookups outside the sandbox.

Attack Vector

Exploitation requires an authenticated actor with permission to execute AccessControl-controlled Python code, such as a TAL/DTML template or Script (Python) object. The attacker constructs a format string that walks from an exposed value (for example, a request or context object) to sensitive attributes, and triggers formatting to receive their string representation.

python
# Patch excerpt: src/AccessControl/ImplPython.py
if name[:1] == '_':
    raise Unauthorized(name)

if name in ('format', 'format_map'):
    if isinstance(inst, str):
        from AccessControl.safe_formatter import safe_format
        from AccessControl.safe_formatter import safe_format_map
        if name == 'format':
            return safe_format(inst, name)
        return safe_format_map(inst, name)
    if isinstance(inst, type) and issubclass(inst, str):
        raise Unauthorized(name)

# Try to get the attribute normally so that unusual
# exceptions are caught early.

Source: Zope AccessControl commit f980450

The fix redirects format and format_map lookups to safe_format and safe_format_map, and denies access to those methods on str subclasses. The equivalent C-level guard in cAccessControl.c recognizes the method name and re-enters the security policy:

c
static int
is_string_format_name(PyObject *name)
{
  PyObject *name_as_bytes;
  char *name_s;
  int result;

  name_as_bytes = convert_name(name);
  if (name_as_bytes == NULL) {
    return -1;
  }

  name_s = PyBytes_AS_STRING(name_as_bytes);
  result = strcmp(name_s, "format") == 0
           || strcmp(name_s, "format_map") == 0;
  Py_DECREF(name_as_bytes);
  return result;
}

Source: Zope AccessControl commit f980450

Detection Methods for CVE-2026-77401

Indicators of Compromise

  • Script (Python) objects, DTML, or TAL templates containing .format( or .format_map( calls with attribute-walking placeholders such as {0.__class__} or {0[__globals__]}.
  • Zope audit log entries showing template edits or execution by low-privilege accounts immediately preceding data disclosure.
  • Unexpected serialization of internal Zope objects in HTTP responses generated by user-editable templates.

Detection Strategies

  • Inventory installed AccessControl package versions and flag any release earlier than 7.4.
  • Static-scan template and Script (Python) repositories for format-string patterns that reference dunder attributes (__class__, __globals__, __mro__).
  • Enable Zope security-policy logging and correlate Unauthorized exceptions from safe_format after upgrading to detect probing attempts.

Monitoring Recommendations

  • Alert on modifications to Through-The-Web (TTW) editable objects performed by non-administrator principals.
  • Monitor outbound response bodies for leakage patterns consistent with Python object repr strings.
  • Track anomalous read access to configuration or credential objects reachable from request context.

How to Mitigate CVE-2026-77401

Immediate Actions Required

  • Upgrade AccessControl to version 7.4 or later across all Zope deployments.
  • Audit user roles and revoke the ability to add or edit Script (Python), DTML, and TAL objects for untrusted accounts.
  • Review recent template commits for weaponized format strings and roll back suspicious changes.

Patch Information

The fix is delivered in Zope AccessControl 7.4 via commit f980450eea416718be62847f34dfd51822938e43. Additional context is available in GHSA-pq59-9fq7-m886. The patch routes format and format_map on strings to safe_format and safe_format_map, and denies these methods entirely when accessed via a str subclass.

Workarounds

  • Remove the Add Scripts (Python) and equivalent template-authoring permissions from any role granted to untrusted users until the upgrade is applied.
  • Replace user-controlled str.format invocations in trusted templates with safe_format from AccessControl.safe_formatter.
  • Restrict network access to Zope Management Interface endpoints so that only administrative networks can reach editable code paths.
bash
# Upgrade AccessControl to the patched release
pip install --upgrade 'AccessControl>=7.4'

# Verify the installed version
python -c "import AccessControl; print(AccessControl.__version__)"

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.