-
Notifications
You must be signed in to change notification settings - Fork 0
Various Changes #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
d5f3bbb
9a8c0bd
cb1dabe
d3681b9
0ec3c84
330d8fe
0759334
35222de
1f5837c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,10 @@ | ||
| module github.com/advania/pass | ||
| module github.com/Gunni/pass | ||
|
|
||
| go 1.12 | ||
| go 1.22 | ||
|
|
||
| require ( | ||
| github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 | ||
| github.com/google/go-cmp v0.3.0 // indirect | ||
| github.com/lib/pq v1.1.1 | ||
| github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is only one caller that uses this library, to parse HTTP |
||
| github.com/lib/pq v1.10.9 | ||
| ) | ||
|
|
||
| require github.com/google/go-cmp v0.3.0 // indirect | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,54 @@ | ||
| github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721 h1:KRMr9A3qfbVM7iV/WcLY/rL5LICqwMHLhwRXKu99fXw= | ||
| github.com/golang/gddo v0.0.0-20190419222130-af0f2af80721/go.mod h1:xEhNfoBDX1hzLm2Nf80qUvZ2sVwoMZ8d6IE2SrsQfh4= | ||
| cloud.google.com/go v0.16.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= | ||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||
| github.com/bradfitz/gomemcache v0.0.0-20170208213004-1952afaa557d/go.mod h1:PmM6Mmwb0LSuEubjR8N7PtNe1KxZLtOUHtbeikc5h60= | ||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
| github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||
| github.com/fsnotify/fsnotify v1.4.3-0.20170329110642-4da3e2cfbabc/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | ||
| github.com/garyburd/redigo v1.1.1-0.20170914051019-70e1b1943d4f/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= | ||
| github.com/go-stack/stack v1.6.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= | ||
| github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f h1:16RtHeWGkJMc80Etb8RPCcKevXGldr57+LOyZt8zOlg= | ||
| github.com/golang/gddo v0.0.0-20210115222349-20d68f94ee1f/go.mod h1:ijRvpgDJDI262hYq/IQVYgf8hd8IHUs93Ol0kvMBAx4= | ||
| github.com/golang/lint v0.0.0-20170918230701-e5d664eb928e/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E= | ||
| github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||
| github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= | ||
| github.com/google/go-cmp v0.1.1-0.20171103154506-982329095285/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | ||
| github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY= | ||
| github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= | ||
| github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= | ||
| github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | ||
| github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY= | ||
| github.com/gregjones/httpcache v0.0.0-20170920190843-316c5e0ff04e/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= | ||
| github.com/hashicorp/hcl v0.0.0-20170914154624-68e816d1c783/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= | ||
| github.com/inconshreveable/log15 v0.0.0-20170622235902-74a0988b5f80/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= | ||
| github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= | ||
| github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||
| github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||
| github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= | ||
| github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= | ||
| github.com/magiconair/properties v1.7.4-0.20170902060319-8d7837e64d3c/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= | ||
| github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= | ||
| github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= | ||
| github.com/mitchellh/mapstructure v0.0.0-20170523030023-d0303fe80992/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= | ||
| github.com/pelletier/go-toml v1.0.1-0.20170904195809-1d6b12b7cb29/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= | ||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||
| github.com/spf13/afero v0.0.0-20170901052352-ee1bd8ee15a1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= | ||
| github.com/spf13/cast v1.1.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= | ||
| github.com/spf13/jwalterweatherman v0.0.0-20170901151539-12bd96e66386/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= | ||
| github.com/spf13/pflag v1.0.1-0.20170901120850-7aff26db30c1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||
| github.com/spf13/viper v1.0.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= | ||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
| golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | ||
| golang.org/x/oauth2 v0.0.0-20170912212905-13449ad91cb2/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||
| golang.org/x/sync v0.0.0-20170517211232-f52d1811a629/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||
| golang.org/x/time v0.0.0-20170424234030-8be79e1e0910/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||
| golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||
| google.golang.org/api v0.0.0-20170921000349-586095a6e407/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= | ||
| google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= | ||
| google.golang.org/genproto v0.0.0-20170918111702-1e559d0a00ee/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= | ||
| google.golang.org/grpc v1.2.1-0.20170921194603-d4b75ebd4f9f/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= | ||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
| gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,7 +19,7 @@ import ( | |
| "strings" | ||
| "time" | ||
|
|
||
| "github.com/advania/pass/helpers" | ||
| "github.com/Gunni/pass/helpers" | ||
|
|
||
| "github.com/lib/pq" | ||
| ) | ||
|
|
@@ -30,6 +30,7 @@ type passConfiguration struct { | |
| File string | ||
| Key string | ||
| } | ||
| ContentSecurityPolicyOverride string | ||
| HSTS struct { | ||
| MaxAge int | ||
| IncludeSubDomains bool | ||
|
|
@@ -84,7 +85,7 @@ var contentSecurityPolicyHTML = strings.Join([]string{ | |
| "form-action 'self';", | ||
| "frame-ancestors 'none';", | ||
| "block-all-mixed-content;", | ||
| "sandbox allow-scripts allow-forms allow-same-origin;", | ||
| "sandbox allow-scripts allow-forms allow-popups allow-same-origin;", | ||
| "require-sri-for script style;", | ||
| "base-uri 'none';", | ||
| }, " ") | ||
|
|
@@ -98,27 +99,6 @@ var contentSecurityPolicyJSON = strings.Join([]string{ | |
| "base-uri 'none';", | ||
| }, " ") | ||
|
|
||
| var featurePolicy = strings.Join([]string{ | ||
| "accelerometer 'none';", | ||
| "ambient-light-sensor 'none';", | ||
| "autoplay 'none';", | ||
| "camera 'none';", | ||
| "encrypted-media 'none';", | ||
| "fullscreen 'none';", | ||
| "geolocation 'none';", | ||
| "gyroscope 'none';", | ||
| "magnetometer 'none';", | ||
| "microphone 'none';", | ||
| "midi 'none';", | ||
| "payment 'none';", | ||
| "picture-in-picture 'none';", | ||
| "speaker 'none';", | ||
| "sync-xhr 'none';", | ||
| "sync-script 'none';", | ||
| "usb 'none';", | ||
| "vr 'none';", | ||
| }, " ") | ||
|
|
||
| // generateSecurityHeaders generates the http securityHeaders to be outputted | ||
| // as http headers before every request | ||
| func (p *Pass) generateSecurityHeaders() { | ||
|
|
@@ -133,7 +113,6 @@ func (p *Pass) generateSecurityHeaders() { | |
| } | ||
|
|
||
| p.sv.securityHeaders["Access-Control-Allow-Origin"] = p.GetURL() | ||
| p.sv.securityHeaders["Feature-Policy"] = featurePolicy | ||
| p.sv.securityHeaders["Referrer-Policy"] = "no-referrer" | ||
| p.sv.securityHeaders["X-Content-Type-Options"] = "nosniff" | ||
| p.sv.securityHeaders["X-Frame-Options"] = "deny" | ||
|
|
@@ -373,11 +352,16 @@ func (p *Pass) OutputHeaders(rw http.ResponseWriter, r *http.Request) { | |
| rw.Header().Set(key, value) | ||
| } | ||
|
|
||
| // More restrictive CSP for json requests | ||
| if helpers.HTTPAcceptCheck("application/json", r.Header) { | ||
| rw.Header().Set("Content-Security-Policy", contentSecurityPolicyJSON) | ||
| if p.sv.cfg.ContentSecurityPolicyOverride == "" { | ||
| // More restrictive CSP for json requests | ||
| if helpers.HTTPAcceptCheck("application/json", r.Header) { | ||
| rw.Header().Set("Content-Security-Policy", contentSecurityPolicyJSON) | ||
| } else { | ||
| rw.Header().Set("Content-Security-Policy", contentSecurityPolicyHTML) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We got two policies, one for JSON and another for HTML, yet only one uniformally applied override? How about we use only one for the default as well? |
||
| } | ||
| } else { | ||
| rw.Header().Set("Content-Security-Policy", contentSecurityPolicyHTML) | ||
| // Allow config to override the CSP | ||
| rw.Header().Set("Content-Security-Policy", p.sv.cfg.ContentSecurityPolicyOverride) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -524,34 +508,37 @@ func onBeforeRequest(rv *requestVariables) { | |
|
|
||
| func handler(p *Pass, rv *requestVariables) { | ||
| if rv.r.Method == http.MethodGet { | ||
| switch rv.path[0] { | ||
| case "favicon.ico": | ||
| p.serveStatic(rv, "static/favicon.ico", "image/x-icon") | ||
| return | ||
| case "css": | ||
| p.serveStatic(rv, "static/css.css", "text/css") | ||
| return | ||
| case "js": | ||
| p.serveStatic(rv, "static/js.js", "application/javascript") | ||
| return | ||
| case "logo": | ||
| p.serveStatic(rv, "static/logo_header.png", "image/png") | ||
| return | ||
| case "robots.txt": | ||
| rv.w.Header().Set("Content-Type", "text/plain") | ||
| rv.w.Header().Set("Cache-Control", "max-age=2592000") // 30 days | ||
| rv.w.Write([]byte("User-agent: *\nDisallow: /")) | ||
| return | ||
| case "ping": | ||
| rv.w.Header().Set("Cache-Control", "max-age=0") | ||
| // Takes ~42 seconds if db is unresponsive, use it to check for it using client side js | ||
| // https://github.com/lib/pq/issues/620 | ||
| // returns HTTP 500 if server can be instantly detected as being down | ||
| if err := rv.sv.db.ping(); err != nil { | ||
| log.Printf("db.Ping() returned %v\n", err) | ||
| rv.w.WriteHeader(http.StatusInternalServerError) | ||
| if len(rv.path) == 1 { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reduce indentation. if len(rv.path) != 1 {
return
}And move this and the switch into a new helper function. |
||
| // All the below paths are length 1, prevent handling /logo/asdf as if /logo was used | ||
| switch rv.path[0] { | ||
| case "favicon.ico": | ||
| p.serveStatic(rv, "static/favicon.ico", "image/x-icon") | ||
| return | ||
| case "css": | ||
| p.serveStatic(rv, "static/css.css", "text/css") | ||
| return | ||
| case "js": | ||
| p.serveStatic(rv, "static/js.js", "application/javascript") | ||
| return | ||
| case "logo": | ||
| p.serveStatic(rv, "static/logo_header.png", "image/png") | ||
| return | ||
| case "robots.txt": | ||
| rv.w.Header().Set("Content-Type", "text/plain") | ||
| rv.w.Header().Set("Cache-Control", "max-age=2592000") // 30 days | ||
| rv.w.Write([]byte("User-agent: *\nDisallow: /")) | ||
| return | ||
| case "ping": | ||
| rv.w.Header().Set("Cache-Control", "max-age=0") | ||
| // Takes ~42 seconds if db is unresponsive, use it to check for it using client side js | ||
| // https://github.com/lib/pq/issues/620 | ||
| // returns HTTP 500 if server can be instantly detected as being down | ||
| if err := rv.sv.db.ping(); err != nil { | ||
| log.Printf("db.Ping() returned %v\n", err) | ||
| rv.w.WriteHeader(http.StatusInternalServerError) | ||
| } | ||
| return | ||
| } | ||
| return | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -652,7 +639,7 @@ func loadConfig(configFileName string) (cfg passConfiguration, err error) { | |
| } | ||
|
|
||
| if len(cfg.Secret) < 64 { | ||
| return cfg, fmt.Errorf("Site secret shorter than 64 characters, please make it at least 64 characters") | ||
| return cfg, fmt.Errorf("%s 'Secret' shorter than 64 characters, please make it at least 64 characters", configFileName) | ||
| } | ||
|
|
||
| return cfg, nil | ||
|
|
@@ -784,6 +771,10 @@ func Main(pass *Pass) { | |
| fmt.Printf("Main program: %s\n", mainApp) | ||
| fmt.Printf("Wrapped by: %s\n", wrapper) | ||
|
|
||
| if sv.cfg.ContentSecurityPolicyOverride != "" { | ||
| fmt.Printf("NOTE: Content-Security-Policy override applied for all requests: %s\n", sv.cfg.ContentSecurityPolicyOverride) | ||
| } | ||
|
|
||
| // goroutine that runs forever checking the state of the database connection | ||
| // This can not run in the normal process flow because of a bug in the pq | ||
| // module, it is not possible to cancel a query with a timeout | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,32 +1,35 @@ | ||
| { | ||
| "Certificate": { | ||
| "File": "your.crt", | ||
| "Key": "your.key" | ||
| }, | ||
| "HSTS": { | ||
| "MaxAge": 63072000, | ||
| "IncludeSubDomains": false, | ||
| "Preload": false | ||
| }, | ||
| "Hostname": "pass.example.com", | ||
| "ListenAddress": "[::1]:4443", | ||
| "PDOString": "host=pass.example.com. port=5432 dbname=passwords user=password_frontend", | ||
| "Secret": "a good 64+ character site secret", | ||
| "PasswordLength": { | ||
| "Min": 6, | ||
| "Max": 10000 | ||
| }, | ||
| "TemplatePath": "templates", | ||
| "Title": "Advania Pass", | ||
| "TrustedProxies": [], | ||
| "TrustedProxyIPHeader": "", | ||
| "Addons": { | ||
| "email": { | ||
| "Server": "relay.example.com:smtp", | ||
| "Sender": { | ||
| "Address": "test@example.com", | ||
| "Name": "Example" | ||
| } | ||
| } | ||
| } | ||
| "Addons": { | ||
| "email": { | ||
| "Sender": { | ||
| "Address": "todo@example.com", | ||
| "Name": "Pass" | ||
| }, | ||
| "Server": "todo.example.com" | ||
| } | ||
| }, | ||
| "ContentSecurityPolicyOverride": "", | ||
| "Certificate": { | ||
| "File": "cert.crt", | ||
| "Key": "cert.key" | ||
| }, | ||
| "HSTS": { | ||
| "MaxAge": 9000001, | ||
| "IncludeSubdomains": false, | ||
| "Preload": false | ||
| }, | ||
| "Hostname": "pass.example.com", | ||
| "ListenAddress": "[::]:4443", | ||
| "PDOString": "postgres://password_frontend@localhost/passwords?sslmode=disable", | ||
| "Secret": "example: dd if=/dev/random bs=128 count=1 | base64 -w0 ; echo", | ||
| "PasswordLength": { | ||
| "Min": 20, | ||
| "Max": 1024 | ||
| }, | ||
| "MinEntryLength": 2048, | ||
| "SecretDays": 7, | ||
| "Title": "Pass", | ||
| "TemplatePath": "templates", | ||
| "TrustedProxies": [], | ||
| "TrustedProxyIPHeader": "" | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps change
set -oeu pipefailtoset -oeux pipefail?