Skip to content

fix: track assignment aliases in component code scanner#14041

Open
erichare wants to merge 2 commits into
release-1.10.3from
fix/le-1787-code-security-assignment-aliases
Open

fix: track assignment aliases in component code scanner#14041
erichare wants to merge 2 commits into
release-1.10.3from
fix/le-1787-code-security-assignment-aliases

Conversation

@erichare

@erichare erichare commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • propagate imported-module identities through assignment aliases in the generated component code scanner
  • keep alias state flow- and scope-aware so safe rebindings, module attributes, and parameter/local shadowing remain allowed
  • add regression coverage for call, attribute-read, and blocked-submodule bypasses

Testing

  • 101 scanner tests passed
  • Ruff, formatting, and pre-commit passed

Merge order

  1. Merge this PR
  2. Merge fix(security): block native FFI imports in generated code #14040
  3. Merge fix(security): harden component code module access #14032

Summary by CodeRabbit

  • Bug Fixes

    • Improved security scanning to reliably detect restricted module usage through direct, chained, destructured, and conditional aliases.
    • Prevented false positives when aliases are reassigned to safe values or shadowed within functions and parameters.
    • Improved detection of restricted submodule access through aliases.
  • Tests

    • Added comprehensive coverage for alias handling, scope isolation, safe rebinding, and shadowing scenarios.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 390bb982-d18b-4bb2-bbc2-54106826aad1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The AST security scanner now tracks multiple module aliases, shadowed bindings, branch-specific states, and nested scopes. Assignment-based access to restricted modules is resolved through direct, chained, destructured, annotated, and named-expression aliases, with regression coverage for safe rebinding and scope isolation.

Changes

Security alias resolution

Layer / File(s) Summary
Alias state and import handling
src/backend/base/langflow/agentic/helpers/code_security.py
Introduces multi-valued module aliases and shadowed-name tracking, and updates import processing to use the new state.
Flow and scope-aware binding
src/backend/base/langflow/agentic/helpers/code_security.py
Handles assignment aliases, unpacking, branch merges, named expressions, and isolated function, lambda, and class scopes.
Security checks and regression coverage
src/backend/base/langflow/agentic/helpers/code_security.py, src/backend/tests/unit/agentic/helpers/test_code_security.py
Resolves dangerous attribute calls across alias candidates and tests restricted access, safe rebinding, and scope shadowing.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

  • langflow-ai/langflow#13784: Expands blocked network imports and os.dup* handling that is evaluated through this alias-resolution logic.

Suggested reviewers: ogabrielluiz, cristhianzl

🚥 Pre-merge checks | ✅ 9
✅ Passed checks (9 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: flow-aware tracking of assignment aliases in the code scanner.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Test Coverage For New Implementations ✅ Passed PASS: Added test_code_security.py unit suite with real scan_code_security assertions for aliasing, rebinding, and scope shadowing; naming matches backend convention.
Test Quality And Coverage ✅ Passed The new pytest unit tests exercise alias propagation, rebinding, scope shadowing, and safe/unsafe cases with concrete assertions, not smoke checks.
Test File Naming And Structure ✅ Passed PASS: The new backend test_*.py uses pytest-style classes and descriptive test_should_* methods, and it covers positive, negative, and edge cases cleanly.
Excessive Mock Usage Warning ✅ Passed PASS: The new tests call scan_code_security directly with code snippets; no Mock/patch/monkeypatch usage appears in the changed test file.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/le-1787-code-security-assignment-aliases

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the bug Something isn't working label Jul 13, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 13, 2026
@erichare erichare marked this pull request as ready for review July 13, 2026 19:47
@github-actions

Copy link
Copy Markdown
Contributor

✅ Test Coverage Advisor

No source changes detected without accompanying tests. Thanks for keeping coverage up! 🎉

Advisory check only — never blocks merge.

@erichare erichare requested a review from Adam-Aghili July 13, 2026 19:50
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 13, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/backend/base/langflow/agentic/helpers/code_security.py`:
- Around line 335-357: Update the AST visitor handling loop and comprehension
targets so they call _bind_assignment_target with the iterated value, rather
than only traversing Store-name nodes. Cover both for/async-for targets and
comprehension.target, conservatively binding aliases so calls through names such
as m or n are scanned.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cc9c0159-d301-4827-a29e-3cc8da52667d

📥 Commits

Reviewing files that changed from the base of the PR and between 2433e87 and 8f6f92b.

📒 Files selected for processing (2)
  • src/backend/base/langflow/agentic/helpers/code_security.py
  • src/backend/tests/unit/agentic/helpers/test_code_security.py

Comment on lines +335 to +357
def visit_Assign(self, node: ast.Assign):
self.visit(node.value)
for target in node.targets:
self.visit(target)
self._bind_assignment_target(target, node.value)

def visit_AnnAssign(self, node: ast.AnnAssign):
self.visit(node.annotation)
if node.value is not None:
self.visit(node.value)
self.visit(node.target)
self._bind_assignment_target(node.target, node.value)

def visit_NamedExpr(self, node: ast.NamedExpr):
self.visit(node.value)
self.visit(node.target)
self._bind_assignment_target(node.target, node.value)

def visit_AugAssign(self, node: ast.AugAssign):
self.visit(node.target)
self.visit(node.value)
if isinstance(node.target, ast.Name):
self._bind_name(node.target.id, frozenset())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm the scanner has no For/While/comprehension target handling.
fd -t f code_security.py --exec rg -nP '\bdef visit_(For|AsyncFor|While|comprehension|ListComp|SetComp|DictComp|GeneratorExp)\b' {}
echo "---- assignment-style handlers present: ----"
fd -t f code_security.py --exec rg -nP '\bdef visit_(Assign|AnnAssign|NamedExpr|AugAssign)\b' {}

Repository: langflow-ai/langflow

Length of output: 421


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="src/backend/base/langflow/agentic/helpers/code_security.py"

echo "== Outline =="
ast-grep outline "$FILE" --view expanded | sed -n '1,240p'

echo
echo "== Binding helpers and visitor methods =="
sed -n '1,260p' "$FILE" | nl -ba | sed -n '1,260p'

echo
echo "== Search for generic_visit / target binding / scan entrypoints =="
rg -n "generic_visit|_bind_assignment_target|_bind_name|_scan_flow_component_code|visit_For|visit_AsyncFor|visit_comprehension|visit_ListComp|visit_SetComp|visit_DictComp|visit_GeneratorExp" "$FILE"

Repository: langflow-ai/langflow

Length of output: 2997


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="src/backend/base/langflow/agentic/helpers/code_security.py"

echo "== Relevant visitor and binding code =="
sed -n '235,520p' "$FILE"

echo
echo "== Any explicit loop/comprehension visitors or target binders elsewhere =="
rg -n "def visit_(For|AsyncFor|While|comprehension|ListComp|SetComp|DictComp|GeneratorExp)|_bind_assignment_target|_resolved_assignment_value|generic_visit" "$FILE"

echo
echo "== AST behavior probe: NodeVisitor generic traversal over For/comprehension targets =="
uv run python3 - <<'PY'
import ast

class V(ast.NodeVisitor):
    def visit_Name(self, node):
        print("Name:", node.id, type(node.ctx).__name__)
        self.generic_visit(node)

code = """
import os
for m in (os,):
    pass
result = [n for n in (os,)]
"""
V().visit(ast.parse(code))
PY

Repository: langflow-ai/langflow

Length of output: 14153


Loop and comprehension targets need alias binding. for/async for targets and comprehension.target are only traversed as ast.Name(..., Store) nodes here, so they never reach _bind_assignment_target; aliases like for m in (os,): m.system(...) or [n.system(...) for n in (os,)] slip past the scanner. Handle those targets conservatively in the visitor.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/backend/base/langflow/agentic/helpers/code_security.py` around lines 335
- 357, Update the AST visitor handling loop and comprehension targets so they
call _bind_assignment_target with the iterated value, rather than only
traversing Store-name nodes. Cover both for/async-for targets and
comprehension.target, conservatively binding aliases so calls through names such
as m or n are scanned.

@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 13, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 43%
43.54% (58072/133362) 69.2% (7883/11391) 41.56% (1298/3123)

Unit Test Results

Tests Skipped Failures Errors Time
4978 0 💤 0 ❌ 0 🔥 12m 55s ⏱️

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.09272% with 21 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (release-1.10.3@61d6490). Learn more about missing BASE report.

Files with missing lines Patch % Lines
...end/base/langflow/agentic/helpers/code_security.py 86.09% 21 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                @@
##             release-1.10.3   #14041   +/-   ##
=================================================
  Coverage                  ?   58.63%           
=================================================
  Files                     ?     2306           
  Lines                     ?   221140           
  Branches                  ?    34222           
=================================================
  Hits                      ?   129676           
  Misses                    ?    89978           
  Partials                  ?     1486           
Flag Coverage Δ
backend 65.90% <86.09%> (?)
frontend 57.76% <ø> (?)
lfx 54.65% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...end/base/langflow/agentic/helpers/code_security.py 91.94% <86.09%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant