Skip to content

server: add --cors-* options - #25655

Merged
ServeurpersoCom merged 5 commits into
masterfrom
xsn/server_cors_args
Jul 14, 2026
Merged

ServeurpersoCom merged 5 commits into
masterfrom
xsn/server_cors_args

Conversation

@ngxson

@ngxson ngxson commented Jul 14, 2026 •

Copy link
Copy Markdown
Collaborator

Overview

Traditionally, llama-server always enable CORS * with no way to disable it. This was fine because llama-server endpoints were stateless, read-only and default config doesn't expose any sensitive data. The only risk was DoS which is not considered a vulnerability per llama.cpp's policy.

However, with the addition of --agent mode (built-in tools), server can now expose API that allow read/write arbitrary files. If combine with the relaxed CORS, it may allow malicious pages to access local file from server API.

This PR introduce 4 flags, inspired by vllm:

  • --cors-origins
  • --cors-methods
  • --cors-headers
  • --(no-)cors-credentials

By default:

  • the relaxed profile is used: credentials are allowed and Origin header is reflected back (no breaking changes), but a warning will show when server starts
  • if server tools are enable, CORS origin will be limited to localhost (can override via --cors-origins)

Recommendations

Depending on use case

  • Public deployment:
    • highly recommended setting an API key
    • explicit --cors-origins is optional
    • using llama-server behind a reverse proxy to mitigate DoS-related issues
  • Local (trusted) network deployment:
    • recommend explicitly set --cors-origins to origin server address
  • Local deployment (same machine):
    • recommend setting --cors-origins localhost (auto set via --agent)

Requirements

@ngxson
ngxson marked this pull request as ready for review July 14, 2026 11:07
@ngxson
ngxson requested review from a team as code owners July 14, 2026 11:07
@ServeurpersoCom

Copy link
Copy Markdown
Contributor

Memo to myself: I'm going to test/merge this one

@pwilkin

pwilkin commented Jul 14, 2026

Copy link
Copy Markdown
Member

@ngxson Definitely should have a separate documentation section in the server notes, at least with what you just wrote in the PR description.

@ServeurpersoCom ServeurpersoCom self-assigned this Jul 14, 2026
@ServeurpersoCom

ServeurpersoCom commented Jul 14, 2026 •

Copy link
Copy Markdown
Contributor

@ngxson Definitely should have a separate documentation section in the server notes, at least with what you just wrote in the PR description.

I think I can commit to the branch if you approve this proposal, @pwilkin?

doc proposal :

diff --git a/tools/server/README.md b/tools/server/README.md
index 9c8b32dcc..84132b5d7 100644
--- a/tools/server/README.md
+++ b/tools/server/README.md
@@ -329,6 +329,22 @@ The server includes a set of built-in tools that enable the LLM to access the lo

 To use this feature, start the server with `--tools all`. You can also enable only specific tools by passing a comma-separated list: `--tools name1,name2,...`. Run `--help` for the full list of available tool names.

+### CORS
+
+By default the server reflects any `Origin` header back with credentials allowed. This matches the old, always-on `*` behavior and is fine as long as the server only exposes stateless, read-only endpoints.
+
+Enabling `--tools` or `--agent` exposes file read/write over the API, so in that case `--cors-origins` defaults to `localhost` instead: only pages served from localhost can reach the server. Pass `--cors-origins` explicitly to override either default.
+
+Recommended `--cors-origins` setting, depending on where the server runs:
+
+| Deployment | Recommendation |
+| ---------- | --------------- |
+| Public | set an API key, put the server behind a reverse proxy, `--cors-origins` optional |
+| Local network | set `--cors-origins` to your frontend's origin |
+| Same machine | `--cors-origins localhost` (default once `--agent` is set) |
+
+Related flags: `--cors-origins`, `--cors-methods`, `--cors-headers`, `--cors-credentials` / `--no-cors-credentials`. Background and rationale: [#25655](https://github.com/ggml-org/llama.cpp/pull/25655).
+
 ## Build

 `llama-server` is built alongside everything else from the root of the project

CORS

By default the server reflects any Origin header back with credentials allowed. This matches the old, always-on * behavior and is fine as long as the server only exposes stateless, read-only endpoints.

Enabling --tools or --agent exposes file read/write over the API, so in that case --cors-origins defaults to localhost instead: only pages served from localhost can reach the server. Pass --cors-origins explicitly to override either default.

Recommended --cors-origins setting, depending on where the server runs:

Deployment Recommendation
Public set an API key, put the server behind a reverse proxy, --cors-origins optional
Local network set --cors-origins to your frontend's origin
Same machine --cors-origins localhost (default once --agent is set)

Related flags: --cors-origins, --cors-methods, --cors-headers, --cors-credentials / --no-cors-credentials. Background and rationale: #25655.

@ServeurpersoCom ServeurpersoCom 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.

LGTM

What's I tested :

  • default (*, credentials) behavior unchanged, startup warning fires

  • --agent / --tools switches default to localhost, explicit override works

  • reflects localhost / 127.0.0.1 / [::1], rejects everything else

  • /cors-proxy forwards only explicit proxy headers

  • test_security.py: 17/17 passed

  • adversarial: null origin, subdomain suffix, decimal/mapped IP, case, trailing dot all rejected

  • minor: "http://evil.com@localhost" accepted, host correctly parses as localhost per URL syntax, not exploitable: browsers never put userinfo in the Origin header (RFC 6454), no real request can carry this value

@ServeurpersoCom
ServeurpersoCom merged commit 6e52db5 into master Jul 14, 2026
30 of 31 checks passed
@leolebkuchen leolebkuchen mentioned this pull request Jul 22, 2026
2 tasks done
@LsnavTech LsnavTech mentioned this pull request Jul 27, 2026
pl752 pushed a commit to pl752/llama.cpp that referenced this pull request Sep 15, 2026
* server: add --cors-* options

* add special "localhost" value

* add tests

* fix test

* add link to PR
frostyautumnleaf pushed a commit to frostyautumnleaf/llama.cpp that referenced this pull request Oct 5, 2026
* server: add --cors-* options

* add special "localhost" value

* add tests

* fix test

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants