Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions Doc/library/annotationlib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ and :func:`call_annotate_function`, as well as the
:func:`call_evaluate_function` function for working with
:term:`evaluate functions <evaluate function>`.

.. caution::

Most functionality in this module can execute arbitrary code; see
:ref:`the security section <annotationlib-security>` for more information.

.. seealso::

Expand Down Expand Up @@ -604,3 +608,23 @@ 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 implications of introspecting annotations
--------------------------------------------------

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 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 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
``__annotations__`` dictionary or directly creating a :class:`ForwardRef` object.
5 changes: 5 additions & 0 deletions Doc/library/inspect.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

.. caution::

This function may execute arbitrary code contained in annotations.
See :ref:`annotationlib-security` for more information.

.. versionadded:: 3.10

.. versionchanged:: 3.14
Expand Down
10 changes: 10 additions & 0 deletions Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3360,6 +3360,11 @@ Introspection helpers
See also :func:`annotationlib.get_annotations`, a lower-level function that
returns annotations more directly.

.. caution::

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
Expand Down Expand Up @@ -3506,6 +3511,11 @@ Introspection helpers
See the documentation for :meth:`annotationlib.ForwardRef.evaluate` for
the meaning of the *owner*, *globals*, *locals*, *type_params*, and *format* parameters.

.. caution::

This function may execute arbitrary code contained in annotations.
See :ref:`annotationlib-security` for more information.

.. versionadded:: 3.14

.. data:: NoDefault
Expand Down
Loading