Skip to content

Commit 9158bcf

Browse files
annotationlib: add note on security to docs (#138508)
1 parent 0c74fc8 commit 9158bcf

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

Doc/library/annotationlib.rst

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ and :func:`call_annotate_function`, as well as the
4646
:func:`call_evaluate_function` function for working with
4747
:term:`evaluate functions <evaluate function>`.
4848

49+
.. caution::
50+
51+
Most functionality in this module can execute arbitrary code; see
52+
:ref:`the security section <annotationlib-security>` for more information.
4953

5054
.. seealso::
5155

@@ -604,3 +608,23 @@ Below are a few examples of the behavior with unsupported expressions:
604608
>>> def ifexp(x: 1 if y else 0): ...
605609
>>> get_annotations(ifexp, format=Format.STRING)
606610
{'x': '1'}
611+
612+
.. _annotationlib-security:
613+
614+
Security implications of introspecting annotations
615+
--------------------------------------------------
616+
617+
Much of the functionality in this module involves executing code related to annotations,
618+
which can then do arbitrary things. For example,
619+
:func:`get_annotations` may call an arbitrary :term:`annotate function`, and
620+
:meth:`ForwardRef.evaluate` may call :func:`eval` on an arbitrary string. Code contained
621+
in an annotation might make arbitrary system calls, enter an infinite loop, or perform any
622+
other operation. This is also true for any access of the :attr:`~object.__annotations__` attribute,
623+
and for various functions in the :mod:`typing` module that work with annotations, such as
624+
:func:`typing.get_type_hints`.
625+
626+
Any security issue arising from this also applies immediately after importing
627+
code that may contain untrusted annotations: importing code can always cause arbitrary operations
628+
to be performed. However, it is unsafe to accept strings or other input from an untrusted source and
629+
pass them to any of the APIs for introspecting annotations, for example by editing an
630+
``__annotations__`` dictionary or directly creating a :class:`ForwardRef` object.

Doc/library/inspect.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,11 @@ Classes and functions
12891289
This is an alias for :func:`annotationlib.get_annotations`; see the documentation
12901290
of that function for more information.
12911291

1292+
.. caution::
1293+
1294+
This function may execute arbitrary code contained in annotations.
1295+
See :ref:`annotationlib-security` for more information.
1296+
12921297
.. versionadded:: 3.10
12931298

12941299
.. versionchanged:: 3.14

Doc/library/typing.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3367,6 +3367,11 @@ Introspection helpers
33673367
See also :func:`annotationlib.get_annotations`, a lower-level function that
33683368
returns annotations more directly.
33693369

3370+
.. caution::
3371+
3372+
This function may execute arbitrary code contained in annotations.
3373+
See :ref:`annotationlib-security` for more information.
3374+
33703375
.. note::
33713376

33723377
If any forward references in the annotations of *obj* are not resolvable
@@ -3513,6 +3518,11 @@ Introspection helpers
35133518
See the documentation for :meth:`annotationlib.ForwardRef.evaluate` for
35143519
the meaning of the *owner*, *globals*, *locals*, *type_params*, and *format* parameters.
35153520

3521+
.. caution::
3522+
3523+
This function may execute arbitrary code contained in annotations.
3524+
See :ref:`annotationlib-security` for more information.
3525+
35163526
.. versionadded:: 3.14
35173527

35183528
.. data:: NoDefault

0 commit comments

Comments
 (0)