Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"bytes"
"context"
"crypto/subtle"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To support a more robust constant-time comparison that avoids leaking the token length, the "crypto/sha256" package is required.

Suggested change
"crypto/subtle"
"crypto/sha256"
"crypto/subtle"

"database/sql"
"encoding/base64"
"encoding/json"
Expand Down Expand Up @@ -124,7 +125,8 @@ func (s *server) GetHealth() http.HandlerFunc {
func (s *server) authadmin(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if token != *adminToken {
// Constant-time compare to avoid timing-attack leak of admin token bytes.
if subtle.ConstantTimeCompare([]byte(token), []byte(*adminToken)) != 1 {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

While subtle.ConstantTimeCompare prevents byte-by-byte timing leaks, it still leaks the length of the adminToken because it returns immediately if the lengths of the two slices differ. A more robust approach is to compare the SHA-256 hashes of both tokens. Since hashes have a fixed length, this eliminates the length side-channel. For even better performance, the hash of the expected adminToken could be precomputed at startup.

Suggested change
if subtle.ConstantTimeCompare([]byte(token), []byte(*adminToken)) != 1 {
tokenHash := sha256.Sum256([]byte(token))
adminHash := sha256.Sum256([]byte(*adminToken))
if subtle.ConstantTimeCompare(tokenHash[:], adminHash[:]) != 1 {

s.Respond(w, r, http.StatusUnauthorized, errors.New("unauthorized"))
return
}
Expand Down
Loading