Skip to content

Commit 9deae53

Browse files
author
Semgrep Autofix
committed
fix unsafe annotation copying in llm_router decorator
Prevent potential code injection via arbitrary type annotations in the llm_router decorator. ## Changes - Removed blanket copying of all annotations from decorated functions via `func.__annotations__.copy()` - Now only copies the return annotation when needed for validation - Added validation to ensure the annotation is an actual type object, not a string forward reference ## Why The previous code copied all annotations from user-provided decorated functions to the wrapper. String annotations (forward references) can be evaluated by `typing.get_type_hints()` in the function's globals/locals namespace, potentially executing arbitrary code. The fix restricts annotation copying to only the return type (which is actually used for routing validation) and rejects string annotations that could be dangerous when evaluated. The wrapper function already has proper parameter annotations defined in its signature, so those don't need to be copied. ## Semgrep Finding Details Annotations passed to `typing.get_type_hints` are evaluated in `globals` and `locals` namespaces. Make sure that no arbitrary value can be written as the annotation and passed to `typing.get_type_hints` function. @18578539 requested Semgrep Assistant generate this pull request to fix [a finding](https://semgrep.dev/orgs/rootflo_ai/findings/683091385) from the detection rule [python.lang.security.audit.dangerous-annotations-usage.dangerous-annotations-usage](https://semgrep.dev/r/python.lang.security.audit.dangerous-annotations-usage.dangerous-annotations-usage).
1 parent ceda045 commit 9deae53

1 file changed

Lines changed: 7 additions & 5 deletions

File tree

flo_ai/flo_ai/arium/llm_router.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1038,12 +1038,14 @@ async def wrapper(
10381038
):
10391039
return await router_instance.route(memory, execution_context)
10401040

1041-
# Preserve the original function's type annotations including return type
1042-
wrapper.__annotations__ = func.__annotations__.copy()
1043-
1044-
# Ensure the return annotation is properly set
1041+
# Only copy the return annotation if needed for validation
1042+
# Avoid copying arbitrary string annotations which could be evaluated
1043+
# by get_type_hints() and potentially execute code
10451044
if 'return' in func.__annotations__:
1046-
wrapper.__annotations__['return'] = func.__annotations__['return']
1045+
return_annotation = func.__annotations__['return']
1046+
# Only copy if it's an actual type object, not a forward reference string
1047+
if not isinstance(return_annotation, str):
1048+
wrapper.__annotations__['return'] = return_annotation
10471049

10481050
return wrapper
10491051

0 commit comments

Comments
 (0)