From ec57ebde52f5da16524f5275f923eedc8c0ab19a Mon Sep 17 00:00:00 2001 From: Voon Siong Wong Date: Sat, 30 Jul 2022 21:49:25 +0000 Subject: [PATCH] feat: apply cspNonce when client reordering (#1836) * feat: apply cspNonce when client reordering --- .changeset/silver-apricots-tell.md | 5 +++ .../core/await/reorderer-renderer.js | 34 +++++++++++++++---- .../expected-events-vdom.json | 24 +++++++++++++ .../expected-events.json | 27 +++++++++++++++ .../expected.html | 1 + .../template.marko | 8 +++++ .../await-client-reorder-cspnonce/test.js | 29 ++++++++++++++++ .../expected-events-vdom.json | 24 +++++++++++++ .../expected-events.json | 30 ++++++++++++++++ .../expected.html | 1 + .../template.marko | 8 +++++ .../await-client-reorder-cspnonce/test.js | 28 +++++++++++++++ 12 files changed, 212 insertions(+), 7 deletions(-) create mode 100644 .changeset/silver-apricots-tell.md create mode 100644 packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected-events-vdom.json create mode 100644 packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected-events.json create mode 100644 packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected.html create mode 100644 packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/template.marko create mode 100644 packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/test.js create mode 100644 packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected-events-vdom.json create mode 100644 packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected-events.json create mode 100644 packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected.html create mode 100644 packages/marko/test/render/fixtures/await-client-reorder-cspnonce/template.marko create mode 100644 packages/marko/test/render/fixtures/await-client-reorder-cspnonce/test.js diff --git a/.changeset/silver-apricots-tell.md b/.changeset/silver-apricots-tell.md new file mode 100644 index 0000000000..67a86c05ec --- /dev/null +++ b/.changeset/silver-apricots-tell.md @@ -0,0 +1,5 @@ +--- +"marko": patch +--- + +Avoid inline styles when using tight Content Security Policy diff --git a/packages/marko/src/core-tags/core/await/reorderer-renderer.js b/packages/marko/src/core-tags/core/await/reorderer-renderer.js index a47296d22f..15a079aea5 100644 --- a/packages/marko/src/core-tags/core/await/reorderer-renderer.js +++ b/packages/marko/src/core-tags/core/await/reorderer-renderer.js @@ -1,5 +1,8 @@ "use strict"; +var escapeDoubleQuotes = + require("../../../runtime/html/helpers/escape-quotes").___escapeDoubleQuotes; + module.exports = function (input, out) { // We cannot call beginSync() when using renderSync(). In this case we will // ignore the await-reorderer tag. @@ -54,13 +57,30 @@ module.exports = function (input, out) { global._afRuntime = true; } - asyncOut.write( - '" - ); + if (global.cspNonce) { + asyncOut.write( + '" + + '
' + + result.toString() + + "
" + ); + } else { + asyncOut.write( + '" + ); + } asyncOut.script( "$af(" + diff --git a/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected-events-vdom.json b/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected-events-vdom.json new file mode 100644 index 0000000000..028b3e1748 --- /dev/null +++ b/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected-events-vdom.json @@ -0,0 +1,24 @@ +[ + { + "event": "await:begin", + "arg": { + "name": "data.outer", + "clientReorder": false + } + }, + { + "event": "await:beforeRender", + "arg": { + "name": "data.outer", + "clientReorder": false + } + }, + { + "event": "await:finish", + "arg": { + "name": "data.outer", + "clientReorder": false, + "finished": true + } + } +] diff --git a/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected-events.json b/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected-events.json new file mode 100644 index 0000000000..1cd8b240c2 --- /dev/null +++ b/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected-events.json @@ -0,0 +1,27 @@ +[ + { + "event": "await:begin", + "arg": { + "name": "input.outer", + "clientReorder": true, + "id": 0 + } + }, + { + "event": "await:beforeRender", + "arg": { + "name": "input.outer", + "clientReorder": true, + "id": 0 + } + }, + { + "event": "await:finish", + "arg": { + "name": "input.outer", + "clientReorder": true, + "id": 0, + "finished": true + } + } +] \ No newline at end of file diff --git a/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected.html b/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected.html new file mode 100644 index 0000000000..c24e9d4852 --- /dev/null +++ b/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/expected.html @@ -0,0 +1 @@ +

Foo

Hello World
diff --git a/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/template.marko b/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/template.marko new file mode 100644 index 0000000000..269a2dab6d --- /dev/null +++ b/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/template.marko @@ -0,0 +1,8 @@ + + <@then|outer|> +
+

Foo

Hello World +
+ + + \ No newline at end of file diff --git a/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/test.js b/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/test.js new file mode 100644 index 0000000000..f6b4504e19 --- /dev/null +++ b/packages/marko/test/render/fixtures-async-callback/await-client-reorder-cspnonce/test.js @@ -0,0 +1,29 @@ +var extend = require("raptor-util/extend"); +var expect = require("chai").expect; +const { callbackProvider } = require("../../../__util__/async-helpers"); + +exports.templateData = { + outer: callbackProvider(1, {}), + $global: { + cspNonce: "xyz" + } +}; + +exports.checkEvents = function (events, snapshot, out) { + events = events.map(function (eventInfo) { + var arg = extend({}, eventInfo.arg); + expect(arg.out != null).to.equal(true); + + delete arg.out; // Not serializable + delete arg.asyncValue; // Not serializable + + return { + event: eventInfo.event, + arg: arg + }; + }); + + snapshot(events, out.isVDOM ? "-events-vdom.json" : "-events.json"); +}; + +exports.skip_vdom = "client-reorder/placeholders are not supported in vdom"; diff --git a/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected-events-vdom.json b/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected-events-vdom.json new file mode 100644 index 0000000000..028b3e1748 --- /dev/null +++ b/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected-events-vdom.json @@ -0,0 +1,24 @@ +[ + { + "event": "await:begin", + "arg": { + "name": "data.outer", + "clientReorder": false + } + }, + { + "event": "await:beforeRender", + "arg": { + "name": "data.outer", + "clientReorder": false + } + }, + { + "event": "await:finish", + "arg": { + "name": "data.outer", + "clientReorder": false, + "finished": true + } + } +] diff --git a/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected-events.json b/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected-events.json new file mode 100644 index 0000000000..7f846ed7a5 --- /dev/null +++ b/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected-events.json @@ -0,0 +1,30 @@ +[ + { + "event": "await:begin", + "arg": { + "name": "input.outer", + "clientReorder": true, + "dataProvider": {}, + "id": 0 + } + }, + { + "event": "await:beforeRender", + "arg": { + "name": "input.outer", + "clientReorder": true, + "dataProvider": {}, + "id": 0 + } + }, + { + "event": "await:finish", + "arg": { + "name": "input.outer", + "clientReorder": true, + "dataProvider": {}, + "id": 0, + "finished": true + } + } +] \ No newline at end of file diff --git a/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected.html b/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected.html new file mode 100644 index 0000000000..50c49dc66d --- /dev/null +++ b/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/expected.html @@ -0,0 +1 @@ +

Foo

Hello World
diff --git a/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/template.marko b/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/template.marko new file mode 100644 index 0000000000..269a2dab6d --- /dev/null +++ b/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/template.marko @@ -0,0 +1,8 @@ + + <@then|outer|> +
+

Foo

Hello World +
+ + + \ No newline at end of file diff --git a/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/test.js b/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/test.js new file mode 100644 index 0000000000..c7044a3f05 --- /dev/null +++ b/packages/marko/test/render/fixtures/await-client-reorder-cspnonce/test.js @@ -0,0 +1,28 @@ +var extend = require("raptor-util/extend"); +var expect = require("chai").expect; + +exports.templateData = { + outer: Promise.resolve(), + $global: { + cspNonce: "xyz" + } +}; + +exports.checkEvents = function (events, snapshot, out) { + events = events.map(function (eventInfo) { + var arg = extend({}, eventInfo.arg); + expect(arg.out != null).to.equal(true); + + delete arg.out; // Not serializable + delete arg.asyncValue; // Not serializable + + return { + event: eventInfo.event, + arg: arg + }; + }); + + snapshot(events, out.isVDOM ? "-events-vdom.json" : "-events.json"); +}; + +exports.skip_vdom = "client-reorder/placeholders are not supported in vdom";