ogen icon indicating copy to clipboard operation
ogen copied to clipboard

CORS headers: The only allowed header is Content-Type

Open Russia9 opened this issue 1 year ago • 1 comments

What version of ogen are you using?

$ go list -m github.com/ogen-go/ogen
github.com/ogen-go/ogen v1.4.1

Can this issue be reproduced with the latest version?

Yes

What did you do?

I created an OpenAPI spec that utilizes a custom user-defined header and has a Bearer security scheme:

openapi: 3.1.0
info:
  title: Simple API
  description: A simple API with header utilization
  version: 1.0.0
paths:
  /items:
    get:
      summary: Retrieve a list of items
      security:
        - bearerAuth: []
      parameters:
        - name: X-Custom-Header
          in: header
          required: true
          description: Custom header for request
          schema:
            type: string
      responses:
        "200":
          description: A list of items
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

Then I called an OPTIONS request to the /items path.

What did you expect to see?

There are headers Authorization, X-Custom-Header and Content-Type in the Access-Control-Allow-Headers header of the OPTIONS response for /items

What did you see instead?

The only CORS-allowed header is Content-Type image

Probable cause

It seems like the Access-Control-Allow-Headers is hardcoded in the template gen/_template/cfg.tmpl:

...
MethodNotAllowed: func(w http.ResponseWriter, r *http.Request, allowed string) {
			status := http.StatusMethodNotAllowed
			if r.Method == "OPTIONS" {
				w.Header().Set("Access-Control-Allow-Methods", allowed)
				w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
				status = http.StatusNoContent
			} else {
				w.Header().Set("Allow", allowed)
			}
			w.WriteHeader(status)
		},
...

It can currently be mitigated by either setting this header in the reverse proxy or redefining the MethodNotAllowed function using ServerOptions.

I propose an addition to the signature of this function to include not only allowed methods but also allowed headers.

Russia9 avatar Oct 02 '24 22:10 Russia9

You can override default handler via WithMethodNotAllowed option. https://github.com/ogen-go/ogen/blob/4182357878201caf52384c2acd887b44d02a3a1f/gen/_template/cfg.tmpl#L258-L265

ghost avatar Oct 03 '24 03:10 ghost