Skip to content

Document required directive unsafe-eval in Content-Security-Policy #1245

@hpedrorodrigues

Description

@hpedrorodrigues

First of all, thanks for this project! 🚀

Summary

I just started working with this project in a GKE cluster and noticed that the Console UI requires the unsafe-eval directive in Content-Security-Policy. While this is a security concern, documenting it for now would already be great.

System configuration and versions

Docker images: 2.11.0 (Jitsu Next)
Deployed using the Helm chart: stafftastic/jitsu-chart

Artifacts (logs, etc)

I see this in the logs when I try to load the page to create a new site/stream, for instance:

Evaluating a string as JavaScript violates the following Content Security Policy directive because 'unsafe-eval' is not an allowed source of script: default-src 'self' blob: data: wss://*.<domain> https://<domain> https://*.<domain> ... 'unsafe-inline' 'wasm-unsafe-eval'.
index.js:118 Error compiling schema, function code: const schema8 = scope.schema[3];const func0 = scope.func[0];const formats0 = scope.formats[0];return function validate5(data, {instancePath="", parentData, parentDataProperty, rootData=data}={}){let vErrors = null;let errors = 0;if(data && typeof data == "object" && !Array.isArray(data)){if(data.id === undefined){const err0 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "id"},message:"must have required property '"+"id"+"'",schema:schema8.required,parentSchema:schema8,data};if(vErrors === null){vErrors = [err0];}else {vErrors.push(err0);}errors++;}if(data.type === undefined){const err1 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "type"},message:"must have required property '"+"type"+"'",schema:schema8.required,parentSchema:schema8,data};if(vErrors === null){vErrors = [err1];}else {vErrors.push(err1);}errors++;}if(data.workspaceId === undefined){const err2 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "workspaceId"},message:"must have required property '"+"workspaceId"+"'",schema:schema8.required,parentSchema:schema8,data};if(vErrors === null){vErrors = [err2];}else {vErrors.push(err2);}errors++;}if(data.name === undefined){const err3 = {instancePath,schemaPath:"#/required",keyword:"required",params:{missingProperty: "name"},message:"must have required property '"+"name"+"'",schema:schema8.required,parentSchema:schema8,data};if(vErrors === null){vErrors = [err3];}else {vErrors.push(err3);}errors++;}for(const key0 in data){if(!(func0.call(schema8.properties, key0))){const err4 = {instancePath,schemaPath:"#/additionalProperties",keyword:"additionalProperties",params:{additionalProperty: key0},message:"must NOT have additional properties",schema:false,parentSchema:schema8,data};if(vErrors === null){vErrors = [err4];}else {vErrors.push(err4);}errors++;}}if(data.id !== undefined){let data0 = data.id;if(typeof data0 !== "string"){const err5 = {instancePath:instancePath+"/id",schemaPath:"#/properties/id/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema8.properties.id.type,parentSchema:schema8.properties.id,data:data0};if(vErrors === null){vErrors = [err5];}else {vErrors.push(err5);}errors++;}}if(data.type !== undefined){let data1 = data.type;if(typeof data1 !== "string"){const err6 = {instancePath:instancePath+"/type",schemaPath:"#/properties/type/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema8.properties.type.type,parentSchema:schema8.properties.type,data:data1};if(vErrors === null){vErrors = [err6];}else {vErrors.push(err6);}errors++;}}if(data.workspaceId !== undefined){let data2 = data.workspaceId;if(typeof data2 !== "string"){const err7 = {instancePath:instancePath+"/workspaceId",schemaPath:"#/properties/workspaceId/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema8.properties.workspaceId.type,parentSchema:schema8.properties.workspaceId,data:data2};if(vErrors === null){vErrors = [err7];}else {vErrors.push(err7);}errors++;}}if(data.name !== undefined){let data3 = data.name;if(typeof data3 !== "string"){const err8 = {instancePath:instancePath+"/name",schemaPath:"#/properties/name/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema8.properties.name.type,parentSchema:schema8.properties.name,data:data3};if(vErrors === null){vErrors = [err8];}else {vErrors.push(err8);}errors++;}}if(data.cloneId !== undefined){let data4 = data.cloneId;if(typeof data4 !== "string"){const err9 = {instancePath:instancePath+"/cloneId",schemaPath:"#/properties/cloneId/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema8.properties.cloneId.type,parentSchema:schema8.properties.cloneId,data:data4};if(vErrors === null){vErrors = [err9];}else {vErrors.push(err9);}errors++;}}if(data.domains !== undefined){let data5 = data.domains;if(Array.isArray(data5)){const len0 = data5.length;for(let i0=0; i0<len0; i0++){let data6 = data5[i0];if(typeof data6 !== "string"){const err10 = {instancePath:instancePath+"/domains/" + i0,schemaPath:"#/properties/domains/items/type",keyword:"type",params:{type: "string"},message:"must be string",schema:schema8.properties.domains.items.type,parentSchema:schema8.properties.domains.items,data:data6};if(vErrors === null){vErrors = [err10];}else {vErrors.push(err10);}errors++;}}}else {const err11 = {instancePath:instancePath+"/domains",schemaPath:"#/properties/domains/type",keyword:"type",params:{type: "array"},message:"must be array",schema:schema8.properties.domains.type,parentSchema:schema8.properties.domains,data:data5};if(vErrors === null){vErrors = [err11];}else {vErrors.push(err11);}errors++;}}if(data.authorizedJavaScriptDomains !== undefined){let data7 = data.authorizedJavaScriptDomains;if(typeof data7 !== "string"){const err12 = {instancePath:instancePath+"/authorizedJavaScriptDomains",schemaPath:"#/properties/authorizedJavaScriptDomai
u @ index.js:118
_compileSchemaEnv @ core.js:473
compile @ core.js:160
rawValidation @ validator.js:46
validateFormData @ validator.js:79
validate @ Form.js:474
getStateFromProps @ Form.js:413
getSnapshotBeforeUpdate @ Form.js:324
(anonymous) @ react-dom.production.min.js:242
(anonymous) @ react-dom.production.min.js:242
uD @ react-dom.production.min.js:282
uw @ react-dom.production.min.js:268
x @ scheduler.production.min.js:13
R @ scheduler.production.min.js:14

This is what I see when I try to save a new site/stream, for instance:

react-dom.production.min.js:106 Uncaught TypeError: Cannot read properties of undefined (reading 'replace')
    at ConfigEditor.tsx:478:54
    at Array.map (<anonymous>)
    at Object.onSave [as onClick] (ConfigEditor.tsx:477:43)
    at button.js:146:66
    at Object.eO (react-dom.production.min.js:54:315)
    at ej (react-dom.production.min.js:54:468)
    at react-dom.production.min.js:55:32
    at n7 (react-dom.production.min.js:55:119)
    at re (react-dom.production.min.js:106:380)
    at react-dom.production.min.js:117:104

Related to:

const fieldId = e.property.replace(".", "");

Notes

Not sure if I'm missing something here. If so, please let me know. Thanks!

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions