From afa6a057fd216372cad96b8660198a353af0c3f9 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 4 Sep 2025 11:51:32 -0700 Subject: [PATCH 1/2] annotationlib: add note on security to docs --- Doc/library/annotationlib.rst | 23 +++++++++++++++++++++++ Doc/library/inspect.rst | 5 +++++ Doc/library/typing.rst | 10 ++++++++++ 3 files changed, 38 insertions(+) diff --git a/Doc/library/annotationlib.rst b/Doc/library/annotationlib.rst index 981d89be7d58d6..5e5ca6bf084840 100644 --- a/Doc/library/annotationlib.rst +++ b/Doc/library/annotationlib.rst @@ -45,6 +45,10 @@ and :func:`call_annotate_function`, as well as the :func:`call_evaluate_function` function for working with :term:`evaluate functions `. +.. warning:: + + Most functionality in this module can execute arbitrary code; see + :ref:`the security section ` for more information. .. seealso:: @@ -603,3 +607,22 @@ Below are a few examples of the behavior with unsupported expressions: >>> def ifexp(x: 1 if y else 0): ... >>> get_annotations(ifexp, format=Format.STRING) {'x': '1'} + +.. _annotationlib-security: + +Security +-------- + +Much of the functionality in this module involves executing arbitrary code. For example, +:func:`get_annotations` may call an arbitrary :term:`annotate function`, and +:meth:`ForwardRef.evaluate` may call :func:`eval` on an arbitrary string. Code contained +in an annotation might make arbitrary system calls, enter an infinite loop, or perform any +other operation. This is also true for access to the :attr:`~object.__annotations__` attribute, +and for various functions in the :mod:`typing` module that work with annotations, such as +:func:`typing.get_type_hints`. + +Any security issues arising from these facts also apply immediately after importing +code that may contain untrusted annotations: importing code can always cause arbitrary operations +to be performed. However, it is unsafe to accept strings or other input from an untrusted source and +pass them to any of the APIs for introspecting annotations, for example by editing an +``__annotations__`` dictionary or directly creating a :class:`ForwardRef` object. diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index e8d1176f477866..71a92337b6659f 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -1289,6 +1289,11 @@ Classes and functions This is an alias for :func:`annotationlib.get_annotations`; see the documentation of that function for more information. + .. warning:: + + This function may execute arbitrary code contained in annotations. + See :ref:`annotationlib-security` for more information. + .. versionadded:: 3.10 .. versionchanged:: 3.14 diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index c8eb1d08a1bb2a..32eeccb66c4515 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3367,6 +3367,11 @@ Introspection helpers See also :func:`annotationlib.get_annotations`, a lower-level function that returns annotations more directly. + .. warning:: + + This function may execute arbitrary code contained in annotations. + See :ref:`annotationlib-security` for more information. + .. note:: If any forward references in the annotations of *obj* are not resolvable @@ -3513,6 +3518,11 @@ Introspection helpers See the documentation for :meth:`annotationlib.ForwardRef.evaluate` for the meaning of the *owner*, *globals*, *locals*, *type_params*, and *format* parameters. + .. warning:: + + This function may execute arbitrary code contained in annotations. + See :ref:`annotationlib-security` for more information. + .. versionadded:: 3.14 .. data:: NoDefault From 091cd793055d914468a2a1350418aaeec521a418 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 4 Sep 2025 19:05:26 -0700 Subject: [PATCH 2/2] feedback --- Doc/library/annotationlib.rst | 13 +++++++------ Doc/library/inspect.rst | 2 +- Doc/library/typing.rst | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/Doc/library/annotationlib.rst b/Doc/library/annotationlib.rst index 5e5ca6bf084840..9daa2a4962e8e2 100644 --- a/Doc/library/annotationlib.rst +++ b/Doc/library/annotationlib.rst @@ -45,7 +45,7 @@ and :func:`call_annotate_function`, as well as the :func:`call_evaluate_function` function for working with :term:`evaluate functions `. -.. warning:: +.. caution:: Most functionality in this module can execute arbitrary code; see :ref:`the security section ` for more information. @@ -610,18 +610,19 @@ Below are a few examples of the behavior with unsupported expressions: .. _annotationlib-security: -Security --------- +Security implications of introspecting annotations +-------------------------------------------------- -Much of the functionality in this module involves executing arbitrary code. For example, +Much of the functionality in this module involves executing code related to annotations, +which can then do arbitrary things. For example, :func:`get_annotations` may call an arbitrary :term:`annotate function`, and :meth:`ForwardRef.evaluate` may call :func:`eval` on an arbitrary string. Code contained in an annotation might make arbitrary system calls, enter an infinite loop, or perform any -other operation. This is also true for access to the :attr:`~object.__annotations__` attribute, +other operation. This is also true for any access of the :attr:`~object.__annotations__` attribute, and for various functions in the :mod:`typing` module that work with annotations, such as :func:`typing.get_type_hints`. -Any security issues arising from these facts also apply immediately after importing +Any security issue arising from this also applies immediately after importing code that may contain untrusted annotations: importing code can always cause arbitrary operations to be performed. However, it is unsafe to accept strings or other input from an untrusted source and pass them to any of the APIs for introspecting annotations, for example by editing an diff --git a/Doc/library/inspect.rst b/Doc/library/inspect.rst index 71a92337b6659f..1061ae8849f48f 100644 --- a/Doc/library/inspect.rst +++ b/Doc/library/inspect.rst @@ -1289,7 +1289,7 @@ Classes and functions This is an alias for :func:`annotationlib.get_annotations`; see the documentation of that function for more information. - .. warning:: + .. caution:: This function may execute arbitrary code contained in annotations. See :ref:`annotationlib-security` for more information. diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst index 32eeccb66c4515..022c76b084c08c 100644 --- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -3367,7 +3367,7 @@ Introspection helpers See also :func:`annotationlib.get_annotations`, a lower-level function that returns annotations more directly. - .. warning:: + .. caution:: This function may execute arbitrary code contained in annotations. See :ref:`annotationlib-security` for more information. @@ -3518,7 +3518,7 @@ Introspection helpers See the documentation for :meth:`annotationlib.ForwardRef.evaluate` for the meaning of the *owner*, *globals*, *locals*, *type_params*, and *format* parameters. - .. warning:: + .. caution:: This function may execute arbitrary code contained in annotations. See :ref:`annotationlib-security` for more information.