Add CSRF checks to boards and threads.

jocadbz
Joca 2026-03-06 14:51:54 -03:00
parent 48363ccef9
commit 82a7e48827
Signed by: jocadbz
GPG Key ID: B1836DCE2F50BDF7
6 changed files with 23 additions and 2 deletions

View File

@ -58,6 +58,11 @@ func BoardHandler(app *App) http.HandlerFunc {
if r.Method == http.MethodPost && loggedIn {
action := r.URL.Query().Get("action")
if action == "create_thread" {
if !app.validateCSRFToken(r, session) {
http.Error(w, "Invalid CSRF token", http.StatusForbidden)
return
}
title := r.FormValue("title")
if title == "" {
http.Error(w, "Thread title is required", http.StatusBadRequest)
@ -118,6 +123,7 @@ func BoardHandler(app *App) http.HandlerFunc {
BasePath: app.Config.ThreadrDir,
StaticPath: app.Config.ThreadrDir + "/static",
CurrentURL: r.URL.RequestURI(),
CSRFToken: app.csrfToken(session),
},
Board: *board,
Threads: threads,

View File

@ -26,6 +26,11 @@ func BoardsHandler(app *App) http.HandlerFunc {
}
if r.Method == http.MethodPost && loggedIn && isAdmin {
if !app.validateCSRFToken(r, session) {
http.Error(w, "Invalid CSRF token", http.StatusForbidden)
return
}
name := r.FormValue("name")
description := r.FormValue("description")
boardType := r.FormValue("type")
@ -106,6 +111,7 @@ func BoardsHandler(app *App) http.HandlerFunc {
BasePath: app.Config.ThreadrDir,
StaticPath: app.Config.ThreadrDir + "/static",
CurrentURL: r.URL.RequestURI(),
CSRFToken: app.csrfToken(session),
},
PublicBoards: publicBoards,
PrivateBoards: privateBoards,

View File

@ -59,6 +59,11 @@ func ThreadHandler(app *App) http.HandlerFunc {
if r.Method == http.MethodPost && loggedIn {
action := r.URL.Query().Get("action")
if action == "submit" {
if !app.validateCSRFToken(r, session) {
http.Error(w, "Invalid CSRF token", http.StatusForbidden)
return
}
content := r.FormValue("content")
replyToStr := r.FormValue("reply_to")
if replyToStr == "" {
@ -164,6 +169,7 @@ func ThreadHandler(app *App) http.HandlerFunc {
BasePath: app.Config.ThreadrDir,
StaticPath: app.Config.ThreadrDir + "/static",
CurrentURL: r.URL.RequestURI(),
CSRFToken: app.csrfToken(session),
},
Thread: *thread,
Board: *board,

View File

@ -40,6 +40,7 @@
<section>
<h3>Create New Thread</h3>
<form method="post" action="{{.BasePath}}/board/?id={{.Board.ID}}&action=create_thread">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<label for="title">Thread Title:</label>
<input type="text" id="title" name="title" required maxlength="255"><br>
<input type="submit" value="Create Thread">
@ -50,4 +51,4 @@
{{template "cookie_banner" .}}
</body>
</html>
{{end}}
{{end}}

View File

@ -56,6 +56,7 @@
<section>
<h3>Create New Public Board</h3>
<form method="post" action="{{.BasePath}}/boards/">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<label for="name">Board Name:</label>
<input type="text" id="name" name="name" required maxlength="255"><br>
<label for="description">Description:</label>
@ -73,4 +74,4 @@
{{template "cookie_banner" .}}
</body>
</html>
{{end}}
{{end}}

View File

@ -62,6 +62,7 @@
<button type="button" onclick="clearReply()">x</button>
</div>
<form method="post" action="{{.BasePath}}/thread/?id={{.Thread.ID}}&action=submit" id="reply-form">
<input type="hidden" name="csrf_token" value="{{.CSRFToken}}">
<input type="hidden" id="reply-to-input" name="reply_to" value="">
<label for="content">Content:</label>
<textarea id="content" name="content" required></textarea><br>