October: Proposal: Implement new cross origin security APIs

Created on 28 Dec 2020  路  8Comments  路  Source: octobercms/october

Over the last few months browsers have been adding many new and exciting api's to get a grip on cross-origin attacks.

Over the coming weeks to months I would like to slowly upgrade October CMS to start locking down these types of attacks.

Example of attack

In 2018 the crypto exchange gate.io got hacked. They were using a third party script to measure analytics from the company statcounter.

The hackers didn't touch the gate.io exchange code at all.

Instead they hacked the code hosted on the location www.statcounter[.]com/counter/counter.js

When a user went to a certain url on the gate.io exchange website, the code in the counter.js would detect that url and perform the attack, under certain criteria. In this case the code was searching for people trading bitcoin and confirmed they have bitcoin in their wallets, before sending the confirmed bitcoin to the hackers address. People who didn't have bitcoin but other cryptocurrencies the hackers code left alone.

October CMS

To me the backend of the cms should be harden and isolated from the whole world, only allowing the admins access!

This means two things to me.

  1. The CMS requesting files and resources from third-parties through cross-origins need to be locked down.
  2. Plugin and theme developers need to understand this attack. There are many plugins in the marketplace that allow questionable unchecked third-party cross-origin code to be loaded into the backend of the cms with little to no checks.

Hardening October

Three main ideas that come to mind are as follows:

  1. Start adding these new api's into October and allow users to customize the options in the config files. For example:
    /*
    |--------------------------------------------------------------------------
    | Cross-Origin-Opener-Policy
    |--------------------------------------------------------------------------
    |
    | The HTTP Cross-Origin-Opener-Policy (COOP) response header 
    | allows you to ensure a top-level document does not share a 
    | browsing context group with cross-origin documents.
    | 
    | COOP will process-isolate your document and potential attackers 
    | can't access to your global object if they were opening it in a popup, 
    | preventing a set of cross-origin attacks dubbed XS-Leaks.
    |
    | `unsafe-none` - This is the default value. Allows the document to be 
    | added to its opener's browsing context group unless the opener itself 
    | has a COOP of same-origin or same-origin-allow-popups.
    | 
    | `same-origin-allow-popups` - Retains references to newly opened 
    | windows or tabs which either don't set COOP or which opt out of 
    | isolation by setting a COOP of unsafe-none.
    | 
    | `same-origin` - Isolates the browsing context exclusively to same-origin
    | documents. Cross-origin documents are not loaded in the same 
    | browsing context.
    */

    'coop' => 'same-origin',
  1. Add a section in the config that allows users to whitelist third-party cross-origin files and resources and block everything else. For example:
    /*
    |--------------------------------------------------------------------------
    | Whitelist cross origins in the backend
    |--------------------------------------------------------------------------
    |
    | Whitelist cross origin website url's or whole domains that you trust
    | and allow them to have access to the backend. If the url or domain
    | is not listed, it will automatically be blocked, to prevent a possible
    | attack.
    */

    'whitelistCrossOrigins' => [ 'https://www.google-analytics.com', 'https://www.googletagmanager.com/gtag/js' ], 

A hacker then injects code into the file https://www.googletagmanager.com/gtag/js that grabs a payload from https://www.evil.com/, because the payload website is not in the whitelist, October will automatically blocked it from loading into the backend.

  1. The new api's in point 1 are different from Subresource Integrity (SRI) API. Developers are also encouraged to use this api as well. For example:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha384-ZvpUoO/+PpLXR1lu4jmpXWu80pZlYUAfxl5NsBMWOEPSjUn/6Z/hRTt8+pR6L4N2" crossorigin="anonymous"></script>

This one down to the developer.

List of API's

  • COEP: Cross Origin Embedder Policy
  • COOP: Cross Origin Opener Policy
  • CORP: Cross Origin Resource Policy
  • CORS: Cross Origin Resource Sharing
  • CORB: Cross Origin Read Blocking
  • Cross-Origin-Embedder-Policy-Report-Only
  • Cross-Origin-Opener-Policy-Report-Only
  • SRI: Subresource Integrity

Work Flow

Questions you need to ask.

  1. Is the file or asset being hosted from the same-site?
  2. Is the file or asset being hosted from a third-party cross-origin site that you have full control over?
  3. Is the file or asset being hosted from a third-party cross-origin site that you do not have full control over?

PR's

Over time gonna submit and link PR's to this issue, please keep it open as more than one pr will be submitted over time.

Questions

If you got questions, please do your own research!

Archived Conceptual Enhancement

All 8 comments

@ayumi-cloud I feel these types of headers are best done at the server level, as I have stated previously. If done at the application level, you have an extra vector to consider for hardening - someone could simply code a plugin that changes these configuration values at run-time, disabling the cross-site headers and allowing malicious assets to load once more. I know (at least with Apache) that it is possible to force these headers after PHP has run but before the headers are sent.

In the near future the gateway.octobercms.com needs to be updated with the new security headers. The reason is because it's making cross-origin requests to the cms backend with the plugins and themes. Can't update the cms until the external servers have been updated (correctly isolated).

@bennothommo

What you commented is not correct about the api's, please do your own research. Also what you previously stated was about your pr and not about these api's they work differently. I don't want to break down your comment and explain the errors.

@ayumi-cloud Please explain what I said in my comment that was wrong. You are indicating that you intend to introduce configuration options for functionality which, if I'm correct, will, a) insert a "Cross-Origin-Opener-Policy" response header, and b) define a whitelist of cross-origin domains. What I am indicating is that any mechanism that you intend to actually populate this header will generally be the last thing that is called in the request pipeline, which means at any point before this, someone can modify the configuration.

please do your own research

Nothing is getting into October CMS code unless the maintainers understand it. So the prerogative is on you to explain it.

@bennothommo

Sure I will try my best to explain and break everything down for you!

will generally be the last thing that is called in the request pipeline

Not correct, these api's are actually the first thing (not last) in the request chain and load before the php code, service workers and the cache etc! Let me show you an example screenshot:

image

If done at the application level, you have an extra vector to consider for hardening - someone could simply code a plugin that changes these configuration values at run-time, disabling the cross-site headers and allowing malicious assets to load once more. I know (at least with Apache) that it is possible to force these headers after PHP has run but before the headers are sent.

Site A is my October cms website.
Site B is a third-party website.

We are going to make a fetch request from Site A to Site B to grab something. Site B has CORS turned on (although every website now has CORS turned on by default). Site A has a plugin to request the data from Site B. Site A also tries to change the HTTP Headers of Site B's CORS policy. Site A's plugin can't change the HTTP Headers of Site B's CORS policy.

So someone could simply code a plugin that changes these configuration values at run-time, disabling the cross-site headers and allowing malicious assets to load once more wouldn't be true!

Take note all the new api's work the same way like CORS. Also you saying at run-time is not correct! For example, before I even make a request from Site A to Site B, Site B has CORS already turned on before the run-time has even taken place!

Nothing is getting into October CMS code unless the maintainers understand it. So the prerogative is on you to explain it.

Yes, totally understand. Let's try and give this a bash and explain more...

Instead of a hacker bothering to hack each website using the October CMS platform, they can save time and hack a single point of failure! In this case it would be the gateway.octobercms.com location, which is used by all the websites running the October CMS platform to download their plugins and themes etc. A hacker just needs to go to the marketplace and check which plugin and themes are being most downloaded. A quick search, suggests to use the Rainlab Static Pages plugin that has 119,564 installations and Rainlab Blog plugin having 109,771 installations. So there is a high chance of these two plugins being downloaded in the future. The hacker has several methods of attack.

One issue with the current October setup is that it's not using a hash method on every single new release for a plugin or theme! There's no automatic flag if the hacker changed the code in the plugin or theme passing through the gateway.octobercms.com location.

I don't know if the plugins are stored on the gateway.octobercms.com server location? If so you just need modify the code located there. Or if the gateway.octobercms.com is acting as a proxy and you can do a man-in-the-middle attack instead. Either way it doesn't matter, the code being send from the gateway.octobercms.com location has been tainted and being directly injected into all the websites through downloading the malware plugins or themes etc.

The gateway.octobercms.com location is sending data out to all the cms websites and is using a cross-origin method. So it makes sense to add the new security api's to properly isolate that location to protect all the cms websites requesting data from that location.

Also it should be noted that a good hacker would not make it obvious that any code has been changed and it would benefit them that the injected code is hidden and not noticed - the longer the better. Who knows the location might already have been hacked and you don't know about it? Everyday government websites with stronger security are getting hacked, so why should the October CMS website be any different?

The first thing to do is add the crossorigin attribute to any assets such as the following:

  • images
  • audio
  • video
  • scripts
  • web workers
    etc.

That are being sent from a third-party source and coming into the cms! See pr code example: https://github.com/octobercms/october/pull/5436/files

When that is working you will see the following:

crossorigin

Notice the browser has blocked the images coming into the cms from a third-party to protect the cms backend, see dev-tools screenshots:

image

When going deeper into their asset profiles you can see the following information:

image

Notice the infomation is talking about the gateway.octobercms.com and not my cms website backend. By default the browser has blocked everything! If someone added a plugin and tried to turn off this protection, they will need to remove the crossorigin attributes! However, this bypass may not be around in the near future as browsers may decide to add crossorigin behind the scenes in the browser code to all cross origin assets coming in.

Moving along the next step is to add the security headers to the gateway.octobercms.com website to allow the browser to whitelist the cross origin assets.

The workflow is that we are whitelisting things and everything is blocked by default. So someone trying to add bad code can only whitelist things and not block them as they are blocked from default, meaning you couldn't hack anything!

Let's talk about the server code on the gateway.octobercms.com website now. There are a few options you could do to allow sending the data to the backend cms.

First is CORS, but I'm not talking about the normal Fetch CORS as you will see this error message:

image

You will need to add the extra CORS Image code to the server.

Another method is using the api's:

  • COOP: Cross Origin Opener Policy
  • CORP: Cross Origin Resource Policy
  • COEP: Cross Origin Embedder Policy

You will need to add them and set the correct options!

Again going to repeat myself here!

We are isolating the gateway.octobercms.com location!

So these api's being added to the server is setting up the security isolation there!

Once the gateway.octobercms.com has been updated to using these api's, all the backend cms will be locked into it's security headers when receiving files and assets. Again repeating myself look at the Site A and Site B example of CORS and a plugin can't change Site B's security API's setup in it's server!

Want to make a quick note about: CORB: Cross Origin Read Blocking api which deals with Spectre Attacks! This api already running in the browser to site isolation tabs! But can also be added to websites security! See here for more details: https://spectreattack.com/spectre.pdf

Next we need to config the cms websites receiving the plugins and themes from the gateway.octobercms.com location. We are whitelisting that location by adding the new api's, by default they are blocked.

We can add the code to our server or to the config files - it should make little difference as I've already pointed a couple of points above and don't want to repeat myself.

I should also mention, the config files should have read-only file permissions! e.g. 600 you shouldn't be allowing for example database.php to be running 644 and allow write etc. to your database details! Plus there are protection mechanisms already in place with many config settings!

The code in the cms websites should be isolating two things!

  • First the code coming into the cms backend e.g. gateway.octobercms.com etc.
  • The second is the code leaving the cms website. For example clickjacking, hotlinking etc.

I could go deeper into these api's and each thing and get really technical but above is a really brief overview.

Lastly, browsers are turning these api features on, adjusting them and addressing these security gaps as the days go by. All websites should start configuring their code to work in tandem with these api's. These things are not going away and are now being added to the html standard and other concert places.

@ayumi-cloud Thank you for the detailed explanation. That makes a lot more sense in what you are proposing.

I'm not sure as to the success you will have in getting changes implemented in gateway.octobercms.com, but you can certainly post them up as you need them.

Am I correct in saying that the only changes that will be getting implemented into October CMS itself would be some CORS policy headers and the crossorigin attribute and sub-integrity checks for assets retrieved from third-party sources? My point about the headers still stands - any request headers defined by the client-side (not gateway.octobercms.com) are still susceptible to manipulation, although I would imagine anyone messing around with those would affect only themselves anyway.

@bennothommo

Happy New Year! 馃帀

October Website

  1. Add security headers to all domains and subdomains e.g. gateway.octobercms.com and octobercms.com

  2. It would be nice if we could setup a test server to do these upgrades - so between the cms and gateway subdomain, so that people won't get disturbed when updating and testing.

Your comment

Am I correct in saying that the only changes that will be getting implemented into October CMS itself would be some CORS policy headers and the crossorigin attribute and sub-integrity checks for assets retrieved from third-party sources?

In my previous comment I used CORS as a single example, as it's been around the longest and I thought you would be most aware of that one. But here I'm suggesting to fully use these:

  • COEP: Cross Origin Embedder Policy
  • COOP: Cross Origin Opener Policy
  • CORP: Cross Origin Resource Policy
  • CORS: Cross Origin Resource Sharing

Above: These to be added to both October CMS and the CMS.

Extra

  • CORB: Cross Origin Read Blocking

Above: This one can be added to the October CMS (but not the CMS). If there is a potential issue with Spectre attack on the server.

Add crossorigin attribute to cross origin assets in the CMS.

Add sub-integrity (SRI) checks for assets retrieved from third-party sources - where possible (because somethings can not be done, for example an open issue I have with the Web Standards repo is with adding SRI protection to importScripts it can't be done right now, so that's an open security issue on the web).

My point about the headers still stands - any request headers defined by the client-side (not gateway.octobercms.com) are still susceptible to manipulation, although I would imagine anyone messing around with those would affect only themselves anyway.

Yah, agree. I just wanted to make the point about the CORS example on Site B and Site A having a plugin couldn't change their http headers.

Let's say the gateway subdomain has the new security api headers in place. Some http headers in the config file in the cms wouldn't matter (as you couldn't change the http headers on the gateway subdomain from the cms). But some other http headers that protect the data leaving the cms needs to be in the server.

My point is that the data coming into the cms is more important to me than the data leaving the cms - yet the reverse is that the http security headers need to be more on the server for the data leaving the cms than the data coming into it. Confusing, but true.


The way to start this proposal will be for the admins to have a private discussion about adding the new security measures to the October website and it would be great to have a test server running to test the api connections between the server (sending plugin and theme data) and the cms, without interrupting people's usage of the platform.

Hope I make sense.

@ayumi-cloud Happy new year to you too :)

My point is that the data coming into the cms is more important to me than the data leaving the cms - yet the reverse is that the http security headers need to be more on the server for the data leaving the cms than the data coming into it. Confusing, but true.

Agreed. It sounds to me that the most important part in all this is that gateway.octobercms.com has the correct headers as the single source of truth. We have to assume that, although very unlikely to be changed, any header, request or code from the client side is modifiable through direct edits or plugins and therefore potentially tainted. That, of course, doesn't stop us from setting some sensible defaults however.

The way to start this proposal will be for the admins to have a private discussion about adding the new security measures to the October website and it would be great to have a test server running to test the api connections between the server (sending plugin and theme data) and the cms, without interrupting people's usage of the platform.

This will be tricky - as I've indicated before, the maintainer team (@LukeTowers, @mjauvin and myself) do not have access to the API server. I personally have no knowledge of the scope of the API, so setting up a test API server would be entirely theoretical based on what we can see from the October CMS code side. My understanding is that the API is proprietary knowledge.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

m49n picture m49n  路  3Comments

mittultechnobrave picture mittultechnobrave  路  3Comments

SeekAndPwn picture SeekAndPwn  路  3Comments

jvanremoortere picture jvanremoortere  路  3Comments

gergo85 picture gergo85  路  3Comments