secure HTTP headers
CSP, frame, XSS, etc.
This commit is contained in:
parent
94b90af504
commit
0ec0a97855
1 changed files with 34 additions and 12 deletions
46
http.go
46
http.go
|
@ -16,6 +16,7 @@ import (
|
||||||
|
|
||||||
rice "github.com/GeertJohan/go.rice"
|
rice "github.com/GeertJohan/go.rice"
|
||||||
"github.com/c2h5oh/datasize"
|
"github.com/c2h5oh/datasize"
|
||||||
|
"github.com/unrolled/secure"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MegaUploader acts as controller for all the application. Since this is inherently a web-focused
|
// MegaUploader acts as controller for all the application. Since this is inherently a web-focused
|
||||||
|
@ -23,11 +24,21 @@ import (
|
||||||
type MegaUploader struct {
|
type MegaUploader struct {
|
||||||
Conf Config
|
Conf Config
|
||||||
configLock *sync.RWMutex
|
configLock *sync.RWMutex
|
||||||
|
secureMW *secure.Secure
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewMegaUploader create a new mega uploader
|
// NewMegaUploader create a new mega uploader
|
||||||
func NewMegaUploader(c Config) MegaUploader {
|
func NewMegaUploader(c Config) MegaUploader {
|
||||||
return MegaUploader{Conf: c, configLock: new(sync.RWMutex)}
|
return MegaUploader{
|
||||||
|
Conf: c,
|
||||||
|
configLock: new(sync.RWMutex),
|
||||||
|
secureMW: secure.New(secure.Options{
|
||||||
|
FrameDeny: true,
|
||||||
|
ContentTypeNosniff: true,
|
||||||
|
BrowserXssFilter: true,
|
||||||
|
ContentSecurityPolicy: "default-src 'self'",
|
||||||
|
}),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mu *MegaUploader) ChangeConf(newconf Config) {
|
func (mu *MegaUploader) ChangeConf(newconf Config) {
|
||||||
|
@ -37,27 +48,37 @@ func (mu *MegaUploader) ChangeConf(newconf Config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// confAcquire is a middleware to read-lock configuration
|
// confAcquire is a middleware to read-lock configuration
|
||||||
func (mu *MegaUploader) confAcquire(inner func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
|
func (mu *MegaUploader) confAcquire(inner http.Handler) http.Handler {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
f := func(w http.ResponseWriter, r *http.Request) {
|
||||||
mu.configLock.RLock()
|
mu.configLock.RLock()
|
||||||
inner(w, r)
|
inner.ServeHTTP(w, r)
|
||||||
mu.configLock.RUnlock()
|
mu.configLock.RUnlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return http.HandlerFunc(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mu *MegaUploader) privateMiddleware(inner func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
return mu.secureMW.Handler(mu.confAcquire(requireUserMiddleware(inner))).ServeHTTP
|
||||||
|
}
|
||||||
|
func (mu *MegaUploader) publicMiddleware(inner func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
return mu.secureMW.Handler(requireUserMiddleware(inner)).ServeHTTP
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetupRoutes adds API routes
|
// SetupRoutes adds API routes
|
||||||
func (mu *MegaUploader) SetupRoutes() {
|
func (mu *MegaUploader) SetupRoutes() {
|
||||||
|
|
||||||
prefix := strings.TrimRight(mu.Conf.Global.RoutePrefix, "/")
|
prefix := strings.TrimRight(mu.Conf.Global.RoutePrefix, "/")
|
||||||
|
|
||||||
http.HandleFunc(prefix+"/", mu.confAcquire(requireUserMiddleware(mu.home)))
|
http.HandleFunc(prefix+"/", mu.privateMiddleware(mu.home))
|
||||||
http.HandleFunc(prefix+"/upload/", mu.confAcquire(requireUserMiddleware(mu.uploadUI)))
|
http.HandleFunc(prefix+"/upload/", mu.privateMiddleware(mu.uploadUI))
|
||||||
static := rice.MustFindBox("res/static")
|
static := rice.MustFindBox("res/static")
|
||||||
http.HandleFunc(prefix+"/static/", requireUserMiddleware(
|
http.HandleFunc(prefix+"/static/", mu.publicMiddleware(
|
||||||
http.StripPrefix(prefix+"/static/", http.FileServer(static.HTTPBox())).ServeHTTP,
|
http.StripPrefix(prefix+"/static/", http.FileServer(static.HTTPBox())).ServeHTTP,
|
||||||
))
|
))
|
||||||
http.HandleFunc(prefix+"/api/share", mu.confAcquire(requireUserMiddleware(mu.listShares)))
|
http.HandleFunc(prefix+"/api/share", mu.privateMiddleware(mu.listShares))
|
||||||
http.HandleFunc(prefix+"/api/share/", mu.confAcquire(requireUserMiddleware(mu.getShare)))
|
http.HandleFunc(prefix+"/api/share/", mu.privateMiddleware(mu.getShare))
|
||||||
http.HandleFunc(prefix+"/api/upload/", mu.confAcquire(requireUserMiddleware(mu.upload)))
|
http.HandleFunc(prefix+"/api/upload/", mu.privateMiddleware(mu.upload))
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUser(r *http.Request) (string, error) {
|
func getUser(r *http.Request) (string, error) {
|
||||||
|
@ -68,8 +89,8 @@ func getUser(r *http.Request) (string, error) {
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func requireUserMiddleware(inner func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
|
func requireUserMiddleware(inner func(w http.ResponseWriter, r *http.Request)) http.Handler {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
f := func(w http.ResponseWriter, r *http.Request) {
|
||||||
_, err := getUser(r)
|
_, err := getUser(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "Only logged-in users are authorized", http.StatusUnauthorized)
|
http.Error(w, "Only logged-in users are authorized", http.StatusUnauthorized)
|
||||||
|
@ -77,6 +98,7 @@ func requireUserMiddleware(inner func(w http.ResponseWriter, r *http.Request)) f
|
||||||
}
|
}
|
||||||
inner(w, r)
|
inner(w, r)
|
||||||
}
|
}
|
||||||
|
return http.HandlerFunc(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mu *MegaUploader) listShares(w http.ResponseWriter, r *http.Request) {
|
func (mu *MegaUploader) listShares(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
Loading…
Reference in a new issue