Skip to content

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

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

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions