New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
CSRF cookies don't set SameSite Attribute. Will soon be rejected by browsers. #2702
Comments
You can address this as follows:
If you are running apostrophe behind a proxy you will also need to pass the You only want to do either of these things in production. In local development ("node app" in your local terminal) 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. |
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! |
Wouldn't it be easier still to set sameSite to strict? On the other hand mozzila says: Secure Optional https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie Perhaps secure is not a problem for localhost at all? |
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 ***@***.***> 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
<#2702 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAH27JNUVJWNXSJMMMOYS3S4AQGJANCNFSM4WVISAYA>
.
--
THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER
APOSTROPHECMS | apostrophecms.com | he/him/his
|
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 ***@***.***> 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 ***@***.***>
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
> <#2702 (comment)>,
> 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
|
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 ***@***.***> 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 ***@***.***>
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 ***@***.***>
> 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
>> <#2702 (comment)>,
>> 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
|
This generates: /home/nodejs/cbosites/app.js:46 SyntaxError: Unexpected identifier |
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. |
Reopening because we should document best practices although we can't impose a setting for this. |
currently working:
The first version of the error related that sameSite as key was unknown. As you can see, I'm unsure where to place trustProxy and or prefix. Probably don't need them anyway. |
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: Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”). And a bunch of: 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? |
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,....? 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? |
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
<#2702 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAH27LT4WM5GRPOM74YDH3TC6IGXANCNFSM4WVISAYA>
.
--
THOMAS BOUTELL | CHIEF TECHNOLOGY OFFICER
APOSTROPHECMS | apostrophecms.com | he/him/his
|
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:
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. |
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 |
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); }); ` |
Oh and if you'd like to see CORS/CSP headers I set explicitly, knowing what I want and how it works, see: |
This is really strange. I get errors like: Loading failed for the <script> with source “https://apostrophe.newthinking.net/modules/apostrophe-assets/js/vendor/setImmediate.js”. apostrophe.newthinking.net:158:1 But can certainly fetch the resource. Where is the protocol missing? or incorrect? |
Ah, what in the world is this: <script> window.apos = {"prefix":"","csrfCookieName":"multisite-dashboard.csrf","htmlPageId":"ckm3rhor30005984seu2uhgmf","uploadsUrl":"/uploads/dashboard"} </script> 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(); .... |
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. |
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. |
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: |
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. |
I would like to join the discussion and ask if To avoid the problem with local development i can recommend to do the customizations for // data/local.js
module.exports = {
baseUrl: 'http://localhost:3000',
modules: {
'apostrophe-express': {
session: {
secret: 'SECRET'
}
}
}
}; |
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. |
Thx, that is really interesting. |
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:
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
The text was updated successfully, but these errors were encountered: