From af2071c60cee190afd0dd2e1198ccdb9b098c347 Mon Sep 17 00:00:00 2001 From: Martin McKeaveney Date: Mon, 7 Oct 2024 16:44:28 +0100 Subject: [PATCH] fixing vulns for ent client --- hosting/proxy/nginx.prod.conf | 2 +- .../controllers/static/templates/preview.hbs | 2 +- packages/server/src/environment.ts | 1 + .../src/sdk/app/rows/tests/utils.spec.ts | 41 +++++++++++++++++++ packages/server/src/sdk/app/rows/utils.ts | 10 +++++ 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/hosting/proxy/nginx.prod.conf b/hosting/proxy/nginx.prod.conf index 59722dac5c..6d5db51bce 100644 --- a/hosting/proxy/nginx.prod.conf +++ b/hosting/proxy/nginx.prod.conf @@ -51,7 +51,7 @@ http { proxy_buffering off; set $csp_default "default-src 'self'"; - set $csp_script "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://*.budibase.net https://cdn.budi.live https://js.intercomcdn.com https://widget.intercom.io https://d2l5prqdbvm3op.cloudfront.net https://us-assets.i.posthog.com"; + set $csp_script "script-src 'self' 'nonce-builderPreview' unsafe-eval' https://*.budibase.net https://cdn.budi.live https://js.intercomcdn.com https://widget.intercom.io https://d2l5prqdbvm3op.cloudfront.net https://us-assets.i.posthog.com"; set $csp_style "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com https://rsms.me https://maxcdn.bootstrapcdn.com"; set $csp_object "object-src 'none'"; set $csp_base_uri "base-uri 'self'"; diff --git a/packages/server/src/api/controllers/static/templates/preview.hbs b/packages/server/src/api/controllers/static/templates/preview.hbs index 54b5b1a4e4..be38825ec9 100644 --- a/packages/server/src/api/controllers/static/templates/preview.hbs +++ b/packages/server/src/api/controllers/static/templates/preview.hbs @@ -31,7 +31,7 @@ } - ", + "\">", + "", + "
Hover over me!
", + "'; EXEC sp_msforeachtable 'DROP TABLE ?'; --", + "{alert('Injected')}", + "UNION SELECT * FROM users", + "INSERT INTO users (username, password) VALUES ('admin', 'password')", + "/* This is a comment */ SELECT * FROM users", + "" + ])('test potentially unsafe input: %s', async input => { + environment.XSS_SAFE_MODE = true + const table = getTable() + const row = { text: input } + const output = await validate({ source: table, row }) + expect(output.valid).toBe(false) + expect(output.errors).toBe(["Input not sanitised - potentially vulnerable to XSS"]) + environment.XSS_SAFE_MODE = false + }) + }) }) diff --git a/packages/server/src/sdk/app/rows/utils.ts b/packages/server/src/sdk/app/rows/utils.ts index 6ef4dcbc8e..4c02889f8f 100644 --- a/packages/server/src/sdk/app/rows/utils.ts +++ b/packages/server/src/sdk/app/rows/utils.ts @@ -22,6 +22,7 @@ import { extractViewInfoFromID, isRelationshipColumn } from "../../../db/utils" import { isSQL } from "../../../integrations/utils" import { docIds, sql } from "@budibase/backend-core" import { getTableFromSource } from "../../../api/controllers/row/utils" +import env from "../../../environment" const SQL_CLIENT_SOURCE_MAP: Record = { [SourceName.POSTGRES]: SqlClient.POSTGRES, @@ -43,6 +44,8 @@ const SQL_CLIENT_SOURCE_MAP: Record = { [SourceName.BUDIBASE]: undefined, } +const XSS_INPUT_REGEX = /[<>;"'(){}]|--|\/\*|\*\/|union|select|insert|drop|delete|update|exec|script/i + export function getSQLClient(datasource: Datasource): SqlClient { if (!isSQL(datasource)) { throw new Error("Cannot get SQL Client for non-SQL datasource") @@ -222,6 +225,13 @@ export async function validate({ } else { res = validateJs.single(row[fieldName], constraints) } + + if (env.XSS_SAFE_MODE && typeof row[fieldName] === "string") { + if (XSS_INPUT_REGEX.test(row[fieldName])) { + errors[fieldName] = ['Input not sanitised - potentially vulnerable to XSS'] + } + } + if (res) errors[fieldName] = res } return { valid: Object.keys(errors).length === 0, errors }