Merge pull request #59 from mutantmonkey/csp_referrer_fix
fix CSP referrer policy
This commit is contained in:
commit
ff1d9f56a1
@ -25,8 +25,8 @@ Command-line options
|
||||
- ```-maxsize 4294967296``` maximum upload file size in bytes (default 4GB)
|
||||
- ```-certfile path/to/your.crt``` -- Path to the ssl certificate (required if you want to use the https server)
|
||||
- ```-keyfile path/to/your.key``` -- Path to the ssl key (required if you want to use the https server)
|
||||
- ```-contentsecuritypolicy "..."``` -- Content-Security-Policy header for pages (default is "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; referrer none;")
|
||||
- ```-filecontentsecuritypolicy "..."``` -- Content-Security-Policy header for files (default is "default-src 'none'; img-src 'self'; object-src 'self'; media-src 'self'; sandbox; referrer none;"")
|
||||
- ```-contentsecuritypolicy "..."``` -- Content-Security-Policy header for pages (default is "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; referrer origin;")
|
||||
- ```-filecontentsecuritypolicy "..."``` -- Content-Security-Policy header for files (default is "default-src 'none'; img-src 'self'; object-src 'self'; media-src 'self'; sandbox; referrer origin;"")
|
||||
- ```-xframeoptions "..." ``` -- X-Frame-Options header (default is "SAMEORIGIN")
|
||||
- ```-remoteuploads``` -- (optionally) enable remote uploads (/upload?url=https://...)
|
||||
- ```-realip``` -- (optionally) let linx-server know you (nginx, etc) are providing the X-Real-IP and/or X-Forwarded-For headers.
|
||||
|
12
csrf.go
12
csrf.go
@ -6,17 +6,19 @@ import (
|
||||
)
|
||||
|
||||
func strictReferrerCheck(r *http.Request, prefix string, whitelistHeaders []string) bool {
|
||||
p := strings.TrimSuffix(prefix, "/")
|
||||
if origin := r.Header.Get("Origin"); origin != "" {
|
||||
// if there's an Origin header, check it and ignore the rest
|
||||
return strings.HasPrefix(origin, p)
|
||||
}
|
||||
|
||||
for _, header := range whitelistHeaders {
|
||||
if r.Header.Get(header) != "" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if referrer := r.Header.Get("Referer"); !strings.HasPrefix(referrer, prefix) {
|
||||
return false
|
||||
}
|
||||
|
||||
if origin := r.Header.Get("Origin"); origin != "" && !strings.HasPrefix(origin, strings.TrimSuffix(prefix, "/")) {
|
||||
if referrer := r.Header.Get("Referer"); !strings.HasPrefix(referrer, p) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,8 @@ func fileServeHandler(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
if !Config.allowHotlink {
|
||||
referer := r.Header.Get("Referer")
|
||||
if referer != "" && !strings.HasPrefix(referer, Config.siteURL) {
|
||||
prefix := strings.TrimSuffix(Config.siteURL, "/")
|
||||
if referer != "" && !strings.HasPrefix(referer, prefix) {
|
||||
w.WriteHeader(403)
|
||||
return
|
||||
}
|
||||
|
5
pages.go
5
pages.go
@ -86,7 +86,10 @@ func oopsHandler(c web.C, w http.ResponseWriter, r *http.Request, rt RespType, m
|
||||
|
||||
func badRequestHandler(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
err := Templates["400.html"].ExecuteWriter(pongo2.Context{}, w)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func unauthorizedHandler(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -184,10 +184,10 @@ func main() {
|
||||
flag.StringVar(&Config.remoteAuthFile, "remoteauthfile", "",
|
||||
"path to a file containing newline-separated scrypted auth keys for remote uploads")
|
||||
flag.StringVar(&Config.contentSecurityPolicy, "contentsecuritypolicy",
|
||||
"default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; referrer none;",
|
||||
"default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; referrer origin;",
|
||||
"value of default Content-Security-Policy header")
|
||||
flag.StringVar(&Config.fileContentSecurityPolicy, "filecontentsecuritypolicy",
|
||||
"default-src 'none'; img-src 'self'; object-src 'self'; media-src 'self'; sandbox; referrer none;",
|
||||
"default-src 'none'; img-src 'self'; object-src 'self'; media-src 'self'; sandbox; referrer origin;",
|
||||
"value of Content-Security-Policy header for file access")
|
||||
flag.StringVar(&Config.xFrameOptions, "xframeoptions", "SAMEORIGIN",
|
||||
"value of X-Frame-Options header")
|
||||
|
@ -45,8 +45,9 @@ func populateTemplatesMap(tSet *pongo2.TemplateSet, tMap map[string]*pongo2.Temp
|
||||
"index.html",
|
||||
"paste.html",
|
||||
"API.html",
|
||||
"404.html",
|
||||
"400.html",
|
||||
"401.html",
|
||||
"404.html",
|
||||
"oops.html",
|
||||
|
||||
"display/audio.html",
|
||||
|
5
templates/400.html
Normal file
5
templates/400.html
Normal file
@ -0,0 +1,5 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
400 Bad Request
|
||||
{% endblock %}
|
@ -46,7 +46,7 @@ type Upload struct {
|
||||
}
|
||||
|
||||
func uploadPostHandler(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||
if !strictReferrerCheck(r, Config.siteURL, []string{"Linx-Delete-Key", "Linx-Expiry", "Linx-Randomize"}) {
|
||||
if !strictReferrerCheck(r, Config.siteURL, []string{"Linx-Delete-Key", "Linx-Expiry", "Linx-Randomize", "X-Requested-With"}) {
|
||||
badRequestHandler(c, w, r)
|
||||
return
|
||||
}
|
||||
@ -145,7 +145,7 @@ func uploadRemote(c web.C, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
} else {
|
||||
// strict referrer checking is mandatory without remote auth keys
|
||||
if !strictReferrerCheck(r, Config.siteURL, []string{"Linx-Delete-Key", "Linx-Expiry", "Linx-Randomize"}) {
|
||||
if !strictReferrerCheck(r, Config.siteURL, []string{"Linx-Delete-Key", "Linx-Expiry", "Linx-Randomize", "X-Requested-With"}) {
|
||||
badRequestHandler(c, w, r)
|
||||
return
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user