From 1a01147a956a9aa513a20b2c9a977a77e63fa833 Mon Sep 17 00:00:00 2001 From: zarzet Date: Wed, 1 Jul 2026 02:03:14 +0700 Subject: [PATCH] fix(extensions): scope signed session files by endpoint and app context Hash session cache paths from namespace, base URL, app version, and platform so credentials do not leak across environments, and invalidate stored sessions when that scope changes. --- go_backend/extension_signed_session.go | 49 +++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/go_backend/extension_signed_session.go b/go_backend/extension_signed_session.go index 2796f45d..5a64f920 100644 --- a/go_backend/extension_signed_session.go +++ b/go_backend/extension_signed_session.go @@ -34,6 +34,10 @@ type signedSessionRecord struct { SessionID string `json:"session_id,omitempty"` SessionSecret string `json:"session_secret,omitempty"` ExpiresAt string `json:"expires_at,omitempty"` + Namespace string `json:"namespace,omitempty"` + BaseURL string `json:"base_url,omitempty"` + AppVersion string `json:"app_version,omitempty"` + Platform string `json:"platform,omitempty"` } type signedSessionExchangeResponse struct { @@ -93,7 +97,14 @@ func (r *extensionRuntime) signedSessionFilePath(config SignedSessionConfig) (st if err := os.MkdirAll(dir, 0700); err != nil { return "", err } - return filepath.Join(dir, namespace+".json"), nil + scope := strings.Join([]string{ + namespace, + strings.TrimSpace(strings.ToLower(config.BaseURL)), + strings.TrimSpace(strings.ToLower(config.AppVersion)), + strings.TrimSpace(strings.ToLower(config.Platform)), + }, "\n") + sum := sha256.Sum256([]byte(scope)) + return filepath.Join(dir, namespace+"-"+hex.EncodeToString(sum[:])[:16]+".json"), nil } func sanitizeSignedSessionNamespace(namespace string) string { @@ -118,13 +129,40 @@ func (r *extensionRuntime) loadSignedSession(config SignedSessionConfig) (*signe } if strings.TrimSpace(record.InstallID) == "" { record.InstallID = randomHex(16) - if err := r.saveSignedSession(config, record); err != nil { - return nil, err - } + } + normalizeSignedSessionRecordScope(config, record) + if err := r.saveSignedSession(config, record); err != nil { + return nil, err } return record, nil } +func normalizeSignedSessionRecordScope(config SignedSessionConfig, record *signedSessionRecord) { + namespace := sanitizeSignedSessionNamespace(config.Namespace) + baseURL := strings.TrimSpace(config.BaseURL) + appVersion := strings.TrimSpace(config.AppVersion) + platform := strings.TrimSpace(config.Platform) + if record.Namespace == "" && record.BaseURL == "" && record.AppVersion == "" && record.Platform == "" { + record.Namespace = namespace + record.BaseURL = baseURL + record.AppVersion = appVersion + record.Platform = platform + return + } + if record.Namespace != namespace || + record.BaseURL != baseURL || + record.AppVersion != appVersion || + record.Platform != platform { + record.SessionID = "" + record.SessionSecret = "" + record.ExpiresAt = "" + } + record.Namespace = namespace + record.BaseURL = baseURL + record.AppVersion = appVersion + record.Platform = platform +} + func (r *extensionRuntime) saveSignedSession(config SignedSessionConfig, record *signedSessionRecord) error { path, err := r.signedSessionFilePath(config) if err != nil { @@ -180,6 +218,9 @@ func (r *extensionRuntime) signedSessionStatus(call goja.FunctionCall) goja.Valu "authenticated": authenticated, "expires_at": record.ExpiresAt, "install_id": record.InstallID, + "session_id": record.SessionID, + "app_version": config.AppVersion, + "platform": config.Platform, }) }