-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmiddleware.go
74 lines (65 loc) · 3.4 KB
/
middleware.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package main
import (
"encoding/base64"
"net/http"
"golang.org/x/crypto/bcrypt"
"github.com/labstack/echo/v4"
)
// BasicAuth returns an HTTP basic authentication middleware.
//
// For valid credentials it calls the next handler.
// For invalid credentials, it sends "401 - Unauthorized" response.
const (
Basic = "Basic"
)
func BasicAuth(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
auth := c.Request().Header.Get(echo.HeaderAuthorization)
l := len(Basic)
if len(auth) > l+1 && auth[:l] == Basic {
b, err := base64.StdEncoding.DecodeString(auth[l+1:])
if err == nil {
cred := string(b)
for i := 0; i < len(cred); i++ {
if cred[i] == ':' {
// Verify credentials
for _, d := range conf.Domains {
if cred[:i] == d.Name && bcrypt.CompareHashAndPassword([]byte(d.PassHash), []byte(cred[i+1:])) == nil {
c.Set("domain", d)
err := next(c)
if err != nil {
c.Error(err)
}
return err
}
}
}
}
}
}
c.Response().Header().Set(echo.HeaderWWWAuthenticate, Basic+" realm=Restricted")
return echo.NewHTTPError(http.StatusUnauthorized)
}
}
func SecurityHeaders(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
h := c.Response().Header()
// every security header apart from HSTS
h.Set(echo.HeaderContentSecurityPolicy,
"default-src 'self'; img-src 'self' data: 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; base-uri 'self'",
)
h.Set(echo.HeaderXFrameOptions, "\"SAMEORIGIN\" always")
h.Set(echo.HeaderXXSSProtection, "\"1; mode=block\" always")
h.Set(echo.HeaderXContentTypeOptions, "\"nosniff\" always")
h.Set(echo.HeaderReferrerPolicy, "no-referrer-when-downgrade")
h.Set("Feature-Policy",
"accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; fullscreen 'none'; geolocation 'none'; gyroscope 'none'; layout-animations 'none'; legacy-image-formats 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; oversized-images 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; sync-xhr 'none'; usb 'none'; vr 'none'; wake-lock 'none'; screen-wake-lock 'none'; web-share 'none'; xr-spatial-tracking 'none'; notifications 'none'; push 'none'; speaker 'none'; vibrate 'none'; payment 'none'")
h.Set("Permissions-Policy",
"accelerometer=(), ambient-light-sensor=(), autoplay=(), battery=(), camera=(), cross-origin-isolated=(), display-capture=(), document-domain=(), encrypted-media=(), execution-while-not-rendered=(), execution-while-out-of-viewport=(), fullscreen=(), geolocation=(), gyroscope=(), magnetometer=(), microphone=(), midi=(), navigation-override=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), speaker-selection=(), conversion-measurement=(), focus-without-user-activation=(), hid=(), idle-detection=(), serial=(), sync-script=(), trust-token-redemption=(), vertical-scroll=(), notifications=(), push=(), speaker=(), vibrate=(), interest-cohort=()")
err := next(c)
if err != nil {
c.Error(err)
}
return nil
}
}