Better implementation of CORS.
This commit is contained in:
@@ -109,9 +109,8 @@ The fields are as follows:
|
|||||||
- `writableGroups`: if true, then the API can modify group description
|
- `writableGroups`: if true, then the API can modify group description
|
||||||
files; by default, group files are treated as read-only;
|
files; by default, group files are treated as read-only;
|
||||||
|
|
||||||
- `publicServer`: if true, then cross-origin access to the server is
|
- `allowOrigin` is an array that contains the list of HTTP origins that
|
||||||
allowed. This makes the server vulnerable to cross-origin scripting
|
are allowed to access the server.
|
||||||
attacks, but is necessary in some cases.
|
|
||||||
|
|
||||||
- `proxyURL`: if running behind a reverse proxy, this specifies the root
|
- `proxyURL`: if running behind a reverse proxy, this specifies the root
|
||||||
URL that will be visible outside the proxy.
|
URL that will be visible outside the proxy.
|
||||||
|
|||||||
+6
-5
@@ -916,11 +916,12 @@ type Configuration struct {
|
|||||||
modTime time.Time `json:"-"`
|
modTime time.Time `json:"-"`
|
||||||
fileSize int64 `json:"-"`
|
fileSize int64 `json:"-"`
|
||||||
|
|
||||||
PublicServer bool `json:"publicServer"`
|
CanonicalHost string `json:"canonicalHost"`
|
||||||
CanonicalHost string `json:"canonicalHost"`
|
AllowOrigin []string `json:"allowOrigin"`
|
||||||
ProxyURL string `json:"proxyURL"`
|
AllowAdminOrigin []string `json:"allowAdminOrigin"`
|
||||||
WritableGroups bool `json:"writableGroups"`
|
ProxyURL string `json:"proxyURL"`
|
||||||
Users map[string]UserDescription
|
WritableGroups bool `json:"writableGroups"`
|
||||||
|
Users map[string]UserDescription
|
||||||
|
|
||||||
// obsolete fields
|
// obsolete fields
|
||||||
Admin []ClientPattern `json:"admin"`
|
Admin []ClientPattern `json:"admin"`
|
||||||
|
|||||||
+44
-15
@@ -502,29 +502,58 @@ func failAuthentication(w http.ResponseWriter, realm string) {
|
|||||||
http.Error(w, "Haha!", http.StatusUnauthorized)
|
http.Error(w, "Haha!", http.StatusUnauthorized)
|
||||||
}
|
}
|
||||||
|
|
||||||
var wsUpgrader = websocket.Upgrader{
|
func CheckOrigin(w http.ResponseWriter, r *http.Request, admin bool) bool {
|
||||||
HandshakeTimeout: 30 * time.Second,
|
if w != nil {
|
||||||
|
w.Header().Add("Vary", "Origin")
|
||||||
|
}
|
||||||
|
|
||||||
|
origins := r.Header["Origin"]
|
||||||
|
if len(origins) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
origin := origins[0]
|
||||||
|
|
||||||
|
ok := false
|
||||||
|
o, err := url.Parse(origin)
|
||||||
|
if err == nil && strings.EqualFold(o.Host, r.Host) {
|
||||||
|
ok = true
|
||||||
|
} else {
|
||||||
|
conf, err := group.GetConfiguration()
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
allow := conf.AllowOrigin
|
||||||
|
if admin {
|
||||||
|
allow = conf.AllowAdminOrigin
|
||||||
|
}
|
||||||
|
for _, a := range allow {
|
||||||
|
if strings.EqualFold(origin, a) {
|
||||||
|
ok = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if w != nil {
|
||||||
|
w.Header().Add("Access-Control-Allow-Origin", origin)
|
||||||
|
}
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
var wsPublicUpgrader = websocket.Upgrader{
|
var wsUpgrader = websocket.Upgrader{
|
||||||
HandshakeTimeout: 30 * time.Second,
|
HandshakeTimeout: 30 * time.Second,
|
||||||
CheckOrigin: func(r *http.Request) bool {
|
CheckOrigin: func(r *http.Request) bool {
|
||||||
return true
|
return CheckOrigin(nil, r, false)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func wsHandler(w http.ResponseWriter, r *http.Request) {
|
func wsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
conf, err := group.GetConfiguration()
|
conn, err := wsUpgrader.Upgrade(w, r, nil)
|
||||||
if err != nil {
|
|
||||||
httpError(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
upgrader := wsUpgrader
|
|
||||||
if conf.PublicServer {
|
|
||||||
upgrader = wsPublicUpgrader
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := upgrader.Upgrade(w, r, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Websocket upgrade: %v", err)
|
log.Printf("Websocket upgrade: %v", err)
|
||||||
return
|
return
|
||||||
|
|||||||
+2
-18
@@ -165,15 +165,7 @@ func whipEndpointHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
conf, err := group.GetConfiguration()
|
CheckOrigin(w, r, false)
|
||||||
if err != nil {
|
|
||||||
httpError(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if conf.PublicServer {
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Method == "OPTIONS" {
|
if r.Method == "OPTIONS" {
|
||||||
w.Header().Set("Access-Control-Allow-Methods", "OPTIONS, POST")
|
w.Header().Set("Access-Control-Allow-Methods", "OPTIONS, POST")
|
||||||
@@ -309,15 +301,7 @@ func whipResourceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
conf, err := group.GetConfiguration()
|
CheckOrigin(w, r, false)
|
||||||
if err != nil {
|
|
||||||
httpError(w, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if conf.PublicServer {
|
|
||||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
|
||||||
}
|
|
||||||
|
|
||||||
if r.Method == "OPTIONS" {
|
if r.Method == "OPTIONS" {
|
||||||
w.Header().Set("Access-Control-Allow-Methods",
|
w.Header().Set("Access-Control-Allow-Methods",
|
||||||
|
|||||||
Reference in New Issue
Block a user