mirror of https://github.com/minio/minio.git
				
				
				
			
		
			
	
	
		
			165 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
		
		
			
		
	
	
			165 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
|  | // Copyright (c) 2015-2023 MinIO, Inc.
 | ||
|  | //
 | ||
|  | // This file is part of MinIO Object Storage stack
 | ||
|  | //
 | ||
|  | // This program is free software: you can redistribute it and/or modify
 | ||
|  | // it under the terms of the GNU Affero General Public License as published by
 | ||
|  | // the Free Software Foundation, either version 3 of the License, or
 | ||
|  | // (at your option) any later version.
 | ||
|  | //
 | ||
|  | // This program is distributed in the hope that it will be useful
 | ||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||
|  | // GNU Affero General Public License for more details.
 | ||
|  | //
 | ||
|  | // You should have received a copy of the GNU Affero General Public License
 | ||
|  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | ||
|  | 
 | ||
|  | package browser | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"fmt" | ||
|  | 	"strconv" | ||
|  | 	"sync" | ||
|  | 
 | ||
|  | 	"github.com/minio/minio/internal/config" | ||
|  | 	"github.com/minio/pkg/v2/env" | ||
|  | ) | ||
|  | 
 | ||
|  | // Browser sub-system constants
 | ||
|  | const ( | ||
|  | 	// browserCSPPolicy setting name for Content-Security-Policy response header value
 | ||
|  | 	browserCSPPolicy = "csp_policy" | ||
|  | 	// browserHSTSSeconds setting name for Strict-Transport-Security response header, amount of seconds for 'max-age'
 | ||
|  | 	browserHSTSSeconds = "hsts_seconds" | ||
|  | 	// browserHSTSIncludeSubdomains setting name for Strict-Transport-Security response header 'includeSubDomains' flag (true or false)
 | ||
|  | 	browserHSTSIncludeSubdomains = "hsts_include_subdomains" | ||
|  | 	// browserHSTSPreload setting name for Strict-Transport-Security response header 'preload' flag (true or false)
 | ||
|  | 	browserHSTSPreload = "hsts_preload" | ||
|  | 	// browserReferrerPolicy setting name for Referrer-Policy response header
 | ||
|  | 	browserReferrerPolicy = "referrer_policy" | ||
|  | 
 | ||
|  | 	EnvBrowserCSPPolicy             = "MINIO_BROWSER_CONTENT_SECURITY_POLICY" | ||
|  | 	EnvBrowserHSTSSeconds           = "MINIO_BROWSER_HSTS_SECONDS" | ||
|  | 	EnvBrowserHSTSIncludeSubdomains = "MINIO_BROWSER_HSTS_INCLUDE_SUB_DOMAINS" | ||
|  | 	EnvBrowserHSTSPreload           = "MINIO_BROWSER_HSTS_PRELOAD" | ||
|  | 	EnvBrowserReferrerPolicy        = "MINIO_BROWSER_REFERRER_POLICY" | ||
|  | ) | ||
|  | 
 | ||
|  | // DefaultKVS - default storage class config
 | ||
|  | var ( | ||
|  | 	DefaultKVS = config.KVS{ | ||
|  | 		config.KV{ | ||
|  | 			Key:   browserCSPPolicy, | ||
|  | 			Value: "default-src 'self' 'unsafe-eval' 'unsafe-inline';", | ||
|  | 		}, | ||
|  | 		config.KV{ | ||
|  | 			Key:   browserHSTSSeconds, | ||
|  | 			Value: "0", | ||
|  | 		}, | ||
|  | 		config.KV{ | ||
|  | 			Key:   browserHSTSIncludeSubdomains, | ||
|  | 			Value: config.EnableOff, | ||
|  | 		}, | ||
|  | 		config.KV{ | ||
|  | 			Key:   browserHSTSPreload, | ||
|  | 			Value: config.EnableOff, | ||
|  | 		}, | ||
|  | 		config.KV{ | ||
|  | 			Key:   browserReferrerPolicy, | ||
|  | 			Value: "strict-origin-when-cross-origin", | ||
|  | 		}, | ||
|  | 	} | ||
|  | ) | ||
|  | 
 | ||
|  | // configLock is a global lock for browser config
 | ||
|  | var configLock sync.RWMutex | ||
|  | 
 | ||
|  | // Config storage class configuration
 | ||
|  | type Config struct { | ||
|  | 	CSPPolicy             string `json:"csp_policy"` | ||
|  | 	HSTSSeconds           int    `json:"hsts_seconds"` | ||
|  | 	HSTSIncludeSubdomains bool   `json:"hsts_include_subdomains"` | ||
|  | 	HSTSPreload           bool   `json:"hsts_preload"` | ||
|  | 	ReferrerPolicy        string `json:"referrer_policy"` | ||
|  | } | ||
|  | 
 | ||
|  | // Update Updates browser with new config
 | ||
|  | func (browseCfg *Config) Update(newCfg Config) { | ||
|  | 	configLock.Lock() | ||
|  | 	defer configLock.Unlock() | ||
|  | 	browseCfg.CSPPolicy = newCfg.CSPPolicy | ||
|  | 	browseCfg.HSTSSeconds = newCfg.HSTSSeconds | ||
|  | 	browseCfg.HSTSIncludeSubdomains = newCfg.HSTSIncludeSubdomains | ||
|  | 	browseCfg.HSTSPreload = newCfg.HSTSPreload | ||
|  | 	browseCfg.ReferrerPolicy = newCfg.ReferrerPolicy | ||
|  | } | ||
|  | 
 | ||
|  | // LookupConfig - lookup api config and override with valid environment settings if any.
 | ||
|  | func LookupConfig(kvs config.KVS) (cfg Config, err error) { | ||
|  | 	cspPolicy := env.Get(EnvBrowserCSPPolicy, kvs.GetWithDefault(browserCSPPolicy, DefaultKVS)) | ||
|  | 	hstsSeconds, err := strconv.Atoi(env.Get(EnvBrowserHSTSSeconds, kvs.GetWithDefault(browserHSTSSeconds, DefaultKVS))) | ||
|  | 	if err != nil { | ||
|  | 		return cfg, err | ||
|  | 	} | ||
|  | 
 | ||
|  | 	hstsIncludeSubdomains := env.Get(EnvBrowserHSTSIncludeSubdomains, kvs.GetWithDefault(browserHSTSIncludeSubdomains, DefaultKVS)) == config.EnableOn | ||
|  | 	hstsPreload := env.Get(EnvBrowserHSTSPreload, kvs.Get(browserHSTSPreload)) == config.EnableOn | ||
|  | 
 | ||
|  | 	referrerPolicy := env.Get(EnvBrowserReferrerPolicy, kvs.GetWithDefault(browserReferrerPolicy, DefaultKVS)) | ||
|  | 	switch referrerPolicy { | ||
|  | 	case "no-referrer", "no-referrer-when-downgrade", "origin", "origin-when-cross-origin", "same-origin", "strict-origin", "strict-origin-when-cross-origin", "unsafe-url": | ||
|  | 		cfg.ReferrerPolicy = referrerPolicy | ||
|  | 	default: | ||
|  | 		return cfg, fmt.Errorf("invalid value %v for %s", referrerPolicy, browserReferrerPolicy) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	cfg.CSPPolicy = cspPolicy | ||
|  | 	cfg.HSTSSeconds = hstsSeconds | ||
|  | 	cfg.HSTSIncludeSubdomains = hstsIncludeSubdomains | ||
|  | 	cfg.HSTSPreload = hstsPreload | ||
|  | 
 | ||
|  | 	return cfg, nil | ||
|  | } | ||
|  | 
 | ||
|  | // GetCSPolicy - Get the Content security Policy
 | ||
|  | func (browseCfg *Config) GetCSPolicy() string { | ||
|  | 	configLock.RLock() | ||
|  | 	defer configLock.RUnlock() | ||
|  | 	return browseCfg.CSPPolicy | ||
|  | } | ||
|  | 
 | ||
|  | // GetHSTSSeconds - Get the Content security Policy
 | ||
|  | func (browseCfg *Config) GetHSTSSeconds() int { | ||
|  | 	configLock.RLock() | ||
|  | 	defer configLock.RUnlock() | ||
|  | 	return browseCfg.HSTSSeconds | ||
|  | } | ||
|  | 
 | ||
|  | // IsHSTSIncludeSubdomains - is HSTS 'includeSubdomains' directive enabled
 | ||
|  | func (browseCfg *Config) IsHSTSIncludeSubdomains() string { | ||
|  | 	configLock.RLock() | ||
|  | 	defer configLock.RUnlock() | ||
|  | 	if browseCfg.HSTSSeconds > 0 && browseCfg.HSTSIncludeSubdomains { | ||
|  | 		return config.EnableOn | ||
|  | 	} | ||
|  | 	return config.EnableOff | ||
|  | } | ||
|  | 
 | ||
|  | // IsHSTSPreload - is HSTS 'preload' directive enabled
 | ||
|  | func (browseCfg *Config) IsHSTSPreload() string { | ||
|  | 	configLock.RLock() | ||
|  | 	defer configLock.RUnlock() | ||
|  | 	if browseCfg.HSTSSeconds > 0 && browseCfg.HSTSPreload { | ||
|  | 		return config.EnableOn | ||
|  | 	} | ||
|  | 	return config.EnableOff | ||
|  | } | ||
|  | 
 | ||
|  | // GetReferPolicy - Get the ReferPolicy
 | ||
|  | func (browseCfg *Config) GetReferPolicy() string { | ||
|  | 	configLock.RLock() | ||
|  | 	defer configLock.RUnlock() | ||
|  | 	return browseCfg.ReferrerPolicy | ||
|  | } |