mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-23 16:27:35 +00:00
632639ae7f
* feat: enable iframe use * cleanup * fix mocks * fix linting * docs: add iframe usage to solution scenarios configurations * improve api * feat(console): security policy * description * remove unnecessary line * disable input button and urls when not enabled * add image to docs Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Fabi <38692350+hifabienne@users.noreply.github.com>
145 lines
3.7 KiB
Go
145 lines
3.7 KiB
Go
package middleware
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type CSP struct {
|
|
DefaultSrc CSPSourceOptions
|
|
ScriptSrc CSPSourceOptions
|
|
ObjectSrc CSPSourceOptions
|
|
StyleSrc CSPSourceOptions
|
|
ImgSrc CSPSourceOptions
|
|
MediaSrc CSPSourceOptions
|
|
FrameSrc CSPSourceOptions
|
|
FrameAncestors CSPSourceOptions
|
|
FontSrc CSPSourceOptions
|
|
ManifestSrc CSPSourceOptions
|
|
ConnectSrc CSPSourceOptions
|
|
FormAction CSPSourceOptions
|
|
}
|
|
|
|
var (
|
|
DefaultSCP = CSP{
|
|
DefaultSrc: CSPSourceOptsNone(),
|
|
ScriptSrc: CSPSourceOptsSelf(),
|
|
ObjectSrc: CSPSourceOptsNone(),
|
|
StyleSrc: CSPSourceOptsSelf(),
|
|
ImgSrc: CSPSourceOptsSelf(),
|
|
MediaSrc: CSPSourceOptsNone(),
|
|
FrameSrc: CSPSourceOptsNone(),
|
|
FrameAncestors: CSPSourceOptsNone(),
|
|
FontSrc: CSPSourceOptsSelf(),
|
|
ManifestSrc: CSPSourceOptsSelf(),
|
|
ConnectSrc: CSPSourceOptsSelf(),
|
|
}
|
|
)
|
|
|
|
func (csp *CSP) Value(nonce, host string, iframe []string) string {
|
|
valuesMap := csp.asMap(iframe)
|
|
|
|
values := make([]string, 0, len(valuesMap))
|
|
for k, v := range valuesMap {
|
|
if v == nil {
|
|
continue
|
|
}
|
|
|
|
values = append(values, fmt.Sprintf("%v %v", k, v.String(nonce, host)))
|
|
}
|
|
|
|
return strings.Join(values, ";")
|
|
}
|
|
|
|
func (csp *CSP) asMap(iframe []string) map[string]CSPSourceOptions {
|
|
frameAncestors := csp.FrameAncestors
|
|
if len(iframe) > 0 {
|
|
frameAncestors = CSPSourceOpts().AddHost(iframe...)
|
|
}
|
|
return map[string]CSPSourceOptions{
|
|
"default-src": csp.DefaultSrc,
|
|
"script-src": csp.ScriptSrc,
|
|
"object-src": csp.ObjectSrc,
|
|
"style-src": csp.StyleSrc,
|
|
"img-src": csp.ImgSrc,
|
|
"media-src": csp.MediaSrc,
|
|
"frame-src": csp.FrameSrc,
|
|
"frame-ancestors": frameAncestors,
|
|
"font-src": csp.FontSrc,
|
|
"manifest-src": csp.ManifestSrc,
|
|
"connect-src": csp.ConnectSrc,
|
|
"form-action": csp.FormAction,
|
|
}
|
|
}
|
|
|
|
type CSPSourceOptions []string
|
|
|
|
func CSPSourceOpts() CSPSourceOptions {
|
|
return CSPSourceOptions{}
|
|
}
|
|
|
|
func CSPSourceOptsNone() CSPSourceOptions {
|
|
return []string{"'none'"}
|
|
}
|
|
|
|
func CSPSourceOptsSelf() CSPSourceOptions {
|
|
return []string{"'self'"}
|
|
}
|
|
|
|
func (srcOpts CSPSourceOptions) AddSelf() CSPSourceOptions {
|
|
return append(srcOpts, "'self'")
|
|
}
|
|
|
|
func (srcOpts CSPSourceOptions) AddInline() CSPSourceOptions {
|
|
return append(srcOpts, "'unsafe-inline'")
|
|
}
|
|
|
|
func (srcOpts CSPSourceOptions) AddEval() CSPSourceOptions {
|
|
return append(srcOpts, "'unsafe-eval'")
|
|
}
|
|
|
|
func (srcOpts CSPSourceOptions) AddStrictDynamic() CSPSourceOptions {
|
|
return append(srcOpts, "'strict-dynamic'")
|
|
}
|
|
|
|
func (srcOpts CSPSourceOptions) AddHost(h ...string) CSPSourceOptions {
|
|
return append(srcOpts, h...)
|
|
}
|
|
|
|
func (srcOpts CSPSourceOptions) AddOwnHost() CSPSourceOptions {
|
|
return append(srcOpts, placeHolderHost)
|
|
}
|
|
|
|
func (srcOpts CSPSourceOptions) AddScheme(s ...string) CSPSourceOptions {
|
|
return srcOpts.add(s, "%v:")
|
|
}
|
|
|
|
func (srcOpts CSPSourceOptions) AddNonce() CSPSourceOptions {
|
|
return append(srcOpts, fmt.Sprintf("'nonce-%s'", placeHolderNonce))
|
|
}
|
|
|
|
const (
|
|
placeHolderNonce = "{{nonce}}"
|
|
placeHolderHost = "{{host}}"
|
|
)
|
|
|
|
func (srcOpts CSPSourceOptions) AddHash(alg, b64v string) CSPSourceOptions {
|
|
return append(srcOpts, fmt.Sprintf("'%v-%v'", alg, b64v))
|
|
}
|
|
|
|
func (srcOpts CSPSourceOptions) String(nonce, host string) string {
|
|
value := strings.Join(srcOpts, " ")
|
|
if !strings.Contains(value, placeHolderNonce) && !strings.Contains(value, placeHolderHost) {
|
|
return value
|
|
}
|
|
return strings.ReplaceAll(strings.ReplaceAll(value, placeHolderHost, host), placeHolderNonce, nonce)
|
|
}
|
|
|
|
func (srcOpts CSPSourceOptions) add(values []string, format string) CSPSourceOptions {
|
|
for i, v := range values {
|
|
values[i] = fmt.Sprintf(format, v)
|
|
}
|
|
|
|
return append(srcOpts, values...)
|
|
}
|