summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--roseh.moe.go108
-rw-r--r--templates/login.html.template1
-rw-r--r--templates/note.html.template1
3 files changed, 32 insertions, 78 deletions
diff --git a/roseh.moe.go b/roseh.moe.go
index 481da6b..1783a03 100644
--- a/roseh.moe.go
+++ b/roseh.moe.go
@@ -371,63 +371,31 @@ func attachCookie(w http.ResponseWriter) error {
return nil
}
-func cookieAuth(w http.ResponseWriter, r *http.Request) (string, bool) {
- const csrfTokenLen = 32
- var csrfToken string
- if csrfCookie, err := r.Cookie("csrf-token"); err == nil {
- csrfToken = csrfCookie.Value
- } else {
- buf := make([]byte, csrfTokenLen)
- rand.Read(buf)
- csrfToken = base64.RawURLEncoding.EncodeToString(buf)
- http.SetCookie(w, &http.Cookie{
- Name: "csrf-token",
- Value: csrfToken,
- Path: "/",
- Secure: true,
- HttpOnly: true,
- SameSite: http.SameSiteStrictMode,
- Partitioned: true,
- })
- }
-
+func cookieAuth(w http.ResponseWriter, r *http.Request) bool {
cookie, err := r.Cookie("auth")
if err != nil {
- return csrfToken, false
+ return false
}
authCookie, err := base64.RawURLEncoding.DecodeString(cookie.Value)
if err != nil {
- return csrfToken, false
+ return false
}
msg, ok := verify(authCookie)
if !ok {
- return csrfToken, false
+ return false
}
var t time.Time
if err := t.UnmarshalBinary(msg); err != nil {
- return csrfToken, false
+ return false
}
cookieAge := time.Since(t)
if cookieAge > cookieExpiration {
- return csrfToken, false
+ return false
}
if cookieAge > 24*time.Hour {
attachCookie(w)
}
- return csrfToken, true
-}
-
-func checkCSRFToken(r *http.Request) error {
- cookie, err := r.Cookie("csrf-token")
- 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
+ return true
}
func checkPassword(password string) bool {
@@ -443,26 +411,18 @@ var (
)
type loginTemplateArgs struct {
- CSRFToken string
- Error bool
+ Error bool
}
-func executeLoginTemplate(w io.Writer, csrfToken string) {
- if err := loginTemplate.Execute(w, loginTemplateArgs{CSRFToken: csrfToken}); err != nil {
+func executeLoginTemplate(w io.Writer) {
+ if err := loginTemplate.Execute(w, loginTemplateArgs{}); err != nil {
log.Printf("Warning: login: %s", err)
}
}
func login(w http.ResponseWriter, r *http.Request) {
- if err := checkCSRFToken(r); err != nil {
- http.Error(w, "bad CSRF token", http.StatusBadRequest)
- return
- }
if !checkPassword(r.FormValue("password")) {
- if err := loginTemplate.Execute(w, loginTemplateArgs{
- Error: true,
- CSRFToken: r.FormValue("csrf-token"),
- }); err != nil {
+ if err := loginTemplate.Execute(w, loginTemplateArgs{Error: true}); err != nil {
log.Printf("Warning: login: %s", err)
}
return
@@ -481,29 +441,24 @@ var (
)
type notepadTemplateArgs struct {
- Content string
- CSRFToken string
+ Content string
}
func notepad(w http.ResponseWriter, r *http.Request) {
- csrfToken, ok := cookieAuth(w, r)
- if !ok {
- executeLoginTemplate(w, csrfToken)
+ if !cookieAuth(w, r) {
+ executeLoginTemplate(w)
return
}
notepadContentsMu.Lock()
currentContent := notepadContents
notepadContentsMu.Unlock()
- if err := notepadTemplate.Execute(w, notepadTemplateArgs{Content: currentContent, CSRFToken: csrfToken}); 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 _, ok := cookieAuth(w, r); !ok {
+ if !cookieAuth(w, r) {
return fmt.Errorf("not logged in")
}
newContent := r.FormValue("content")
@@ -566,22 +521,23 @@ func main() {
log.Fatal(err)
}
- http.HandleFunc("GET /pong", pong)
- http.HandleFunc("GET /wormhole", wormhole)
- http.HandleFunc("POST /wormhole/{hole}", wormholeSend)
- http.HandleFunc("GET /wormhole/{hole}", wormholeRecv)
- http.HandleFunc("GET /wormhole/{hole}/ready", wormholeReady)
- 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", wormhole)
+ mux.HandleFunc("POST /wormhole/{hole}", wormholeSend)
+ mux.HandleFunc("GET /wormhole/{hole}", wormholeRecv)
+ mux.HandleFunc("GET /wormhole/{hole}/ready", wormholeReady)
+ 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)
addr := fmt.Sprintf(":%d", *port)
log.Printf("Listening on %q", addr)
- log.Fatal(http.ListenAndServe(addr, nil))
+ log.Fatal(http.ListenAndServe(addr, http.NewCrossOriginProtection().Handler(mux)))
}
diff --git a/templates/login.html.template b/templates/login.html.template
index f08caf7..0cf3469 100644
--- a/templates/login.html.template
+++ b/templates/login.html.template
@@ -5,7 +5,6 @@
<p class="login-error">Incorrect password</p>
{{end}}
<form class="password-form" action="/login" method="post">
- <input type="hidden" name="csrf-token" value="{{.CSRFToken}}">
<label class="password-label" for="password">Enter password</label>
<input id="password" class="password" type="password" name="password" autofocus>
</form>
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>