apostrophecms / apostrophe

A full-featured, open-source content management framework built with Node.js that empowers organizations by combining in-context editing and headless architecture in a full-stack JS environment.
https://apostrophecms.com
MIT License
4.33k stars 589 forks source link

CSRF cookies don't set SameSite Attribute. Will soon be rejected by browsers. #2702

Closed poetaster closed 1 year ago

poetaster commented 3 years ago

Install from Git, last week.

Developer tools console shows:

Cookie “multisite-ckkclehap000k3i4sxv7zp87b.csrf” will be soon rejected because it has the “SameSite” attribute set to “None” or an invalid value, without the “secure” attribute. To know more about the “SameSite“ attribute, read https://developer.mozilla.org/docs/Web/HTTP/Headers/Set-Cookie/SameSite

To Reproduce

Step by step instructions to reproduce the behavior:

  1. Turn on Developer Console in FF or Chrome, etc.
  2. Observe warnings.

Expected behavior

SameSite attribute set?

Describe the bug

The SameSite Attribute is missing.

Details

Version of Node.js:

12.20.1

Server Operating System:

Debian Buster

boutell commented 3 years ago

You can address this as follows:

modules: {
  'apostrophe-express': {
    session: {
      cookie: {
        secure: true
        sameSite: 'none'
      }
    }
  }
}

If you are running apostrophe behind a proxy you will also need to pass the trustProxy: true option to apostrophe-express.

You only want to do either of these things in production. In local development ("node app" in your local terminal) secure: true would prevent you from logging in since when debugging locally you are not using HTTPS.

I thought we might need to make a core change here, but since we can't do this by default (it would break local development), I think this is really a documentation issue.

poetaster commented 3 years ago

Ah, ok, I develope on the same env as I deploy on with SSL (parallel virtual servers) but as you note, this is a reasonable solution. Thanks!

poetaster commented 3 years ago

Wouldn't it be easier still to set sameSite to strict? On the other hand mozzila says:

Secure Optional Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistent to man-in-the-middle attacks.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie

Perhaps secure is not a problem for localhost at all?

boutell commented 3 years ago

Interesting. That might be the case as long as it can be verified across browsers.

On Wed, Jan 27, 2021 at 9:36 AM Mark Washeim notifications@github.com wrote:

Wouldn't it be easier still to set sameSite to strict? On the other hand mozzila says:

Secure Optional Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistent to man-in-the-middle attacks.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie

Perhaps secure is not a problem for localhost at all?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/apostrophecms/apostrophe/issues/2702#issuecomment-768327574, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAH27JNUVJWNXSJMMMOYS3S4AQGJANCNFSM4WVISAYA .

--

THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER APOSTROPHECMS | apostrophecms.com | he/him/his

boutell commented 3 years ago

Defaulting to strict would be a bc break, though perhaps not for much longer.

On Wed, Jan 27, 2021 at 10:48 AM Tom Boutell tom@apostrophecms.com wrote:

Interesting. That might be the case as long as it can be verified across browsers.

On Wed, Jan 27, 2021 at 9:36 AM Mark Washeim notifications@github.com wrote:

Wouldn't it be easier still to set sameSite to strict? On the other hand mozzila says:

Secure Optional Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistent to man-in-the-middle attacks.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie

Perhaps secure is not a problem for localhost at all?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/apostrophecms/apostrophe/issues/2702#issuecomment-768327574, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAH27JNUVJWNXSJMMMOYS3S4AQGJANCNFSM4WVISAYA .

--

THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER APOSTROPHECMS | apostrophecms.com | he/him/his

--

THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER APOSTROPHECMS | apostrophecms.com | he/him/his

boutell commented 3 years ago

Defaulting to secure would be too, for A2. So probably we just need to document best practices here and possibly put something in apostrophe-boilerplate.

On Wed, Jan 27, 2021 at 10:48 AM Tom Boutell tom@apostrophecms.com wrote:

Defaulting to strict would be a bc break, though perhaps not for much longer.

On Wed, Jan 27, 2021 at 10:48 AM Tom Boutell tom@apostrophecms.com wrote:

Interesting. That might be the case as long as it can be verified across browsers.

On Wed, Jan 27, 2021 at 9:36 AM Mark Washeim notifications@github.com wrote:

Wouldn't it be easier still to set sameSite to strict? On the other hand mozzila says:

Secure Optional Cookie is only sent to the server when a request is made with the https: scheme (except on localhost), and therefore is more resistent to man-in-the-middle attacks.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie

Perhaps secure is not a problem for localhost at all?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/apostrophecms/apostrophe/issues/2702#issuecomment-768327574, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAH27JNUVJWNXSJMMMOYS3S4AQGJANCNFSM4WVISAYA .

--

THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER APOSTROPHECMS | apostrophecms.com | he/him/his

--

THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER APOSTROPHECMS | apostrophecms.com | he/him/his

--

THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER APOSTROPHECMS | apostrophecms.com | he/him/his

poetaster commented 3 years ago

You can address this as follows:

modules: {
  'apostrophe-express': {
    session: {
      cookie: {
        secure: true
        sameSite: 'none'
      }
    }
  }
}

If you are running apostrophe behind a proxy you will also need to pass the trustProxy: true option to apostrophe-express.

This generates:

/home/nodejs/cbosites/app.js:46 SameSite: 'secure' } ^^^^^^^^

SyntaxError: Unexpected identifier at wrapSafe (internal/modules/cjs/loader.js:915:16) at Module._compile (internal/modules/cjs/loader.js:963:27) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12) at internal/main/run_main_module.js:17:47 [nodemon] app crashed - waiting for file changes before starting...

boutell commented 3 years ago

I don't know exactly what you have here, but that's a syntax error being reported in your javascript code, not something at the apostrophe level. Maybe a missing comma.

boutell commented 3 years ago

Reopening because we should document best practices although we can't impose a setting for this.

poetaster commented 3 years ago

currently working:

   sites: {
   modules: {
     'apostrophe-express': {
        prefix: "",
        session: {
           prefix: "",
           cookie: {
              secure: true,
              sameSite: 'none',
            },
            trustProxy: true ,
          },
        trustProxy:true ,
     },

The first version of the error related that sameSite as key was unknown. I tried variations, SameSite, and other values.

As you can see, I'm unsure where to place trustProxy and or prefix. Probably don't need them anyway.

poetaster commented 3 years ago

Whoa. So now I'm slowly in real trouble. Good thing nothing is live.

I can't use the mutlidomain controller anymore:

On the console I get:

Tons of: Cookie “cbosites.csrf” will be soon treated as cross-site cookie against “https://apostrophe.newthinking.net/” because the scheme does not match. apostrophe.newthinking.net

Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”).

And a bunch of: Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/setImmediate.js (“script-src”).

For more or less ALL javascript. The javascript is not loading and I can no longer use the domain controller ... which make it impossible to use multi site. which leaves me going (quickly, I'm now out of time) for other software.

What in the world can I do? TURN OFF CORS?

poetaster commented 3 years ago

I'm very confused. I've changed nothing in the dashboard app.

https://apotest-1.newthinking.net/ is still available. The settings (where express is concerned) where 1. not set for dash.

I tried. Set apostrophe-express modules settings to be the same. Fail. Well, they are on a subdomain,....? I tried. secure: false in the express settings for dashboard? Fail. Ok...

Is this all a problem with subdomains? the domain controller, for obvious reasons, is a subdomain.

How in the world to I resolve this issue. And why did it appear now?

boutell commented 3 years ago

It sounds like you added a content security policy header to your project. That header needs to allow what Apostrophe is doing in order for Apostrophe to work.

However "scheme does not match" probably means you're mixing HTTP and HTTPS.

On Wed, Mar 10, 2021 at 10:49 AM Mark Washeim @.***> wrote:

I'm very confused. I've changed nothing in the dashboard app.

https://apotest-1.newthinking.net/ is still available. The settings (where express is concerned) where 1. not set for dash.

I tried. Set apostrophe-express modules settings to be the same. Fail. Well, they are on a subdomain,....? I tried. secure: false in the express settings for dashboard? Fail. Ok...

Is this all a problem with subdomains? the domain controller, for obvious reasons, is a subdomain.

How in the world to I resolve this issue. And why did it appear now?

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/apostrophecms/apostrophe/issues/2702#issuecomment-795634762, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAH27LT4WM5GRPOM74YDH3TC6IGXANCNFSM4WVISAYA .

--

THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER APOSTROPHECMS | apostrophecms.com | he/him/his

poetaster commented 3 years ago

No. I did not. The proxy only permits SSL/HTTPS. The install of dashboard is untouched (and worked until I changed SITES), outside of the data stored in mongo.

This is amazing. I made:

  1. No changes to the proxy.
  2. No changes to the config for the dashboard
  3. Changes to the /sites config (for the palette module).

And sites can't be managed. This is just way too much 'unclear'.

I can strip the headers with the proxy, but I no longer believe this is production ready software.

poetaster commented 3 years ago

This is from the dashboard (no CSP/CORS header set in apps.js oder data.js).

Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”). apostrophe.newthinking.net:155:1 Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/setImmediate.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/lodash.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/async.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/moment.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery-url-parser.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery-ui.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery-hotkeys.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.iframe-transport.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.fileupload.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/cropper.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery-textchange.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/pikaday.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.cookie.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.findSafe.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.onSafe.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.alter-class.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/sluggo.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/spectrum.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.scrollintoview.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.get-outer-html.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.find-by-name.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.projector.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.bottomless.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.selective.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.images-ready.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.radio.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/jquery.json-call.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/moog.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-assets/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-admin-bar/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-login/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-login/js/reset-known-password-modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-notifications/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-browser-utils/js/lean.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-browser-utils/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-ui/js/ui.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-ui/js/context.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-schemas/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-schemas/js/array-modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-docs/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-jobs/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-jobs/js/modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-versions/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-versions/js/editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-doc-type-manager/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-pieces/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-tags/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-pieces/js/manager-modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-tags/js/manager-modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-modal/js/modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-attachments/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-attachments/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-attachments/js/cropEditor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-attachments/js/focal-point-editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-oembed/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-doc-type-manager/js/chooser.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-global/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-doc-type-manager/js/relationship-editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-pieces/js/editor-modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-pieces/js/batch-permissions-modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-polymorphic-manager/js/chooser-modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-polymorphic-manager/js/chooser.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-pages/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-pages/js/editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-pages/js/reorganize.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-pages/js/vendor/tree.jquery.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-pages/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-search/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-any-page-manager/js/chooser.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-any-page-manager/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-areas/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-areas/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-areas/js/beforeCkeditor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-areas/js/vendor/ckeditor/ckeditor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-areas/js/editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-areas/js/splitHtml.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-widgets/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-rich-text-widgets/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-widgets/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-rich-text-widgets/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-widgets/js/editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-rich-text-widgets/js/editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-video-fields/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-video-widgets/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-users/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-users/js/editor-modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-images/js/chooser.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-images/js/relationship-editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-images/js/manager-modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-images/js/editor-modal.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-images/js/focal-point-editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-images/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-images-widgets/js/always.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-pieces-widgets/js/editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-images-widgets/js/editor.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-files/js/user.js (“script-src”). Content Security Policy: The page’s settings blocked the loading of a resource at https://apostrophe.newthinking.net/modules/apostrophe-files/js/editor-modal.js (“script-src”).

poetaster commented 3 years ago

the config:

`const hostname = '127.0.0.1';
const port = 3000;

const multi = require('apostrophe-multisite')({

  // An API key is required for interserver communication.
  // Make it unique and secure, not this
  apiKey: '********************',

  // For speed and availability, make sure a site is live on this many
  // processes, on separate servers when possible. Processes are SHARED
  // by MANY sites, but setting this high still uses more RAM
  concurrencyPerSite: 4,

  // If we receive no new requests for a site in an hour,
  // let that apos object go, freeing up RAM in exchange for
  // a little extra spinup time on the next request
  timeout: 60 * 60,

  shortNamePrefix: process.env.SHORTNAME_PREFIX || 'multisite-',

  // MongoDB URL for database connection. If you have multiple physical
  // servers then you MUST configure this to a SHARED server (which
  // may be a replica set). Can be set via MONGODB_URL env var
  mongodbUrl: 'mongodb://localhost:27017',

  // Hostname of the dashboard site. Distinct from the hosted sites.
  dashboardHostname: 'apostrophe.newthinking.net',

  // Session secret. Please use a unique string.
  sessionSecret: '**********',

  // Apostrophe configuration for your hosted sites.
  // Just one config for all of them; per-site config could be
  // user editable settings in apostrophe-global.
  // You can also do much more in `sites/lib/modules`,
  // following Apostrophe's usual patterns

  sites: {
   modules: {
   /*'apostrophe-express': {
     prefix: "",
     session: { 
         prefix: "",
       cookie: { 
         secure: true,
         sameSite: 'none',
       }, 
       trustProxy: true ,
     }, 
     trustProxy:true ,
   }, */
    'helpers': { extend: 'apostrophe-module' },
    'styleguide': {},
    'apostrophe-seo': {},
    'apostrophe-open-graph': {},
    'apostrophe-pieces-import': {},
    'apostrophe-favicons': {},
    //'apostrophe-favicons-global': {},
    'default-pages': { extend: 'apostrophe-custom-pages' },
    // Categorical "meta" piece types
    'category-object-types': { extend: 'apostrophe-pieces' },
    'artists': { extend: 'apostrophe-pieces' },
    'artists-pages': { extend: 'apostrophe-pieces-pages' },
    'locations': {
      extend: 'apostrophe-pieces',
      'mapQuest': {
        key: 'twADhGQBQQW3R9laAAzA0UaTj5Rrrskj',
        secret: 'stTrrmLbEcY9B9Wc'
      }
    },
    'locations-widgets': { extend: 'apostrophe-widgets' },
    'artworks': { extend: 'apostrophe-pieces' },
    'artworks-pages': { extend: 'apostrophe-pieces-pages' },
    'artworks-widgets': { extend: 'apostrophe-pieces-widgets' },

    'articles': { extend: 'apostrophe-blog' },
    'articles-pages': { extend: 'apostrophe-pieces-pages' },
    'articles-widgets': { extend: 'apostrophe-pieces-widgets' },
    'articles-featured-widgets': { extend: 'apostrophe-widgets' },

    'events': { extend: 'apostrophe-events' },
    'events-pages': { extend: 'apostrophe-pieces-pages' },
    'events-widgets': { extend: 'apostrophe-pieces-widgets' },

    'people': { extend: 'apostrophe-pieces' },
    'people-pages': { extend: 'apostrophe-pieces-pages' },
    // Content Widgets
    'image-widgets': { extend: 'apostrophe-widgets' },
    'slideshow-widgets': { extend: 'apostrophe-widgets' },
    'logo-mask-widgets': { extend: 'apostrophe-widgets' },
    'link-widgets': { extend: 'apostrophe-widgets' },
    'marquee-widgets': { extend: 'apostrophe-widgets' },
    'feature-widgets': { extend: 'marquee-widgets' },
    'two-panel-widgets': { extend: 'apostrophe-widgets' },
    'content-widgets': { extend: 'apostrophe-widgets' },
    'random-met-artwork-widgets': { extend: 'apostrophe-widgets' },
    'apostrophe-palette-admin-bar': {},
    'apostrophe-palette-widgets': {},
    'apostrophe-palette': {},
    'apostrophe-palette-global': {
    paletteFields: [ // array of fields, like a normal schema
      {
        name: 'backgroundColor',
        label: 'Background color of the website',
        type: 'color',
        selector: 'body',
        property: 'background-color',
      },
      {
        name: 'featureBlockBG',
        label: 'Feature Block Background',
        type: 'color',
        selector: '.o-background-light',
        property: 'background-color',
      },
      {
        name: 'headerBlockBG',
        label: 'Header Block Background',
        type: 'color',
        selector: '.c-header',
        property: 'background-color',
      },
      {
        name: 'footerBlockBG',
        label: 'Footer Block Background',
        type: 'color',
        selector: '.c-footer',
        property: 'background-color',
      },
      {
        name: 'mastHeadColor',
        label: 'Masthead Color',
        type: 'color',
        selector: '.c-masthead',
        property: 'color',
      },
      {
        name: 'mastheadVisi',
        label: 'Masthead Visibility',
        type: 'string',
        selector: '.c-masthead',
        property: 'display',
      },
      {
        name: 'bodyColor',
        label: 'Body Link Color',
        type: 'color',
        selector: '.o-body a',
        property: 'color',
      },
    ]
  },
    // Layout Widgets
    'columns-widgets': { extend: 'apostrophe-widgets' },

      'apostrophe-users': { groups: [ { title: 'admin', permissions: [ 'admin' ] } ] },
    },
  'apostrophe-assets':{ minify:'true' },
  },

  // Apostrophe configuration for the dashboard site.
  // A `sites` module always exists, a piece that governs
  // multisite management and has a hostnames property.
  // You can also do much more in `dashboard/lib/modules`,
  // following Apostrophe's usual patterns

  dashboard: {
    modules: {
      'apostrophe-users': {
        groups: [
          {
            title: 'admin',
            permissions: [ 'admin' ]
          }
        ]
      },
      // Further configure the pieces module that represents sites. Perhaps
      // you wish to add some custom fields in the usual way
      'sites': {
        addFields: [ ]
      }
    }
  }
}).then(function(result) {
  if (result === 'task') {
    console.log('Running task...');
  } else {
    // top level await is not a thing, so handle the promise
    console.log('Running...');
  }
}).catch(function(err) {
  console.error(err);
  process.exit(1);
});
`
poetaster commented 3 years ago

Oh and if you'd like to see CORS/CSP headers I set explicitly, knowing what I want and how it works, see: https://netzpolitik.org I've been doing this for a living for 30 years. ... And I'm out of time.

poetaster commented 3 years ago

This is really strange. I get errors like:

Loading failed for the 

No wonder stripping the headers with the web server doesn't work. The client is screwing it up. It's followd by a bunch of:

         apos.csrf();
  apos.prefixAjax();
....
poetaster commented 3 years ago

Ah, dammit. It's all javascript up and down.

So. I got it. And I really think it's wrong.

CSP is being set IN JAVASCRIPT (there are No headers set by the server because I STRIP THEM). This is BAD.

The whole point of CSP is to ensure that a policy set for the domain can't be interfered with from outside. Outside IS the browser. It IS javascript.

If the SERVER (not javascript in the client) sets the CORS/CSP headers and the browser isn't broken, then no injected crap will be loaded.

What we have here is a case where the Javascript doesn't evaluate and you get wrong CORS/CSP behaviour. THIS IS NOT clear. It could be a bug in FF.

What?! So the devs now determine how the sysadmin deals with bad behaviour? no way.

It's effectively countermanding my core header setting routines from the server. Sorry. The client does NOT get to determine how the firewall works.

poetaster commented 3 years ago

Oh, yeah. and the app works. But I will not deploy this in production. It's a trojan horse waiting to happen. I'll do some pentesting for fun.

On the other hand, maybe Firefox is broken. I turned off javascript (just to test a hypothesis) and it STILL produced CSP warnings. Which doesn't really make sense, since turning off javascript client side has nothing to do with CSP/CORS et. al. Chrome produced the same warnings about the future deprecation (strange!) but NOT the CSP refusal to load.

Frankly I'm a bit confused.

In any case, I know how to use CSP and CORS and do so judiciously (with wordpress behind haproxy/varnish, for instance), with drupal (same proxies) with node.js (same proxies etherpad/ethercalc) with go (pydio/cells) and other backends. Never seen anything like this.

But I think this is maybe a new ticket. other ticket.

boutell commented 3 years ago

Hi @poetaster,

To be honest I'm having trouble tracking down which balls you still consider to be in play in this thread. It's a lot to take in.

But one point that catches my eye is your concern that we're injecting inline script tags. I understand that concern, which is why Apostrophe 3.x does not do it. Data is injected only as data attributes and code is only loaded via "script src".

But Apostrophe 2.x, which has been around since before CSP was a common expectation and needs to remain backwards compatible, will continue to operate in the same manner in this area.

I'd welcome your input on the 3.x alpha:

https://a3.docs.apostrophecms.org/

Also, if you're in need of a commercial level of support I encourage you to reach out to us to start a business relationship:

https://apostrophecms.com/pricing

poetaster commented 3 years ago

Sorry about the cross-talk and low signal to noise ratio. The problem was nothing more than a test stage with a browser profile that turns off javascript. That this generated CSP warnings for every script file request makes 0 sense. That scripts don't load, if javascript is turned off makes perfect sense.

I only noticed what was going on when I switched to chrome and went through the details of the FF profile. I'm inclined to say it's a bug in firefox since you get the expected behaviour in chrome.

As for the inline injecting, it's a bit of a hot potato but I'll have a look at apos.csrf(); and see what I can see.

And I'll have a look at a3 ASAP ... I'm under pressure for this release to go live so these issues first.

Thanks for your time and patience. I always find the odd edge cases.

felixlberg commented 3 years ago

I would like to join the discussion and ask if trustProxy: true also means a reverse proxy like you typically use with nginx in production to forward to port 3000?

To avoid the problem with local development i can recommend to do the customizations for apostrophe-express in data/local.js. I have had good experiences with this as well to set the session secret because i don`t want to have it public in my repo:

// data/local.js

module.exports = {
  baseUrl: 'http://localhost:3000',
  modules: {
    'apostrophe-express': {
      session: {
        secret: 'SECRET'
      }
    }
  }
};
boutell commented 3 years ago

Yes, trustProxy: true is for running behind a reverse proxy like nginx.

data/local.js is a good technique for small servers. For cloud deployments you can put environment variable checks in your repo, i.e. secret: process.env.SESSION_SECRET, and set those env vars in your cloud platform.

felixlberg commented 3 years ago

Thx, that is really interesting.