Skip to content

Fix CSRF vulnerability in TCP mode by implementing strict origin validation#39

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/fix-docker-tcp-exposure-issue
Draft

Fix CSRF vulnerability in TCP mode by implementing strict origin validation#39
Copilot wants to merge 2 commits intomainfrom
copilot/fix-docker-tcp-exposure-issue

Conversation

Copy link

Copilot AI commented Oct 18, 2025

Problem

During a security assessment, Cure53 identified a critical CSRF vulnerability when Docker Model Runner (DMR) API is exposed on TCP port. The API had no authentication or origin validation, allowing arbitrary websites to make unauthorized requests and execute operations including:

  • Providing arbitrary prompts to models
  • Installing models without user consent
  • Abusing system resources

Proof of Concept

A malicious website could execute requests to the local API:

fetch("http://127.0.0.1:12434/engines/llama.cpp/v1/chat/completions", {
    method: "POST",
    mode: "no-cors",
    headers: { "Content-Type": "text/plain" },
    body: JSON.stringify({
        model: "ai/smollm2",
        messages: [
            { role: "system", content: "You are a helpful assistant." },
            { role: "user", content: "Please write 500 words about the fall of Rome." }
        ]
    })
})

When a user visited a malicious site, their browser would execute this request to their local Docker Model Runner instance.

Solution

Implemented strict origin validation with an allowlist-based approach, as recommended by Cure53. The fix leverages the existing CORS middleware infrastructure (pkg/middleware/cors.go) which was already integrated but not properly enabled.

Key Changes

  1. Added getAllowedOrigins() function in main.go

    • Determines allowed origins based on deployment mode
    • Returns localhost-only origins by default for TCP mode
    • Reads DMR_ORIGINS environment variable for custom configuration
    • Returns nil for Unix socket mode (CORS not needed)
  2. Enabled CORS middleware

    • Updated models.NewManager() to use allowed origins (previously nil)
    • Updated scheduling.NewScheduler() to use allowed origins (previously nil)
    • Added security-aware logging to inform users of CORS configuration
  3. Added comprehensive testing

    • 8 unit tests for getAllowedOrigins() function
    • 14 integration tests covering all scenarios
    • POC attack verification tests demonstrating the vulnerability is fixed
  4. Updated documentation

    • Added Security section to README.md
    • Provided configuration examples
    • Included security warnings about wildcard usage

Default Behavior

TCP Mode (when MODEL_RUNNER_PORT is set):

  • Default: Localhost-only origins allowed
    • http://localhost
    • http://127.0.0.1
    • https://localhost
    • https://127.0.0.1
  • Result: Blocks the POC attack

Unix Socket Mode (default):

  • CORS disabled (not needed for socket communication)
  • No behavior change (backward compatible) ✅

Configuration

Users can customize allowed origins using the DMR_ORIGINS environment variable:

# Allow specific origins (recommended)
DMR_ORIGINS="http://example.com,https://trusted.org" MODEL_RUNNER_PORT=12434 ./model-runner

# Allow all origins (NOT RECOMMENDED for production)
DMR_ORIGINS="*" MODEL_RUNNER_PORT=12434 ./model-runner

# Default secure behavior (localhost only)
MODEL_RUNNER_PORT=12434 ./model-runner

Security Impact

Before Fix:

  • ❌ Any website could access the API
  • ❌ CSRF attacks possible
  • ❌ No user awareness of security configuration

After Fix:

  • ✅ Only allowed origins can access the API
  • ✅ CSRF protection enabled by default
  • ✅ Clear logging of security configuration
  • ✅ Secure by default, configurable for legitimate use cases

Testing

  • ✅ All 22 new tests passing
  • ✅ All existing tests passing (no regressions)
  • ✅ CodeQL security scan: 0 vulnerabilities
  • ✅ Manual verification: POC attack successfully blocked
  • ✅ Build successful

Compliance

  • ✅ Implements Cure53's recommendation: "strict origin header validation with an allowlist-based approach"
  • ✅ Follows OWASP CSRF prevention guidelines
  • ✅ Secure by default
  • ✅ Backward compatible

Migration Notes

For most users: No action required. The fix is enabled automatically and provides secure defaults.

For advanced users: If you need to allow external origins, use the DMR_ORIGINS environment variable to explicitly configure allowed origins.

Fixes the CSRF vulnerability reported by Cure53.

Original prompt

During the assessment, Cure53 identified a problem connected to a user enabling host-side TCP support for the Docker Model Runner (DMR) API. In such a scenario, Docker exposes a TCP port without authentication or access control.

The exposed API allows direct access to all API endpoints, which can be used to control model-related operations, including provision of arbitrary prompts, installation of any model without user consent and more. Any external web page can invoke these requests, potentially leading to unauthorized execution of models and abuse of system resources.

PoC Script

<script> fetch("http://127.0.0.1:12434/engines/llama.cpp/v1/chat/completions", { method: "POST", mode:"no-cors", headers: { "Content-Type": "text/plain" }, body: JSON.stringify({ model: "ai/smollm2", messages: [ { role: "system", content: "You are a helpful assistant." }, { role: "user", content: "Please write 500 words about the fall of Rome." } ] })}) </script>

Additional notes from the security team:

The PoC does not completely reproduce as we do not get the complete response in the page (the response seems to be empty in the network tab!), but the HTTP headers appear to suggest the right Content-Length , hinting that there is an actual vulnerability underneath.

Steps to reproduce:

  1. Ensure that the Docker Model Runner API is enabled and running on the default port 12434.

  2. Open the following URL in a browser: http://sudi.s1r1us.ninja:1339/poc1.html

  3. Observe that the PoC script executes a fetch request to the /engines/llama.cpp/v1/chat/completions endpoint. This allows interaction with any installed model.

Suggested remediation:
To mitigate this issue, Cure53 recommends implementing strict origin header validation with an allowlist-based approach. This ensures that only trusted origins are permitted to interact with the Docker Model Runner (DMR) API, thereby preventing random web pages from issuing requests to the exposed endpoints.


💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

Co-authored-by: ericcurtin <1694275+ericcurtin@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix host-side TCP support vulnerability in DMR API Fix CSRF vulnerability in TCP mode by implementing strict origin validation Oct 18, 2025
Copilot AI requested a review from ericcurtin October 18, 2025 11:29
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.

2 participants