Skip to content

fix(security): protect Docling Serve outbound requests#14033

Merged
erichare merged 3 commits into
release-1.10.3from
fix/le-1785-docling-ssrf
Jul 14, 2026
Merged

fix(security): protect Docling Serve outbound requests#14033
erichare merged 3 commits into
release-1.10.3from
fix/le-1785-docling-ssrf

Conversation

@erichare

@erichare erichare commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • validate Docling Serve URLs with the shared SSRF policy before creating an HTTP client
  • pin validated public DNS addresses and disable automatic redirects
  • preserve API headers and explicitly allowlisted internal Docling deployments

Validation

  • Docling Remote component tests: 9 passed
  • Ruff formatting and lint checks
  • uv build --package lfx-docling --wheel
  • pre-commit hooks

Summary by CodeRabbit

  • Bug Fixes

    • Improved security for remote Docling requests by blocking metadata-service addresses.
    • Added safer handling for public and explicitly allowlisted internal Docling hosts.
    • Preserved required request headers and connection settings during remote processing.
  • Tests

    • Added coverage for secure URL validation, host resolution, allowlisting, and request configuration.

@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: b82dbe3f-5348-4816-b0c9-deb4a765b9d9

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

Docling remote task polling and concurrent file conversion now create HTTP clients through a shared SSRF-protected helper. Tests cover metadata URL blocking, public host IP pinning, headers, redirects, and explicitly allowlisted internal hosts.

Changes

Docling SSRF protection

Layer / File(s) Summary
Centralized protected client creation
src/bundles/docling/src/lfx_docling/components/docling/docling_remote.py
Task polling and concurrent conversion use _create_http_client, which applies processed headers and SSRF-protected HTTPX client options.
SSRF behavior tests
src/bundles/docling/tests/test_docling_remote.py
Tests validate metadata URL rejection, public-host transport pinning, request options, and explicitly allowlisted internal hosts.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

  • langflow-ai/langflow#13353: Overlaps in Docling remote request and header construction, while this change adds SSRF-protected client configuration.
🚥 Pre-merge checks | ✅ 8 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Test Quality And Coverage ⚠️ Warning Coverage is strong for SSRF blocking, headers, and retry/error paths, but the test module imports typing.Self in a Python 3.10-supported package, so it can fail to import. Import Self from typing_extensions (or avoid it) and add one happy-path process_files test to cover the new client creation flow.
✅ Passed checks (8 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding security protections for Docling Serve outbound requests.
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 Yes: test_docling_remote.py adds three SSRF-focused tests for process_task_id/process_files, and the file follows the backend test_*.py convention.
Test File Naming And Structure ✅ Passed test_docling_remote.py is a backend pytest module with descriptive test_ functions, logical helpers, and both positive/negative cases.
Excessive Mock Usage Warning ✅ Passed Tests use a few focused fakes/monkeypatches only for HTTP/SSRF boundaries; core header/config logic is tested with real component behavior, so mocks aren't excessive.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/le-1785-docling-ssrf

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
@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:49
@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

🧹 Nitpick comments (1)
src/bundles/docling/tests/test_docling_remote.py (1)

150-246: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a pinning/headers test for the process_files call site.

The new pinning/headers/redirect assertions only exercise _process_task_id. process_files (docling_remote.py Line 339) uses the same _create_http_client helper but isn't independently asserted for headers/pinning/follow_redirects, only for the blocking case. As per path instructions for **/test_*.py, ensure "the tests actually cover the new or changed behavior rather than acting as placeholders."

🤖 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/bundles/docling/tests/test_docling_remote.py` around lines 150 - 246, Add
a dedicated process_files test that exercises the successful HTTP-client
creation path, not only blocked URLs. Configure a public API URL and headers,
stub hostname resolution and the relevant file-processing response, then assert
the captured client uses preserved headers, follow_redirects=False, and an
SSRFProtectedSyncTransport with the expected pinned IPs; keep the existing
_process_task_id coverage unchanged.

Source: Path instructions

🤖 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/bundles/docling/tests/test_docling_remote.py`:
- Line 5: Update the import in the test module to obtain Self from
typing_extensions instead of typing, while leaving Any imported from typing.
This preserves compatibility with the bundle’s Python 3.10 support.

---

Nitpick comments:
In `@src/bundles/docling/tests/test_docling_remote.py`:
- Around line 150-246: Add a dedicated process_files test that exercises the
successful HTTP-client creation path, not only blocked URLs. Configure a public
API URL and headers, stub hostname resolution and the relevant file-processing
response, then assert the captured client uses preserved headers,
follow_redirects=False, and an SSRFProtectedSyncTransport with the expected
pinned IPs; keep the existing _process_task_id coverage unchanged.
🪄 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: 2f8378d6-8441-42aa-a14c-25c71e348999

📥 Commits

Reviewing files that changed from the base of the PR and between 2433e87 and 264040d.

📒 Files selected for processing (2)
  • src/bundles/docling/src/lfx_docling/components/docling/docling_remote.py
  • src/bundles/docling/tests/test_docling_remote.py

Comment thread src/bundles/docling/tests/test_docling_remote.py Outdated
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 13, 2026
@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Frontend Unit Test Coverage Report

Coverage Summary

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

Unit Test Results

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

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (release-1.10.3@61d6490). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@                Coverage Diff                @@
##             release-1.10.3   #14033   +/-   ##
=================================================
  Coverage                  ?   49.54%           
=================================================
  Files                     ?     2164           
  Lines                     ?   207753           
  Branches                  ?    15075           
=================================================
  Hits                      ?   102925           
  Misses                    ?   103343           
  Partials                  ?     1485           
Flag Coverage Δ
backend 65.80% <ø> (?)
frontend 43.54% <ø> (?)
lfx 54.65% <ø> (?)

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

🚀 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.

@Adam-Aghili Adam-Aghili left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM but 1 code rabbit issue is legitimate

Comment thread src/bundles/docling/tests/test_docling_remote.py Outdated
@github-actions github-actions Bot added the lgtm This PR has been approved by a maintainer label Jul 14, 2026
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jul 14, 2026
@erichare erichare merged commit 32bef8c into release-1.10.3 Jul 14, 2026
47 checks passed
@erichare erichare deleted the fix/le-1785-docling-ssrf branch July 14, 2026 17:28
erichare added a commit that referenced this pull request Jul 14, 2026
* fix(kb): enforce per-user path containment

* fix(security): protect Docling Serve outbound requests (#14033)

* fix(security): protect Docling Serve requests

* fix(docling): support Self on Python 3.10

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* fix(auth): verify current password on password changes (#14034)

* fix(security): harden MCP stdio configuration (#14036)

* fix(security): restrict MCP stdio package sources

* fix(security): block MCP Docker host access

* fix(security): validate embedded MCP stdio configs

* fix: require executable-only MCP commands

* test: use allowed MCP commands in timeout tests

* fix(security): harden component code module access (#14032)

* fix(security): harden component code module access

* fix(security): block native FFI imports in generated code

* fix: track module assignment aliases in code scanner

* fix(security): address alias review findings

* fix: correct deprecated model settings behavior (#14047)

* fix: prevent deprecated model enablement

* test: use supported model in credential cleanup

* fix(voice): enforce flow authorization on websocket (#14043)

* fix(security): block native FFI imports in generated code (#14040)

* fix(security): block native FFI imports in generated code

* fix: track module assignment aliases in code scanner

* chore: resolve code security conflicts

* fix(security): confine AssemblyAI audio file access (#14037)

* fix(security): confine AssemblyAI audio file access

* [autofix.ci] apply automated fixes

* test: stub optional AssemblyAI dependency

* fix(security): harden AssemblyAI file submission

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>

* fix: track assignment aliases in component code scanner (#14041)

fix: bind loop and comprehension aliases

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
erichare added a commit that referenced this pull request Jul 16, 2026
* fix(security): protect Docling Serve outbound requests (#14033)

* fix(security): protect Docling Serve requests

* fix(docling): support Self on Python 3.10

(cherry picked from commit 32bef8c)

* fix(auth): verify current password on password changes (#14034)

(cherry picked from commit 16725f0)

* fix(security): harden component code module access (#14032)

* fix(security): harden component code module access

* fix(security): block native FFI imports in generated code

* fix: track module assignment aliases in code scanner

* fix(security): address alias review findings

(cherry picked from commit 2016e4b)

* fix: bind loop and comprehension aliases

(cherry picked from commit 375ce63)

* fix(voice): enforce flow authorization on websocket (#14043)

(cherry picked from commit 229f86d)

* fix(kb): enforce folder connector security settings

(cherry picked from commit 917e390)

* fix(kb): enforce per-user path containment

(cherry picked from commit ec81655)

* fix(security): confine AssemblyAI audio file access (#14037)

Adapt the 1.10.3 fix to the lfx-bundles component path used by release-1.11.0.

* fix(security): harden published image connector defaults

* fix(lfx): register code execution aliases

(cherry picked from commit cf13188)

* fix(security): complete release-1.11 forward port

* [autofix.ci] apply automated fixes

* fix(security): protect SQL runtime configuration

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

* fix(security): address review gaps

* test: align MCP command security fixtures

* fix(voice): preserve public flow websocket access

* chore: regenerate component metadata

* chore: align generated component metadata

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working lgtm This PR has been approved by a maintainer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants