@@ -46,6 +46,10 @@ and :func:`call_annotate_function`, as well as the
46
46
:func: `call_evaluate_function ` function for working with
47
47
:term: `evaluate functions <evaluate function> `.
48
48
49
+ .. caution ::
50
+
51
+ Most functionality in this module can execute arbitrary code; see
52
+ :ref: `the security section <annotationlib-security >` for more information.
49
53
50
54
.. seealso ::
51
55
@@ -604,3 +608,23 @@ Below are a few examples of the behavior with unsupported expressions:
604
608
>>> def ifexp(x: 1 if y else 0): ...
605
609
>>> get_annotations(ifexp, format=Format.STRING)
606
610
{'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