GRPC_WEB_CORS_ORIGIN_DENIED grpc auth_error ai_generated true

INTERNAL: grpc-web: CORS preflight failed for origin http://malicious-site.com: Access-Control-Allow-Origin not present in response

ID: grpc/cors-preflight-origin-not-allowed

Also available as: JSON · Markdown · 中文
92%Fix Rate
89%Confidence
1Evidence
2024-02-28First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
gRPC-Web v1.4.0 active
envoy v1.28.0 active
gRPC-web-go-client v1.4.0 active

Root Cause

A gRPC-Web client from an unauthorized origin attempted a CORS preflight request, but the server's CORS policy did not include that origin in the allowed origins list.

generic

中文

来自未授权来源的 gRPC-Web 客户端尝试了 CORS 预检请求,但服务器的 CORS 策略未将该来源列入允许列表。

Official Documentation

https://github.com/grpc/grpc-web/blob/master/README.md#cors

Workarounds

  1. 95% success Add the specific origin to the CORS allowlist on the gRPC-Web proxy (e.g., Envoy). In Envoy config: cors_policy: allow_origin_string_match: [prefix: "https://myapp.example.com"] allow_methods: "POST, OPTIONS" allow_headers: "content-type, x-grpc-web"
    Add the specific origin to the CORS allowlist on the gRPC-Web proxy (e.g., Envoy). In Envoy config: cors_policy: allow_origin_string_match: [prefix: "https://myapp.example.com"] allow_methods: "POST, OPTIONS" allow_headers: "content-type, x-grpc-web"
  2. 90% success If using a custom Go gRPC-Web server, add CORS middleware: func corsMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "https://myapp.example.com"); w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS"); w.Header().Set("Access-Control-Allow-Headers", "content-type, x-grpc-web"); if r.Method == "OPTIONS" { w.WriteHeader(http.StatusOK); return }; h.ServeHTTP(w, r) }) }
    If using a custom Go gRPC-Web server, add CORS middleware: func corsMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "https://myapp.example.com"); w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS"); w.Header().Set("Access-Control-Allow-Headers", "content-type, x-grpc-web"); if r.Method == "OPTIONS" { w.WriteHeader(http.StatusOK); return }; h.ServeHTTP(w, r) }) }
  3. 85% success Use a reverse proxy like nginx to add CORS headers before the request reaches the gRPC-Web server: add_header 'Access-Control-Allow-Origin' 'https://myapp.example.com' always;
    Use a reverse proxy like nginx to add CORS headers before the request reaches the gRPC-Web server: add_header 'Access-Control-Allow-Origin' 'https://myapp.example.com' always;

中文步骤

  1. Add the specific origin to the CORS allowlist on the gRPC-Web proxy (e.g., Envoy). In Envoy config: cors_policy: allow_origin_string_match: [prefix: "https://myapp.example.com"] allow_methods: "POST, OPTIONS" allow_headers: "content-type, x-grpc-web"
  2. If using a custom Go gRPC-Web server, add CORS middleware: func corsMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "https://myapp.example.com"); w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS"); w.Header().Set("Access-Control-Allow-Headers", "content-type, x-grpc-web"); if r.Method == "OPTIONS" { w.WriteHeader(http.StatusOK); return }; h.ServeHTTP(w, r) }) }
  3. Use a reverse proxy like nginx to add CORS headers before the request reaches the gRPC-Web server: add_header 'Access-Control-Allow-Origin' 'https://myapp.example.com' always;

Dead Ends

Common approaches that don't work:

  1. 90% fail

    Setting Access-Control-Allow-Origin: * in production exposes the API to cross-site request forgery and data theft from any website.

  2. 95% fail

    Disabling CORS checks on the client by using a non-browser environment (e.g., curl) does not solve the problem for actual web users.