Skip to content
Merged
Changes from 1 commit
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