fix: encrypt the cookie in sessions

This commit is contained in:
Stavros
2025-07-04 01:08:17 +03:00
parent 7640e956c2
commit ebcf6e6aa6
4 changed files with 61 additions and 5 deletions

View File

@@ -33,7 +33,7 @@ type Auth struct {
func (auth *Auth) GetSession(c *gin.Context) (*sessions.Session, error) {
// Create cookie store
store := sessions.NewCookieStore([]byte(auth.Config.Secret))
store := sessions.NewCookieStore([]byte(auth.Config.HMACSecret), []byte(auth.Config.EncryptionSecret))
// Configure cookie store
store.Options = &sessions.Options{
@@ -46,9 +46,21 @@ func (auth *Auth) GetSession(c *gin.Context) (*sessions.Session, error) {
// Get session
session, err := store.Get(c.Request, auth.Config.SessionCookieName)
if err != nil {
log.Error().Err(err).Msg("Failed to get session")
return nil, err
log.Warn().Err(err).Msg("Invalid session, clearing cookie and retrying")
// Delete the session cookie if there is an error
c.SetCookie(auth.Config.SessionCookieName, "", -1, "/", auth.Config.Domain, auth.Config.CookieSecure, true)
// Try to get the session again
session, err = store.Get(c.Request, auth.Config.SessionCookieName)
if err != nil {
// If we still can't get the session, log the error and return nil
log.Error().Err(err).Msg("Failed to get session")
return nil, err
}
}
return session, nil

View File

@@ -80,12 +80,13 @@ type AuthConfig struct {
Users Users
OauthWhitelist string
SessionExpiry int
Secret string
CookieSecure bool
Domain string
LoginTimeout int
LoginMaxRetries int
SessionCookieName string
HMACSecret string
EncryptionSecret string
}
// HooksConfig is the configuration for the hooks service

View File

@@ -1,8 +1,11 @@
package utils
import (
"bytes"
"crypto/sha256"
"encoding/base64"
"errors"
"io"
"net"
"net/url"
"os"
@@ -11,6 +14,7 @@ import (
"tinyauth/internal/types"
"github.com/traefik/paerser/parser"
"golang.org/x/crypto/hkdf"
"github.com/google/uuid"
"github.com/rs/zerolog/log"
@@ -405,3 +409,32 @@ func FilterIP(filter string, ip string) (bool, error) {
// If the filter is not a CIDR range or a single IP, return false
return false, nil
}
func DeriveKey(secret string, info string) (string, error) {
// Create hashing function
hash := sha256.New
// Create a new key using the secret and info
hkdf := hkdf.New(hash, []byte(secret), nil, []byte(info)) // I am not using a salt because I just want two different keys from one secret, maybe bad practice
// Create a new key
key := make([]byte, 32)
// Read the key from the HKDF
_, err := io.ReadFull(hkdf, key)
if err != nil {
return "", err
}
// Verify the key is not empty
if bytes.Equal(key, make([]byte, 32)) {
return "", errors.New("derived key is empty")
}
// Encode the key to base64
encodedKey := base64.StdEncoding.EncodeToString(key)
// Return the key as a base64 encoded string
return encodedKey[:32], nil
}