summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.eu>2024-02-14 15:58:16 +0100
committerRené 'Necoro' Neumann <necoro@necoro.eu>2024-02-14 15:58:16 +0100
commit6544171b7a6eb2e0156b66a1ad4c58d3a6cacd86 (patch)
treec1ce0edd527024e8e03f113b0fb00c05cdfc37bc
parent3194896b33500bab959147bac38ab4fb93dd55bb (diff)
downloadgosten-6544171b7a6eb2e0156b66a1ad4c58d3a6cacd86.tar.gz
gosten-6544171b7a6eb2e0156b66a1ad4c58d3a6cacd86.tar.bz2
gosten-6544171b7a6eb2e0156b66a1ad4c58d3a6cacd86.zip
CSRF handling
-rw-r--r--auth.go5
-rw-r--r--csrf.go27
-rw-r--r--go.mod1
-rw-r--r--go.sum2
-rw-r--r--main.go2
-rw-r--r--templ/login.tpl1
6 files changed, 36 insertions, 2 deletions
diff --git a/auth.go b/auth.go
index 14cd6d7..7be1c1e 100644
--- a/auth.go
+++ b/auth.go
@@ -106,6 +106,7 @@ type User struct {
Password string `form:"type=password;options=required"`
RememberMe bool `form:"type=checkbox;value=y;options=checked"`
Errors []error `form:"-"`
+ Csrf
}
func showLoginPage(w http.ResponseWriter, u User) {
@@ -117,7 +118,9 @@ func loginPage() http.HandlerFunc {
if session(r).Authenticated {
http.Redirect(w, r, "/", http.StatusFound)
}
- showLoginPage(w, User{})
+ showLoginPage(w, User{
+ Csrf: CsrfField(r),
+ })
}
}
diff --git a/csrf.go b/csrf.go
new file mode 100644
index 0000000..962a2a0
--- /dev/null
+++ b/csrf.go
@@ -0,0 +1,27 @@
+package main
+
+import (
+ "html/template"
+ "net/http"
+
+ "github.com/gorilla/csrf"
+ "github.com/gorilla/securecookie"
+)
+
+func csrfHandler(next http.Handler) http.Handler {
+ return csrf.Protect(
+ securecookie.GenerateRandomKey(32),
+ csrf.SameSite(csrf.SameSiteStrictMode),
+ csrf.FieldName("csrf.csrffield"), // should match the structure in `Csrf`
+ )(next)
+}
+
+// Csrf handles the CSRF data for a form.
+// Include it verbatim and then use `{{.CsrfField}}` in templates.
+type Csrf struct {
+ CsrfField template.HTML `form:"-"`
+}
+
+func CsrfField(r *http.Request) Csrf {
+ return Csrf{CsrfField: csrf.TemplateField(r)}
+}
diff --git a/go.mod b/go.mod
index afdfe50..e2d4b2e 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.22
require (
github.com/Necoro/form v0.0.0-20240211223301-6fa9f8196e1e
github.com/go-sql-driver/mysql v1.7.1
+ github.com/gorilla/csrf v1.7.2
github.com/gorilla/handlers v1.5.2
github.com/gorilla/schema v1.2.1
github.com/gorilla/securecookie v1.1.2
diff --git a/go.sum b/go.sum
index 2b48e8d..ccc5424 100644
--- a/go.sum
+++ b/go.sum
@@ -16,6 +16,8 @@ github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbu
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/gorilla/csrf v1.7.2 h1:oTUjx0vyf2T+wkrx09Trsev1TE+/EbDAeHtSTbtC2eI=
+github.com/gorilla/csrf v1.7.2/go.mod h1:F1Fj3KG23WYHE6gozCmBAezKookxbIvUJT+121wTuLk=
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
github.com/gorilla/schema v1.2.1 h1:tjDxcmdb+siIqkTNoV+qRH2mjYdr2hHe5MKXbp61ziM=
diff --git a/main.go b/main.go
index 20200c3..38bfd93 100644
--- a/main.go
+++ b/main.go
@@ -45,7 +45,7 @@ func main() {
mux.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("static"))))
mux.Handle("/favicon.ico", http.NotFoundHandler())
- handler := sessionHandler(mux)
+ handler := sessionHandler(csrfHandler(mux))
handler = handlers.CombinedLoggingHandler(os.Stderr, handler)
handler = handlers.ProxyHeaders(handler)
diff --git a/templ/login.tpl b/templ/login.tpl
index d704365..205b030 100644
--- a/templ/login.tpl
+++ b/templ/login.tpl
@@ -1,6 +1,7 @@
{{define "body"}}
<form action="/login" method="post">
{{inputs_and_errors_for . .Errors}}
+ {{.CsrfField}}
<button type="submit">Log In!</button>
</form>
{{end}} \ No newline at end of file