Skip to content

fix issue#3495#3556

Open
xunluHu wants to merge 2 commits intointelowlproject:masterfrom
xunluHu:bridge3459
Open

fix issue#3495#3556
xunluHu wants to merge 2 commits intointelowlproject:masterfrom
xunluHu:bridge3459

Conversation

@xunluHu
Copy link
Copy Markdown

@xunluHu xunluHu commented Mar 26, 2026

Description

Fix: Inject global default timeout for requests to prevent Celery worker starvation (DoS) issue#3495

Background

As discussed in the issue, many analyzers and connectors use the requests library without an explicit timeout parameter. Because IntelOwl utilizes a fixed-size pool of Celery workers, slow or malicious external services can keep HTTP requests open indefinitely (slow-tail attacks). This can effectively cause a Denial of Service (DoS) by occupying all available worker slots.

Proposed Changes

Instead of manually hunting down and updating hundreds of scattered requests.get/post calls (which is error-prone and doesn't prevent future regressions), I implemented a system-wide, non-intrusive monkey patch for the requests library.

Specific changes include:

  1. Global Default Timeout : Introduced get_default_requests_timeout() in api_app/helpers.py . It defaults to a tuple of (10.0, 30.0) (10s connect, 30s read).
  2. Environment Variable Support : Administrators can now override the default timeouts without changing code by setting INTELOWL_REQUESTS_CONNECT_TIMEOUT and INTELOWL_REQUESTS_READ_TIMEOUT .
  3. Session Patching : Created patch_requests_default_timeout() which intercepts requests.sessions.Session.request .
    • If a plugin developer omits the timeout, the default tuple is automatically injected.
    • If a plugin developer explicitly sets a timeout (e.g., for long file downloads), the patch respects their choice and does not override it.
  4. App Initialization : Integrated the patch into ApiAppConfig.ready() in api_app/apps.py so that the protection is activated automatically upon application startup (including Celery workers).
  5. Unit Tests : Added comprehensive tests in tests/api_app/test_requests_timeout.py to ensure the patch injects defaults correctly, respects explicit timeouts, and reads environment variables properly.

Why this approach?

This "Secure by Default" approach ensures that both existing and future analyzers/connectors are protected from indefinite hangs automatically, while still maintaining the flexibility for specific plugins to define their own timeouts when necessary.

How to test

  1. Run the newly added unit tests: python manage.py test tests.api_app.test_requests_timeout
  2. Point any existing analyzer to a slowloris or infinite loop server without an explicit timeout; observe that the worker now correctly times out after 10-30 seconds instead of hanging forever.

@xunluHu xunluHu closed this Mar 26, 2026
@xunluHu xunluHu reopened this Mar 26, 2026
@xunluHu xunluHu force-pushed the bridge3459 branch 2 times, most recently from 278e83f to 5d61c7f Compare March 27, 2026 05:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant