mirror of
https://github.com/elicpeter/nyx.git
synced 2026-06-21 20:18:06 +02:00
Authorization analysis logic improvements (#61)
This commit is contained in:
parent
3c89bddbf2
commit
40995e45e7
55 changed files with 4193 additions and 134 deletions
|
|
@ -0,0 +1,60 @@
|
|||
// Nyx CVE benchmark fixture.
|
||||
//
|
||||
// CVE: CVE-2023-22621
|
||||
// Project: Strapi (strapi/strapi)
|
||||
// License: MIT (https://github.com/strapi/strapi/blob/develop/LICENSE)
|
||||
// Advisory: https://github.com/strapi/strapi/security/advisories/GHSA-2h87-4q2w-v4hf
|
||||
// Patched: 921d30961d6ba96cc098f2aea197350a49f990bd
|
||||
// packages/core/email/server/services/email.js:25-50
|
||||
//
|
||||
// Patched-fix simplification: `createStrictInterpolationRegExp` is
|
||||
// imported from `@strapi/utils` upstream; we inline a one-line stub
|
||||
// that builds a regex restricted to a fixed allowlist. The load-
|
||||
// bearing fix is the explicit `{ interpolate, evaluate: false,
|
||||
// escape: false }` options object passed to `_.template`, which
|
||||
// disables lodash's `<% ... %>` evaluate block. The trailing
|
||||
// `(data)` invocation of the compiled function is split off (matches
|
||||
// the corresponding split in `vulnerable.js`).
|
||||
//
|
||||
// Trim parity with `vulnerable.js`: same `attributes.reduce`-to-`for`
|
||||
// transformation; the load-bearing
|
||||
// `_.template(emailTemplate[attribute], { interpolate, evaluate: false, escape: false })`
|
||||
// call is verbatim from upstream's options-object form.
|
||||
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
const createStrictInterpolationRegExp = (allowed) =>
|
||||
new RegExp(`<%=\\s*(${allowed.join('|')})\\s*%>`, 'g');
|
||||
|
||||
const keysDeep = (obj) => Object.keys(obj || {});
|
||||
|
||||
const sendTemplatedEmail = (emailOptions = {}, emailTemplate = {}, data = {}) => {
|
||||
const attributes = ['subject', 'text', 'html'];
|
||||
const allowedInterpolationVariables = keysDeep(data);
|
||||
const interpolate = createStrictInterpolationRegExp(allowedInterpolationVariables);
|
||||
|
||||
const templatedAttributes = {};
|
||||
for (const attribute of attributes) {
|
||||
if (emailTemplate[attribute]) {
|
||||
const compiled = _.template(emailTemplate[attribute], {
|
||||
interpolate,
|
||||
evaluate: false,
|
||||
escape: false,
|
||||
});
|
||||
templatedAttributes[attribute] = compiled(data);
|
||||
}
|
||||
}
|
||||
return templatedAttributes;
|
||||
};
|
||||
|
||||
app.put('/users-permissions/email-templates', (req, res) => {
|
||||
sendTemplatedEmail({}, req.body.emailTemplate, req.body.data);
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
app.listen(1337);
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
// Nyx CVE benchmark fixture.
|
||||
//
|
||||
// CVE: CVE-2023-22621
|
||||
// Project: Strapi (strapi/strapi)
|
||||
// License: MIT (https://github.com/strapi/strapi/blob/develop/LICENSE)
|
||||
// Advisory: https://github.com/strapi/strapi/security/advisories/GHSA-2h87-4q2w-v4hf
|
||||
// Vulnerable: 479bdde67eb3759d89218c9686208be2409217ef
|
||||
// packages/core/email/server/services/email.js:23-39
|
||||
//
|
||||
// Strapi <= 4.5.5 compiled email-template strings via lodash `_.template`
|
||||
// without restricting the interpolation regex. An authenticated admin
|
||||
// could PUT /users-permissions/email-templates with a payload whose
|
||||
// `subject` / `text` / `html` field contained a lodash `<% ... %>`
|
||||
// evaluate block, which lodash compiles into a JavaScript Function. When
|
||||
// the email service rendered the template, the embedded JavaScript
|
||||
// executed in the Strapi process context (RCE).
|
||||
//
|
||||
// Trims: `keysDeep` import, `missingAttributes` early-throw, plugin
|
||||
// provider chain, the surrounding controller layer that translates
|
||||
// `PUT /email-templates` into a call to `sendTemplatedEmail`. The
|
||||
// load-bearing sink call `_.template(emailTemplate[attribute])` is
|
||||
// verbatim; the trailing `(data)` invocation of the compiled
|
||||
// function is split off so the engine sees the SSTI sink directly
|
||||
// rather than as the inner call of a `f()()` chain.
|
||||
|
||||
'use strict';
|
||||
|
||||
const _ = require('lodash');
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
const sendTemplatedEmail = (emailOptions = {}, emailTemplate = {}, data = {}) => {
|
||||
const attributes = ['subject', 'text', 'html'];
|
||||
const templatedAttributes = {};
|
||||
for (const attribute of attributes) {
|
||||
if (emailTemplate[attribute]) {
|
||||
const compiled = _.template(emailTemplate[attribute]);
|
||||
templatedAttributes[attribute] = compiled(data);
|
||||
}
|
||||
}
|
||||
return templatedAttributes;
|
||||
};
|
||||
|
||||
app.put('/users-permissions/email-templates', (req, res) => {
|
||||
sendTemplatedEmail({}, req.body.emailTemplate, req.body.data);
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
app.listen(1337);
|
||||
Loading…
Add table
Add a link
Reference in a new issue