Skip to content

Commit 2584b31

Browse files
committed
Add threat model to remote debugging docs
The remote debugging protocol has been generating spurious vulnerability reports from automated scanners that pattern-match on "remote access" and "memory operations" without understanding the privilege model. This section documents the security boundaries so reporters can self-triage before submitting. The threat model clarifies three points: attaching requires the same OS-level privileges as GDB (ptrace, task_for_pid, or SeDebugPrivilege), crashes caused by reading corrupted target process memory are not security issues, and a compromised target process is out of scope. A subsection explains when operators should use PYTHON_DISABLE_REMOTE_DEBUG for defence-in-depth.
1 parent 6009309 commit 2584b31

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

Doc/howto/remote_debugging.rst

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,3 +624,59 @@ To inject and execute a Python script in a remote process:
624624
6. Set ``_PY_EVAL_PLEASE_STOP_BIT`` in the ``eval_breaker`` field.
625625
7. Resume the process (if suspended). The script will execute at the next safe
626626
evaluation point.
627+
628+
.. _remote-debugging-threat-model:
629+
630+
Security and threat model
631+
=========================
632+
633+
The remote debugging protocol relies on the same operating system primitives
634+
used by native debuggers such as GDB and LLDB. Attaching to a process
635+
requires the **same privileges** that those debuggers require, for example
636+
``ptrace`` / Yama LSM on Linux, ``task_for_pid`` on macOS, and
637+
``SeDebugPrivilege`` on Windows. Python does not introduce any new privilege
638+
escalation path; if an attacker already possesses the permissions needed to
639+
attach to a process, they could equally use GDB to read memory or inject
640+
code.
641+
642+
The following principles define what is, and is not, considered a security
643+
vulnerability in this feature:
644+
645+
**Attaching requires OS-level privileges.**
646+
On every supported platform the operating system gates cross-process
647+
memory access behind privilege checks (``CAP_SYS_PTRACE``, root, or
648+
administrator rights). A report that demonstrates an issue only after
649+
these privileges have already been obtained is **not** a vulnerability in
650+
CPython, since the OS security boundary was already crossed.
651+
652+
**Crashes or memory errors when reading a compromised process are not
653+
vulnerabilities.**
654+
A tool that reads internal interpreter state from a target process must
655+
trust that memory to be well-formed. If the target process has been
656+
corrupted or is controlled by an attacker, the debugger or profiler may
657+
crash, produce garbage output, or behave unpredictably. This is the same
658+
risk accepted by every ``ptrace``-based debugger. Bugs in this category
659+
(buffer overflows, segmentation faults, or undefined behaviour triggered
660+
by reading corrupted state) are **not** treated as security issues, though
661+
fixes that improve robustness are welcome.
662+
663+
**Vulnerabilities in the target process are not in scope.**
664+
If the Python process being debugged has already been compromised, the
665+
attacker already controls execution in that process. Demonstrating further
666+
impact from that starting point does not constitute a vulnerability in the
667+
remote debugging protocol.
668+
669+
When to use ``PYTHON_DISABLE_REMOTE_DEBUG``
670+
-------------------------------------------
671+
672+
The environment variable :envvar:`PYTHON_DISABLE_REMOTE_DEBUG` (and the
673+
equivalent :option:`-X disable_remote_debug` flag) allows operators to disable
674+
the in-process side of the protocol as a **defence-in-depth** measure. This
675+
may be useful in hardened or sandboxed deployment environments where no
676+
debugging or profiling of the process is expected and reducing attack surface
677+
is a priority, even though the OS-level privilege checks already prevent
678+
unprivileged access.
679+
680+
Setting this variable does **not** affect other OS-level debugging interfaces
681+
(``ptrace``, ``/proc``, ``task_for_pid``, etc.), which remain available
682+
according to their own permission models.

0 commit comments

Comments
 (0)