added CSRF

This commit is contained in:
Philipp 2021-08-29 16:55:23 +02:00
parent a06e8db2ff
commit 5c7d92f4f3
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG key ID: 276B613AF9DBE9C3
10 changed files with 42 additions and 6 deletions

View file

@ -14,6 +14,7 @@ func main() {
log.Fatal(err) log.Fatal(err)
} }
h := web.NewHandler(store) csrfKey := []byte("dmwij82jda92jf9a202na#d2.e3i!824")
h := web.NewHandler(store, csrfKey)
http.ListenAndServe(":3000", h) http.ListenAndServe(":3000", h)
} }

1
go.mod
View file

@ -5,6 +5,7 @@ go 1.16
require ( require (
github.com/go-chi/chi v1.5.4 // indirect github.com/go-chi/chi v1.5.4 // indirect
github.com/google/uuid v1.3.0 // direct github.com/google/uuid v1.3.0 // direct
github.com/gorilla/csrf v1.7.1 // indirect
github.com/jmoiron/sqlx v1.3.4 // indirect github.com/jmoiron/sqlx v1.3.4 // indirect
github.com/lib/pq v1.10.2 // indirect github.com/lib/pq v1.10.2 // indirect
) )

6
go.sum
View file

@ -9,6 +9,10 @@ github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIu
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= 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/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/csrf v1.7.1 h1:Ir3o2c1/Uzj6FBxMlAUB6SivgVMy1ONXwYgXn+/aHPE=
github.com/gorilla/csrf v1.7.1/go.mod h1:+a/4tCmqhG6/w4oafeAZ9pEa3/NZOWYVbD9fV0FwIQA=
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w= github.com/jmoiron/sqlx v1.3.4 h1:wv+0IJZfL5z0uZoUjlpKgHkgaFSYD+r9CfrXjEXsO7w=
github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= github.com/jmoiron/sqlx v1.3.4/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
@ -22,5 +26,7 @@ github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/ogier/pflag v0.0.1 h1:RW6JSWSu/RkSatfcLtogGfFgpim5p7ARQ10ECk5O750= github.com/ogier/pflag v0.0.1 h1:RW6JSWSu/RkSatfcLtogGfFgpim5p7ARQ10ECk5O750=
github.com/ogier/pflag v0.0.1/go.mod h1:zkFki7tvTa0tafRvTBIZTvzYyAu6kQhPZFnshFFPE+g= github.com/ogier/pflag v0.0.1/go.mod h1:zkFki7tvTa0tafRvTBIZTvzYyAu6kQhPZFnshFFPE+g=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e h1:o3PsSEY8E4eXWkXrIP9YJALUkVZqzHJT5DOasTyn8Vs=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

View file

@ -19,6 +19,7 @@
<div class="card mb-4"> <div class="card mb-4">
<div class="text-right"> <div class="text-right">
<form action="/threads/{{.Thread.ID}}/{{.Post.ID}}" method="POST"> <form action="/threads/{{.Thread.ID}}/{{.Post.ID}}" method="POST">
{{.CSRF}}
<textarea name="content" class="form-control border-0 border-bottom-1 p-3" <textarea name="content" class="form-control border-0 border-bottom-1 p-3"
placeholder="What are your thoughts?" rows="4"></textarea> placeholder="What are your thoughts?" rows="4"></textarea>
<div class="border-top p-1"> <div class="border-top p-1">

View file

@ -6,6 +6,7 @@
{{define "content"}} {{define "content"}}
<form action=/threads/{{.Thread.ID}} method="POST"> <form action=/threads/{{.Thread.ID}} method="POST">
{{.CSRF}}
<div class="form-group"> <div class="form-group">
<label>Title</label> <label>Title</label>
<input name="title" type="text" class="form-control" placeholder="Give your post a great title"> <input name="title" type="text" class="form-control" placeholder="Give your post a great title">

View file

@ -39,6 +39,7 @@
</div> </div>
<div class="text-center"> <div class="text-center">
<form action=/threads/{{.Thread.ID}}/delete method="POST"> <form action=/threads/{{.Thread.ID}}/delete method="POST">
{{.CSRF}}
<button type="submit" class="text-danger btn-sm btn btn-link">Delete this thread</button> <button type="submit" class="text-danger btn-sm btn btn-link">Delete this thread</button>
</form> </form>
</div> </div>

View file

@ -4,6 +4,7 @@
{{define "content"}} {{define "content"}}
<form action="/threads" method="POST"> <form action="/threads" method="POST">
{{.CSRF}}
<div class="form-group"> <div class="form-group">
<label>Title</label> <label>Title</label>
<input name="title" type="text" class="form-control" placeholder="Give your thread a great title"> <input name="title" type="text" class="form-control" placeholder="Give your thread a great title">

View file

@ -7,9 +7,10 @@ import (
"git.snrd.de/Spaenny/goddit" "git.snrd.de/Spaenny/goddit"
"github.com/go-chi/chi" "github.com/go-chi/chi"
"github.com/go-chi/chi/middleware" "github.com/go-chi/chi/middleware"
"github.com/gorilla/csrf"
) )
func NewHandler(store goddit.Store) *Handler { func NewHandler(store goddit.Store, csrfKey []byte) *Handler {
h := &Handler{ h := &Handler{
Mux: chi.NewMux(), Mux: chi.NewMux(),
store: store, store: store,
@ -20,6 +21,7 @@ func NewHandler(store goddit.Store) *Handler {
comments := CommentHandler{store: store} comments := CommentHandler{store: store}
h.Use(middleware.Logger) h.Use(middleware.Logger)
h.Use(csrf.Protect(csrfKey, csrf.Secure(false)))
h.Get("/", h.Home()) h.Get("/", h.Home())
h.Route("/threads", func(r chi.Router) { h.Route("/threads", func(r chi.Router) {

View file

@ -7,6 +7,7 @@ import (
"git.snrd.de/Spaenny/goddit" "git.snrd.de/Spaenny/goddit"
"github.com/go-chi/chi" "github.com/go-chi/chi"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/gorilla/csrf"
) )
type PostHandler struct { type PostHandler struct {
@ -15,6 +16,7 @@ type PostHandler struct {
func (h *PostHandler) Create() http.HandlerFunc { func (h *PostHandler) Create() http.HandlerFunc {
type data struct { type data struct {
CSRF template.HTML
Thread goddit.Thread Thread goddit.Thread
} }
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/post_create.html")) tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/post_create.html"))
@ -33,12 +35,16 @@ func (h *PostHandler) Create() http.HandlerFunc {
return return
} }
tmpl.Execute(w, data{Thread: t}) tmpl.Execute(w, data{
CSRF: csrf.TemplateField(r),
Thread: t,
})
} }
} }
func (h *PostHandler) Show() http.HandlerFunc { func (h *PostHandler) Show() http.HandlerFunc {
type data struct { type data struct {
CSRF template.HTML
Thread goddit.Thread Thread goddit.Thread
Post goddit.Post Post goddit.Post
Comments []goddit.Comment Comments []goddit.Comment
@ -78,7 +84,12 @@ func (h *PostHandler) Show() http.HandlerFunc {
return return
} }
tmpl.Execute(w, data{Thread: t, Post: p, Comments: cc}) tmpl.Execute(w, data{
CSRF: csrf.TemplateField(r),
Thread: t,
Post: p,
Comments: cc,
})
} }
} }

View file

@ -7,6 +7,7 @@ import (
"git.snrd.de/Spaenny/goddit" "git.snrd.de/Spaenny/goddit"
"github.com/go-chi/chi" "github.com/go-chi/chi"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/gorilla/csrf"
) )
type ThreadHandler struct { type ThreadHandler struct {
@ -31,14 +32,20 @@ func (h *ThreadHandler) List() http.HandlerFunc {
} }
func (h *ThreadHandler) Create() http.HandlerFunc { func (h *ThreadHandler) Create() http.HandlerFunc {
type data struct {
CSRF template.HTML
}
tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/thread_create.html")) tmpl := template.Must(template.ParseFiles("templates/layout.html", "templates/thread_create.html"))
return func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) {
tmpl.Execute(w, nil) tmpl.Execute(w, data{
CSRF: csrf.TemplateField(r),
})
} }
} }
func (h *ThreadHandler) Show() http.HandlerFunc { func (h *ThreadHandler) Show() http.HandlerFunc {
type data struct { type data struct {
CSRF template.HTML
Thread goddit.Thread Thread goddit.Thread
Posts []goddit.Post Posts []goddit.Post
} }
@ -61,7 +68,11 @@ func (h *ThreadHandler) Show() http.HandlerFunc {
http.Error(w, err.Error(), http.StatusInternalServerError) http.Error(w, err.Error(), http.StatusInternalServerError)
return return
} }
tmpl.Execute(w, data{Thread: t, Posts: pp}) tmpl.Execute(w, data{
CSRF: csrf.TemplateField(r),
Thread: t,
Posts: pp,
})
} }
} }