Skip to content

Commit a04311b

Browse files
committed
CONSOLE-4265: Add new API field to ConsolePlugin CRD for allowing additional CSP sources
1 parent 8a37acc commit a04311b

20 files changed

+2337
-7
lines changed

console/v1/tests/consoleplugins.console.openshift.io/AAA_ungated.yaml

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,189 @@ tests:
8787
i18n:
8888
loadType: Invalid
8989
expectedError: "Unsupported value: \"Invalid\""
90+
- name: Should be able to create a ConsolePlugin with valid CSP configuration
91+
initial: |
92+
apiVersion: console.openshift.io/v1
93+
kind: ConsolePlugin
94+
spec:
95+
displayName: foo
96+
backend:
97+
type: Service
98+
contentSecurityPolicy:
99+
- directive: ScriptSrc
100+
values:
101+
- https://script1.com/
102+
- directive: ImgSrc
103+
values:
104+
- https://img1.com/
105+
expected: |
106+
apiVersion: console.openshift.io/v1
107+
kind: ConsolePlugin
108+
spec:
109+
displayName: foo
110+
backend:
111+
type: Service
112+
contentSecurityPolicy:
113+
- directive: ScriptSrc
114+
values:
115+
- https://script1.com/
116+
- directive: ImgSrc
117+
values:
118+
- https://img1.com/
119+
- name: Should throw an error for duplicate CSP directive entries
120+
initial: |
121+
apiVersion: console.openshift.io/v1
122+
kind: ConsolePlugin
123+
spec:
124+
displayName: foo
125+
backend:
126+
type: Service
127+
contentSecurityPolicy:
128+
- directive: ScriptSrc
129+
values:
130+
- https://script1.com/
131+
- directive: ScriptSrc
132+
values:
133+
- https://script1.com/
134+
expectedError: "spec.contentSecurityPolicy[1]: Duplicate value: map[string]interface {}{\"directive\":\"ScriptSrc\"}"
135+
- name: Should throw an error for duplicate CSP directive values
136+
initial: |
137+
apiVersion: console.openshift.io/v1
138+
kind: ConsolePlugin
139+
spec:
140+
displayName: foo
141+
backend:
142+
type: Service
143+
contentSecurityPolicy:
144+
- directive: ScriptSrc
145+
values:
146+
- https://script1.com/
147+
- https://script1.com/
148+
expectedError: "spec.contentSecurityPolicy[0].values: Invalid value: \"array\": each CSP directive value must be unique"
149+
- name: Should throw an error for incorrect directive type
150+
initial: |
151+
apiVersion: console.openshift.io/v1
152+
kind: ConsolePlugin
153+
spec:
154+
displayName: foo
155+
backend:
156+
type: Service
157+
contentSecurityPolicy:
158+
- directive: TestSrc
159+
values:
160+
- https://script1.com/
161+
expectedError: "spec.contentSecurityPolicy[0].directive: Unsupported value: \"TestSrc\": supported values: \"DefaultSrc\", \"ScriptSrc\", \"StyleSrc\", \"ImgSrc\", \"FontSrc\""
162+
- name: Should throw an error for invalid CSP directive values, using wildcard
163+
initial: |
164+
apiVersion: console.openshift.io/v1
165+
kind: ConsolePlugin
166+
spec:
167+
displayName: foo
168+
backend:
169+
type: Service
170+
contentSecurityPolicy:
171+
- directive: ScriptSrc
172+
values:
173+
- "*"
174+
expectedError: "spec.contentSecurityPolicy[0].values[0]: Invalid value: \"string\": CSP directive value cannot be a wildcard"
175+
- name: Should be able to create a ConsolePlugin with valid CSP value, using domain with wildcard prefix
176+
initial: |
177+
apiVersion: console.openshift.io/v1
178+
kind: ConsolePlugin
179+
spec:
180+
displayName: foo
181+
backend:
182+
type: Service
183+
contentSecurityPolicy:
184+
- directive: ScriptSrc
185+
values:
186+
- "*.example.com"
187+
expected: |
188+
apiVersion: console.openshift.io/v1
189+
kind: ConsolePlugin
190+
spec:
191+
displayName: foo
192+
backend:
193+
type: Service
194+
contentSecurityPolicy:
195+
- directive: ScriptSrc
196+
values:
197+
- "*.example.com"
198+
- name: Should throw an error for invalid CSP directive values, starting and ending with quotes
199+
initial: |
200+
apiVersion: console.openshift.io/v1
201+
kind: ConsolePlugin
202+
spec:
203+
displayName: foo
204+
backend:
205+
type: Service
206+
contentSecurityPolicy:
207+
- directive: ScriptSrc
208+
values:
209+
- "'none'"
210+
expectedError: "\"string\": CSP directive value cannot contain a quote"
211+
- name: Should throw an error for invalid CSP directive values with quote
212+
initial: |
213+
apiVersion: console.openshift.io/v1
214+
kind: ConsolePlugin
215+
spec:
216+
displayName: foo
217+
backend:
218+
type: Service
219+
contentSecurityPolicy:
220+
- directive: ScriptSrc
221+
values:
222+
- "foo'bar"
223+
expectedError: "\"string\": CSP directive value cannot contain a quote"
224+
- name: Should throw an error for invalid CSP directive values with comma
225+
initial: |
226+
apiVersion: console.openshift.io/v1
227+
kind: ConsolePlugin
228+
spec:
229+
displayName: foo
230+
backend:
231+
type: Service
232+
contentSecurityPolicy:
233+
- directive: ScriptSrc
234+
values:
235+
- "foo,bar"
236+
expectedError: "spec.contentSecurityPolicy[0].values[0]: Invalid value: \"string\": CSP directive value cannot contain a comma"
237+
- name: Should throw an error for invalid CSP directive values with semi-colon
238+
initial: |
239+
apiVersion: console.openshift.io/v1
240+
kind: ConsolePlugin
241+
spec:
242+
displayName: foo
243+
backend:
244+
type: Service
245+
contentSecurityPolicy:
246+
- directive: ScriptSrc
247+
values:
248+
- "foo;bar"
249+
expectedError: "spec.contentSecurityPolicy[0].values[0]: Invalid value: \"string\": CSP directive value cannot contain a semi-colon"
250+
- name: Should throw an error for invalid CSP directive values with whitespace, using space
251+
initial: |
252+
apiVersion: console.openshift.io/v1
253+
kind: ConsolePlugin
254+
spec:
255+
displayName: foo
256+
backend:
257+
type: Service
258+
contentSecurityPolicy:
259+
- directive: ScriptSrc
260+
values:
261+
- https://scr ipt1.com/
262+
expectedError: "spec.contentSecurityPolicy[0].values[0]: Invalid value: \"string\": CSP directive value cannot contain a whitespace"
263+
- name: Should throw an error for invalid CSP directive values with whitespace, using tab
264+
initial: |
265+
apiVersion: console.openshift.io/v1
266+
kind: ConsolePlugin
267+
spec:
268+
displayName: foo
269+
backend:
270+
type: Service
271+
contentSecurityPolicy:
272+
- directive: ScriptSrc
273+
values:
274+
- https://scri pt1.com/
275+
expectedError: "spec.contentSecurityPolicy[0].values[0]: Invalid value: \"string\": CSP directive value cannot contain a whitespace"

console/v1/types_console_plugin.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,131 @@ type ConsolePluginSpec struct {
4848
// i18n is the configuration of plugin's localization resources.
4949
// +optional
5050
I18n ConsolePluginI18n `json:"i18n"`
51+
// contentSecurityPolicy is a list of Content-Security-Policy (CSP) directives for the plugin.
52+
// Each directive specifies a list of values, appropriate for the given directive type,
53+
// for example a list of remote endpoints for fetch directives such as ScriptSrc.
54+
// Console web application uses CSP to detect and mitigate certain types of attacks,
55+
// such as cross-site scripting (XSS) and data injection attacks.
56+
// Dynamic plugins should specify this field if need to load assets from outside
57+
// the cluster or if violation reports are observed. Dynamic plugins should always prefer
58+
// loading their assets from within the cluster, either by vendoring them, or fetching
59+
// from a cluster service.
60+
// CSP violation reports can be viewed in the browser's console logs during development and
61+
// testing of the plugin in the OpenShift web console.
62+
// Available directive types are DefaultSrc, ScriptSrc, StyleSrc, ImgSrc and FontSrc.
63+
// Each of the available directives may be defined only once in the list.
64+
// The value 'self' is automatically included in all fetch directives by the OpenShift web
65+
// console's backend.
66+
// For more information about the CSP directives, see:
67+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
68+
//
69+
// The OpenShift web console server aggregates the CSP directives and values across
70+
// its own default values and all enabled ConsolePlugin CRs, merging them into a single
71+
// policy string that is sent to the browser via `Content-Security-Policy` HTTP response header.
72+
//
73+
// Example:
74+
// ConsolePlugin A directives:
75+
// script-src: https://script1.com/, https://script2.com/
76+
// font-src: https://font1.com/
77+
//
78+
// ConsolePlugin B directives:
79+
// script-src: https://script2.com/, https://script3.com/
80+
// font-src: https://font2.com/
81+
// img-src: https://img1.com/
82+
//
83+
// Unified set of CSP directives, passed to the OpenShift web console server:
84+
// script-src: https://script1.com/, https://script2.com/, https://script3.com/
85+
// font-src: https://font1.com/, https://font2.com/
86+
// img-src: https://img1.com/
87+
//
88+
// OpenShift web console server CSP response header:
89+
// Content-Security-Policy: default-src 'self'; base-uri 'self'; script-src 'self' https://script1.com/ https://script2.com/ https://script3.com/; font-src 'self' https://font1.com/ https://font2.com/; img-src 'self' https://img1.com/; style-src 'self'; frame-src 'none'; object-src 'none'
90+
//
91+
// +openshift:enable:FeatureGate=ConsolePluginContentSecurityPolicy
92+
// +kubebuilder:validation:MaxItems=5
93+
// +kubebuilder:validation:XValidation:rule="self.map(x, x.values.map(y, y.size()).sum()).sum() < 8192",message="the total combined size of values of all directives must not exceed 8192 (8kb)"
94+
// +listType=map
95+
// +listMapKey=directive
96+
// +optional
97+
ContentSecurityPolicy []ConsolePluginCSP `json:"contentSecurityPolicy"`
98+
}
99+
100+
// DirectiveType is an enumeration of OpenShift web console supported CSP directives.
101+
// LoadType is an enumeration of i18n loading types.
102+
// +kubebuilder:validation:Enum:="DefaultSrc";"ScriptSrc";"StyleSrc";"ImgSrc";"FontSrc"
103+
// +enum
104+
type DirectiveType string
105+
106+
const (
107+
// DefaultSrc directive serves as a fallback for the other CSP fetch directives.
108+
// For more information about the DefaultSrc directive, see:
109+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src
110+
DefaultSrc DirectiveType = "DefaultSrc"
111+
// ScriptSrc directive specifies valid sources for JavaScript.
112+
// For more information about the ScriptSrc directive, see:
113+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
114+
ScriptSrc DirectiveType = "ScriptSrc"
115+
// StyleSrc directive specifies valid sources for stylesheets.
116+
// For more information about the StyleSrc directive, see:
117+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
118+
StyleSrc DirectiveType = "StyleSrc"
119+
// ImgSrc directive specifies a valid sources of images and favicons.
120+
// For more information about the ImgSrc directive, see:
121+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src
122+
ImgSrc DirectiveType = "ImgSrc"
123+
// FontSrc directive specifies valid sources for fonts loaded using @font-face.
124+
// For more information about the FontSrcdirective, see:
125+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/font-src
126+
FontSrc DirectiveType = "FontSrc"
127+
)
128+
129+
// CSPDirectiveValue is single value for a Content-Security-Policy directive.
130+
// Each directive value must have a maximum length of 1024 characters and must not contain
131+
// whitespace, commas (,), semicolons (;) or single quotes ('). The value '*' is not permitted.
132+
// +kubebuilder:validation:MinLength=1
133+
// +kubebuilder:validation:MaxLength=1024
134+
// +kubebuilder:validation:XValidation:rule="!self.contains(\"'\")",message="CSP directive value cannot contain a quote"
135+
// +kubebuilder:validation:XValidation:rule="!self.matches('\\\\s')",message="CSP directive value cannot contain a whitespace"
136+
// +kubebuilder:validation:XValidation:rule="!self.contains(',')",message="CSP directive value cannot contain a comma"
137+
// +kubebuilder:validation:XValidation:rule="!self.contains(';')",message="CSP directive value cannot contain a semi-colon"
138+
// +kubebuilder:validation:XValidation:rule="self != '*'",message="CSP directive value cannot be a wildcard"
139+
type CSPDirectiveValue string
140+
141+
// ConsolePluginCSP holds configuration for a specific CSP directive
142+
type ConsolePluginCSP struct {
143+
// directive specifies which Content-Security-Policy directive to configure.
144+
// Available directive types are DefaultSrc, ScriptSrc, StyleSrc, ImgSrc and FontSrc.
145+
// DefaultSrc directive serves as a fallback for the other CSP fetch directives.
146+
// For more information about the DefaultSrc directive, see:
147+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/default-src
148+
// ScriptSrc directive specifies valid sources for JavaScript.
149+
// For more information about the ScriptSrc directive, see:
150+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src
151+
// StyleSrc directive specifies valid sources for stylesheets.
152+
// For more information about the StyleSrc directive, see:
153+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/style-src
154+
// ImgSrc directive specifies a valid sources of images and favicons.
155+
// For more information about the ImgSrc directive, see:
156+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src
157+
// FontSrc directive specifies valid sources for fonts loaded using @font-face.
158+
// For more information about the FontSrc directive, see:
159+
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/font-src
160+
// +kubebuilder:validation:Required
161+
Directive DirectiveType `json:"directive"`
162+
// values defines an array of values to append to the console defaults for this directive.
163+
// Each ConsolePlugin may define their own directives with their values. These will be set
164+
// by the OpenShift web console's backend, as part of its Content-Security-Policy header.
165+
// The array can contain at most 16 values. Each directive value must have a maximum length
166+
// of 1024 characters and must not contain whitespace, commas (,), semicolons (;) or single
167+
// quotes ('). The value '*' is not permitted.
168+
// Each value in the array must be unique.
169+
//
170+
// +kubebuilder:validation:Required
171+
// +kubebuilder:validation:MinItems=1
172+
// +kubebuilder:validation:MaxItems=16
173+
// +kubebuilder:validation:XValidation:rule="self.all(x, self.exists_one(y, x == y))",message="each CSP directive value must be unique"
174+
// +listType=atomic
175+
Values []CSPDirectiveValue `json:"values"`
51176
}
52177

53178
// LoadType is an enumeration of i18n loading types

0 commit comments

Comments
 (0)