@@ -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.
0 commit comments