dchest / captcha

Go package captcha implements generation and verification of image and audio CAPTCHAs.
godoc.org/github.com/dchest/captcha
MIT License
1.92k stars 293 forks source link

Security issue: Can't set custom security headers #22

Closed iu4u57k3 closed 5 years ago

iu4u57k3 commented 5 years ago

We can setup a captcha server by using: http.Handle("/captcha/", captcha.Server(captcha.StdWidth, captcha.StdHeight)

However, this does not allow setting custom headers for enhancing security such as:

Access-Control-Allow-Origin
X-Frame-Options
X-Content-Type-Options
X-XSS-Protection

This leaves the application vulnerable to various attacks

dchest commented 5 years ago

Server is the standard Go http.Handler, so you can combine it with other http.Handler or http.HandlerFunc to set headers before calling it. For example,

    captchaServer := captcha.Server(captcha.StdWidth, captcha.StdHeight)

    http.HandleFunc("/captcha/", func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("X-My-Header", "itworks")
        captchaServer.ServeHTTP(w, r)
    })

All of the headers you listed seem useless, though:

Anything I missed?

Since captcha URLs are unguessable by design, other origins would not be able to embed them into their pages. However you should protect your HTML page that display captchas with X-Content-Type-Options and X-Frame-Options so that other origins won't be able to embed it into iframe so that people solve your captchas on unrelated to your website. (They still can, of course, run it server-side, so I'm not sure if that's much of the help).

iu4u57k3 commented 5 years ago

Thanks for your clarification!

iu4u57k3 commented 5 years ago

It will be a good idea to add w.Header().Set("X-Frame-Options", "DENY") in captcha.serve function. So there will be no need to add custom headers.

dchest commented 5 years ago

captcha.Serve serves images and audio, so X-Frame-Options: deny is useless for it as mentioned above: they can be embedded with <img src="..." and <audio src="..." without using iframe. However, since the image URL is unguessable, without knowing captcha id, attackers will not be able to take advantage of it.