feature (signature): protect url param via signature

This commit is contained in:
MickaelK 2025-01-15 01:09:53 +11:00
parent e9870f72f2
commit f1b1d71f40
3 changed files with 39 additions and 8 deletions

View file

@ -106,6 +106,7 @@ func NewConfiguration() Configuration {
Elmnts: []FormElement{
FormElement{Name: "iframe", Type: "text", Default: "", Description: "list of domains who can use the application from an iframe. eg: https://www.filestash.app http://example.com"},
FormElement{Name: "enable_chromecast", Type: "boolean", Default: true, Description: "Enable users to stream content on a chromecast device. This feature requires the browser to access google's server to download the chromecast SDK."},
FormElement{Name: "signature", Type: "text", Default: "", Description: "Enforce signature when using URL parameters in the authentication process"},
},
},
},

View file

@ -56,14 +56,15 @@ func init() {
}
var (
BUILD_REF string
BUILD_DATE string
LICENSE string = "agpl"
SECRET_KEY string
SECRET_KEY_DERIVATE_FOR_PROOF string
SECRET_KEY_DERIVATE_FOR_ADMIN string
SECRET_KEY_DERIVATE_FOR_USER string
SECRET_KEY_DERIVATE_FOR_HASH string
BUILD_REF string
BUILD_DATE string
LICENSE string = "agpl"
SECRET_KEY string
SECRET_KEY_DERIVATE_FOR_PROOF string
SECRET_KEY_DERIVATE_FOR_ADMIN string
SECRET_KEY_DERIVATE_FOR_USER string
SECRET_KEY_DERIVATE_FOR_HASH string
SECRET_KEY_DERIVATE_FOR_SIGNATURE string
)
/*
@ -76,6 +77,7 @@ func InitSecretDerivate(secret string) {
SECRET_KEY_DERIVATE_FOR_ADMIN = Hash("ADMIN_"+SECRET_KEY, len(SECRET_KEY))
SECRET_KEY_DERIVATE_FOR_USER = Hash("USER_"+SECRET_KEY, len(SECRET_KEY))
SECRET_KEY_DERIVATE_FOR_HASH = Hash("HASH_"+SECRET_KEY, len(SECRET_KEY))
SECRET_KEY_DERIVATE_FOR_SIGNATURE = Hash("SGN_"+SECRET_KEY, len(SECRET_KEY))
}
var base = os.Getenv("FILESTASH_BASE")

View file

@ -8,6 +8,7 @@ import (
"net/http"
"net/url"
"os"
"slices"
"strings"
"text/template"
"time"
@ -351,6 +352,33 @@ func SessionAuthMiddleware(ctx *App, res http.ResponseWriter, req *http.Request)
if decodedState, err := base64.StdEncoding.DecodeString(state); err == nil {
stateStruct := map[string]string{}
json.Unmarshal(decodedState, &stateStruct)
// check variables are "legit"
attributes := ""
signature := ""
fields := strings.Split(Config.Get("features.protection.signature").String(), ",")
for k, v := range stateStruct {
if k == "signature" {
signature = v
}
if slices.Contains(fields, k) {
attributes += fmt.Sprintf("%s[%s] ", k, v)
}
}
attributes = strings.TrimSpace(attributes)
v, err := DecryptString(SECRET_KEY_DERIVATE_FOR_SIGNATURE, signature)
if err != nil || attributes != v {
v, _ = EncryptString(SECRET_KEY_DERIVATE_FOR_SIGNATURE, attributes)
Log.Debug("callback signature is required, signature=%s", v)
http.Redirect(
res, req,
WithBase("/?error=Invalid%20Signature&trace=signature is not correct"),
http.StatusTemporaryRedirect,
)
return
}
// populate variable
for key, value := range stateStruct {
if templateBind[key] != "" {
continue