n8n-nodes-trusera 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"dashboardHtml.d.ts","sourceRoot":"","sources":["../../lib/dashboardHtml.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CA6wBR"}
1
+ {"version":3,"file":"dashboardHtml.d.ts","sourceRoot":"","sources":["../../lib/dashboardHtml.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,UAAU,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CA8wBR"}
@@ -18,7 +18,7 @@ function generateDashboardHtml(scanResult, password) {
18
18
  let dataScript;
19
19
  let decryptionScript = '';
20
20
  let passwordFormHtml = '';
21
- const remediationScript = `<script>var REMEDIATION_MAP = ${JSON.stringify(config_1.REMEDIATION_MAP)};</script>`;
21
+ const remediationScript = `<script>var REMEDIATION_MAP = ${JSON.stringify(config_1.REMEDIATION_MAP).replace(/<\//g, '<\\/')};</script>`;
22
22
  if (password) {
23
23
  const salt = (0, crypto_1.randomBytes)(16);
24
24
  const iv = (0, crypto_1.randomBytes)(12);
@@ -71,24 +71,25 @@ async function handleLogin(e) {
71
71
  return;
72
72
  }
73
73
  SCAN_DATA = data;
74
- try { sessionStorage.setItem('trusera-pwd', pwd); } catch(e) {}
74
+ try {
75
+ sessionStorage.setItem('trusera-data', JSON.stringify(data));
76
+ } catch(e) {}
75
77
  document.getElementById('login-screen').classList.add('hidden');
76
78
  document.getElementById('dashboard').classList.remove('hidden');
77
79
  renderDashboard();
78
80
  }
79
81
 
80
82
  async function trySessionRestore() {
81
- var saved; try { saved = sessionStorage.getItem('trusera-pwd'); } catch(e) {}
82
- if (saved) {
83
- var data = await decryptData(saved);
84
- if (data) {
85
- SCAN_DATA = data;
83
+ try {
84
+ var raw = sessionStorage.getItem('trusera-data');
85
+ if (raw) {
86
+ SCAN_DATA = JSON.parse(raw);
86
87
  document.getElementById('login-screen').classList.add('hidden');
87
88
  document.getElementById('dashboard').classList.remove('hidden');
88
89
  renderDashboard();
89
90
  return;
90
91
  }
91
- }
92
+ } catch(e) {}
92
93
  document.getElementById('login-screen').classList.remove('hidden');
93
94
  }
94
95
  `;
@@ -111,7 +112,7 @@ async function trySessionRestore() {
111
112
  </div>`;
112
113
  }
113
114
  else {
114
- dataScript = `<script>var SCAN_DATA = ${jsonPayload};</script>`;
115
+ dataScript = `<script>var SCAN_DATA = ${jsonPayload.replace(/<\//g, '<\\/')};</script>`;
115
116
  }
116
117
  const dashboardHiddenClass = password ? ' hidden' : '';
117
118
  return `<!DOCTYPE html>
@@ -120,7 +121,7 @@ async function trySessionRestore() {
120
121
  <meta charset="UTF-8">
121
122
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
122
123
  <title>Trusera AI-BOM Dashboard</title>
123
- <script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"><\/script>
124
+ <script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js" integrity="sha384-bJFOSBzPRbfMrlRk8kGnSMA3t0DqP01GYIKZO9YFi5ZjdDbeqYeAzn9iUcbnrsnk" crossorigin="anonymous"><\/script>
124
125
  <style>
125
126
  :root {
126
127
  --bg: #0d1117;
@@ -693,17 +694,17 @@ function showComponentModal(idx) {
693
694
  modalRow('Provider', c.provider || '-') +
694
695
  modalRow('Model', c.modelName || '-') +
695
696
  modalRow('Version', c.version || '-') +
696
- modalRow('Severity', severityBadge(sev)) +
697
+ modalRow('Severity', severityBadge(sev), true) +
697
698
  modalRow('Risk Score', String(score)) +
698
699
  modalRow('Workflow', fp) +
699
- modalRow('OWASP Categories', owaspCats) +
700
+ modalRow('OWASP Categories', owaspCats, true) +
700
701
  modalRow('Source', c.source || '-') +
701
702
  flagsHtml +
702
703
  '</div></div>';
703
704
  }
704
705
 
705
- function modalRow(label, value) {
706
- return '<div class="modal-row"><div class="modal-label">' + esc(label) + '</div><div class="modal-value">' + (typeof value === 'string' && value.indexOf('<') !== -1 ? value : esc(value)) + '</div></div>';
706
+ function modalRow(label, value, isHTML) {
707
+ return '<div class="modal-row"><div class="modal-label">' + esc(label) + '</div><div class="modal-value">' + (isHTML ? value : esc(value)) + '</div></div>';
707
708
  }
708
709
 
709
710
  function closeModal(event) {
@@ -1 +1 @@
1
- {"version":3,"file":"dashboardHtml.js","sourceRoot":"","sources":["../../lib/dashboardHtml.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dashboardHtml.js","sourceRoot":"","sources":["../../lib/dashboardHtml.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TruseraWebhook.node.d.ts","sourceRoot":"","sources":["../../../nodes/TruseraWebhook/TruseraWebhook.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,SAAS,EACT,oBAAoB,EACrB,MAAM,cAAc,CAAC;AAKtB,qBAAa,cAAe,YAAW,SAAS;IAC9C,WAAW,EAAE,oBAAoB,CAyC/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CA+DtE"}
1
+ {"version":3,"file":"TruseraWebhook.node.d.ts","sourceRoot":"","sources":["../../../nodes/TruseraWebhook/TruseraWebhook.node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,SAAS,EACT,oBAAoB,EACrB,MAAM,cAAc,CAAC;AAkBtB,qBAAa,cAAe,YAAW,SAAS;IAC9C,WAAW,EAAE,oBAAoB,CAyC/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAsEtE"}
@@ -3,6 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TruseraWebhook = void 0;
4
4
  const scanner_1 = require("../../lib/scanner");
5
5
  const dashboardHtml_1 = require("../../lib/dashboardHtml");
6
+ /**
7
+ * Escape HTML special characters to prevent XSS in error messages.
8
+ * OWASP: A03:2021 - Injection (Cross-Site Scripting)
9
+ */
10
+ function escapeHtml(str) {
11
+ return str
12
+ .replace(/&/g, '&amp;')
13
+ .replace(/</g, '&lt;')
14
+ .replace(/>/g, '&gt;')
15
+ .replace(/"/g, '&quot;')
16
+ .replace(/'/g, '&#39;');
17
+ }
6
18
  class TruseraWebhook {
7
19
  constructor() {
8
20
  this.description = {
@@ -58,7 +70,7 @@ class TruseraWebhook {
58
70
  let cursor = null;
59
71
  do {
60
72
  const url = `${baseUrl}/api/v1/workflows?limit=100` +
61
- (cursor ? `&cursor=${cursor}` : '');
73
+ (cursor ? `&cursor=${encodeURIComponent(cursor)}` : '');
62
74
  const resp = await fetch(url, {
63
75
  headers: {
64
76
  'X-N8N-API-KEY': apiKey,
@@ -80,15 +92,22 @@ class TruseraWebhook {
80
92
  const scanResult = (0, scanner_1.scanWorkflows)(workflows);
81
93
  // Generate HTML dashboard
82
94
  const html = (0, dashboardHtml_1.generateDashboardHtml)(scanResult, password || undefined);
83
- // Serve HTML directly
95
+ // Serve HTML directly with security headers
84
96
  res.setHeader('Content-Type', 'text/html; charset=utf-8');
97
+ res.setHeader('X-Content-Type-Options', 'nosniff');
98
+ res.setHeader('X-Frame-Options', 'DENY');
99
+ res.setHeader('Referrer-Policy', 'no-referrer');
85
100
  res.status(200).end(html);
86
101
  }
87
102
  catch (err) {
103
+ // Escape error message to prevent reflected XSS via crafted error strings
104
+ // OWASP: A03:2021 - Injection (Cross-Site Scripting)
88
105
  res.setHeader('Content-Type', 'text/html; charset=utf-8');
106
+ res.setHeader('X-Content-Type-Options', 'nosniff');
107
+ res.setHeader('X-Frame-Options', 'DENY');
89
108
  res.status(500).end(`<!DOCTYPE html><html><body style="font-family:sans-serif;padding:40px">` +
90
109
  `<h1>Trusera Dashboard Error</h1>` +
91
- `<pre style="color:red">${err.message}</pre>` +
110
+ `<pre style="color:red">${escapeHtml(err.message)}</pre>` +
92
111
  `</body></html>`);
93
112
  }
94
113
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"TruseraWebhook.node.js","sourceRoot":"","sources":["../../../nodes/TruseraWebhook/TruseraWebhook.node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TruseraWebhook.node.js","sourceRoot":"","sources":["../../../nodes/TruseraWebhook/TruseraWebhook.node.ts"],"names":[],"mappings":";;;AAOA,+CAAkD;AAClD,2DAAgE;AAEhE;;;GAGG;AACH,SAAS,UAAU,CAAC,GAAW;IAC7B,OAAO,GAAG;SACP,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC5B,CAAC;AAED,MAAa,cAAc;IAA3B;QACE,gBAAW,GAAyB;YAClC,WAAW,EAAE,iBAAiB;YAC9B,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,kBAAkB;YACxB,KAAK,EAAE,CAAC,SAAS,CAAC;YAClB,OAAO,EAAE,CAAC;YACV,QAAQ,EAAE,uBAAuB;YACjC,WAAW,EACT,wHAAwH;YAC1H,QAAQ,EAAE;gBACR,IAAI,EAAE,iBAAiB;gBACvB,SAAS,EAAE,gBAAgB;aACQ;YACrC,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE;gBACX;oBACE,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,IAAI;iBACf;aACF;YACD,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,SAAS;oBACf,UAAU,EAAE,KAAK;oBACjB,YAAY,EAAE,UAAU;oBACxB,IAAI,EAAE,SAAS;oBACf,UAAU,EAAE,IAAI;iBACjB;aACF;YACD,UAAU,EAAE;gBACV;oBACE,WAAW,EAAE,oBAAoB;oBACjC,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC/B,OAAO,EAAE,EAAE;oBACX,WAAW,EACT,4GAA4G;iBAC/G;aACF;SACF,CAAC;IAwEJ,CAAC;IAtEC,KAAK,CAAC,OAAO;QACX,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAErC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;YACtD,MAAM,OAAO,GAAG,CAAE,KAAK,CAAC,OAAkB,IAAI,uBAAuB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YAC1F,MAAM,MAAM,GAAG,KAAK,CAAC,MAAgB,CAAC;YACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,EAAE,CAAW,CAAC;YAEjE,mDAAmD;YACnD,MAAM,YAAY,GAAmC,EAAE,CAAC;YACxD,IAAI,MAAM,GAAkB,IAAI,CAAC;YACjC,GAAG,CAAC;gBACF,MAAM,GAAG,GACP,GAAG,OAAO,6BAA6B;oBACvC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC1D,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBAC5B,OAAO,EAAE;wBACP,eAAe,EAAE,MAAM;wBACvB,QAAQ,EAAE,kBAAkB;qBAC7B;iBACF,CAAC,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;oBACb,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC,MAAM,IAAI,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;gBACxE,CAAC;gBACD,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAG9B,CAAC;gBACF,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChC,MAAM,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC;YACnC,CAAC,QAAQ,MAAM,EAAE;YAEjB,qBAAqB;YACrB,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;gBAC1C,IAAI,EAAE,EAAE;gBACR,QAAQ,EAAG,EAAE,CAAC,IAAe,IAAK,EAAE,CAAC,EAAa,IAAI,SAAS;aAChE,CAAC,CAAC,CAAC;YACJ,MAAM,UAAU,GAAG,IAAA,uBAAa,EAAC,SAAS,CAAC,CAAC;YAE5C,0BAA0B;YAC1B,MAAM,IAAI,GAAG,IAAA,qCAAqB,EAAC,UAAU,EAAE,QAAQ,IAAI,SAAS,CAAC,CAAC;YAEtE,4CAA4C;YAC5C,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;YAC1D,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;YACnD,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;YACzC,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAAC;YAChD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,0EAA0E;YAC1E,qDAAqD;YACrD,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,0BAA0B,CAAC,CAAC;YAC1D,GAAG,CAAC,SAAS,CAAC,wBAAwB,EAAE,SAAS,CAAC,CAAC;YACnD,GAAG,CAAC,SAAS,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;YACzC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CACjB,yEAAyE;gBACzE,kCAAkC;gBAClC,0BAA0B,UAAU,CAAE,GAAa,CAAC,OAAO,CAAC,QAAQ;gBACpE,gBAAgB,CACjB,CAAC;QACJ,CAAC;QAED,OAAO;YACL,iBAAiB,EAAE,IAAI;YACvB,YAAY,EAAE;gBACZ,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC;aAClE;SACF,CAAC;IACJ,CAAC;CACF;AAlHD,wCAkHC"}
@@ -8,6 +8,19 @@ import type {
8
8
  import { scanWorkflows } from '../../lib/scanner';
9
9
  import { generateDashboardHtml } from '../../lib/dashboardHtml';
10
10
 
11
+ /**
12
+ * Escape HTML special characters to prevent XSS in error messages.
13
+ * OWASP: A03:2021 - Injection (Cross-Site Scripting)
14
+ */
15
+ function escapeHtml(str: string): string {
16
+ return str
17
+ .replace(/&/g, '&amp;')
18
+ .replace(/</g, '&lt;')
19
+ .replace(/>/g, '&gt;')
20
+ .replace(/"/g, '&quot;')
21
+ .replace(/'/g, '&#39;');
22
+ }
23
+
11
24
  export class TruseraWebhook implements INodeType {
12
25
  description: INodeTypeDescription = {
13
26
  displayName: 'Trusera Webhook',
@@ -67,7 +80,7 @@ export class TruseraWebhook implements INodeType {
67
80
  do {
68
81
  const url =
69
82
  `${baseUrl}/api/v1/workflows?limit=100` +
70
- (cursor ? `&cursor=${cursor}` : '');
83
+ (cursor ? `&cursor=${encodeURIComponent(cursor)}` : '');
71
84
  const resp = await fetch(url, {
72
85
  headers: {
73
86
  'X-N8N-API-KEY': apiKey,
@@ -95,15 +108,22 @@ export class TruseraWebhook implements INodeType {
95
108
  // Generate HTML dashboard
96
109
  const html = generateDashboardHtml(scanResult, password || undefined);
97
110
 
98
- // Serve HTML directly
111
+ // Serve HTML directly with security headers
99
112
  res.setHeader('Content-Type', 'text/html; charset=utf-8');
113
+ res.setHeader('X-Content-Type-Options', 'nosniff');
114
+ res.setHeader('X-Frame-Options', 'DENY');
115
+ res.setHeader('Referrer-Policy', 'no-referrer');
100
116
  res.status(200).end(html);
101
117
  } catch (err) {
118
+ // Escape error message to prevent reflected XSS via crafted error strings
119
+ // OWASP: A03:2021 - Injection (Cross-Site Scripting)
102
120
  res.setHeader('Content-Type', 'text/html; charset=utf-8');
121
+ res.setHeader('X-Content-Type-Options', 'nosniff');
122
+ res.setHeader('X-Frame-Options', 'DENY');
103
123
  res.status(500).end(
104
124
  `<!DOCTYPE html><html><body style="font-family:sans-serif;padding:40px">` +
105
125
  `<h1>Trusera Dashboard Error</h1>` +
106
- `<pre style="color:red">${(err as Error).message}</pre>` +
126
+ `<pre style="color:red">${escapeHtml((err as Error).message)}</pre>` +
107
127
  `</body></html>`,
108
128
  );
109
129
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-trusera",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "n8n community node to scan workflows for AI security risks using Trusera AI-BOM",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",