summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRose Hogenson <rosehogenson@posteo.net>2025-11-30 20:46:47 -0800
committerRose Hogenson <rosehogenson@posteo.net>2025-11-30 20:46:47 -0800
commit1a71a5985f3116c138f4acc4613e8e29982e38f5 (patch)
treebc3447970e65dd54471b74a3f0ed5214e2558ccb
parent7335cf0aa21c597a311dedf8d893094ad196a0f8 (diff)
downloadroseh.moe-1a71a5985f3116c138f4acc4613e8e29982e38f5.tar.zst
Use built-in cross-origin protection
-rw-r--r--roseh.moe.go78
-rw-r--r--templates/note.html.template1
2 files changed, 20 insertions, 59 deletions
diff --git a/roseh.moe.go b/roseh.moe.go
index 3d357fd..6d1ccea 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -421,42 +421,6 @@ func cookieAuth(w http.ResponseWriter, r *http.Request) bool {
return true
}
-const csrfCookieName = "roseh.moe.csrf-token"
-
-func reqCSRFToken(w http.ResponseWriter, r *http.Request) string {
- const csrfTokenLen = 32
- if csrfCookie, err := r.Cookie(csrfCookieName); err == nil {
- return csrfCookie.Value
- } else {
- buf := make([]byte, csrfTokenLen)
- rand.Read(buf)
- csrfToken := base64.RawURLEncoding.EncodeToString(buf)
- http.SetCookie(w, &http.Cookie{
- Name: csrfCookieName,
- Value: csrfToken,
- Path: "/",
- Secure: true,
- HttpOnly: true,
- SameSite: http.SameSiteStrictMode,
- Partitioned: true,
- })
- return csrfToken
- }
-}
-
-func checkCSRFToken(r *http.Request) error {
- cookie, err := r.Cookie(csrfCookieName)
- if err != nil {
- return err
- }
- cookieHash := sha256.Sum256([]byte(cookie.Value))
- formValueHash := sha256.Sum256([]byte(r.FormValue("csrf-token")))
- if subtle.ConstantTimeCompare(cookieHash[:], formValueHash[:]) == 0 {
- return fmt.Errorf("bad CSRF token")
- }
- return nil
-}
-
func checkPassword(password string) bool {
const pwHashSize = targetSecurityLevel
hash := sha256.Sum256([]byte(password))
@@ -529,8 +493,7 @@ var (
)
type notepadTemplateArgs struct {
- Content string
- CSRFToken string
+ Content string
}
func notepad(w http.ResponseWriter, r *http.Request) {
@@ -541,15 +504,12 @@ func notepad(w http.ResponseWriter, r *http.Request) {
notepadContentsMu.Lock()
currentContent := notepadContents
notepadContentsMu.Unlock()
- if err := notepadTemplate.Execute(w, notepadTemplateArgs{Content: currentContent, CSRFToken: reqCSRFToken(w, r)}); err != nil {
+ if err := notepadTemplate.Execute(w, notepadTemplateArgs{Content: currentContent}); err != nil {
log.Printf("Warning: notepad: %s", err)
}
}
func saveNote(w http.ResponseWriter, r *http.Request) error {
- if err := checkCSRFToken(r); err != nil {
- return err
- }
if !cookieAuth(w, r) {
return fmt.Errorf("not logged in")
}
@@ -625,22 +585,24 @@ func main() {
log.Fatal(err)
}
- http.HandleFunc("GET /pong", pong)
- http.HandleFunc("GET /wormhole", newWormhole)
- http.HandleFunc("GET /wormhole/{hole}/upload", wormhole)
- http.HandleFunc("POST /wormhole/{hole}/upload", wormholeSend)
- http.HandleFunc("GET /wormhole/{hole}", wormholeRecv)
- http.HandleFunc("GET /wormhole/{hole}/qr.png", wormholeQR)
- http.HandleFunc("GET /login", serveLogin)
- http.HandleFunc("POST /login", login)
- http.HandleFunc("GET /notepad", notepad)
- http.HandleFunc("POST /notepad", autosave)
- http.HandleFunc("GET /cmd/{cmd}", cmd)
- http.HandleFunc("GET /pkg/{pkg}", pkg)
- http.HandleFunc("GET /static/", static)
- http.HandleFunc("GET /favicon.ico", favicon)
- http.HandleFunc("GET /{$}", index)
- http.HandleFunc("GET /", notFound)
+ mux := http.NewServeMux()
+ mux.HandleFunc("GET /pong", pong)
+ mux.HandleFunc("GET /wormhole", newWormhole)
+ mux.HandleFunc("GET /wormhole/{hole}/upload", wormhole)
+ mux.HandleFunc("POST /wormhole/{hole}/upload", wormholeSend)
+ mux.HandleFunc("GET /wormhole/{hole}", wormholeRecv)
+ mux.HandleFunc("GET /wormhole/{hole}/qr.png", wormholeQR)
+ mux.HandleFunc("GET /login", serveLogin)
+ mux.HandleFunc("POST /login", login)
+ mux.HandleFunc("GET /notepad", notepad)
+ mux.HandleFunc("POST /notepad", autosave)
+ mux.HandleFunc("GET /cmd/{cmd}", cmd)
+ mux.HandleFunc("GET /pkg/{pkg}", pkg)
+ mux.HandleFunc("GET /static/", static)
+ mux.HandleFunc("GET /favicon.ico", favicon)
+ mux.HandleFunc("GET /{$}", index)
+ mux.HandleFunc("GET /", notFound)
+ http.Handle("/", http.NewCrossOriginProtection().Handler(mux))
jellyfinURL, err := url.Parse("http://127.0.0.1:8096")
if err != nil {
log.Fatal(err)
diff --git a/templates/note.html.template b/templates/note.html.template
index 07c2d8e..19da416 100644
--- a/templates/note.html.template
+++ b/templates/note.html.template
@@ -6,7 +6,6 @@
{{end}}
<form id="form" method="post">
- <input type="hidden" name="csrf-token" value="{{.CSRFToken}}">
<div class="save-indicator-container">
{{block "saveIndicator" ""}}
<span id="save-indicator">{{.}}</span>