Search code examples
javascriptcontent-security-policysandbox

How to prevent external script from top level navigation


On our site, external scripts from ad provider (all Javascript) occasionally navigate the user to some malware site.

Any JS-code can be loaded from the ad provider (e.g. sometimes it creates an iframe to display the ad, sometime the ad is displayed directly in the main page).

I wonder how to safely prevent any external script from triggering top level navigation, whether the script is executed from within an iframe or not.

Current solution is to add CSP sandbox header in every response:

header( 'Content-Security-Policy: sandbox allow-downloads allow-forms allow-modals allow-pointer-lock allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-scripts allow-storage-access-by-user-activation allow-top-navigation-by-user-activation allow-top-navigation-to-custom-protocols;' );

The strategy is to prevent top level navigation by omitting the sandbox allow-top-navigation header.

Is this a sufficient solution in order to prevent top level navigation? Is there a better way to achieve this?


Solution

  • It is not sufficient because in your case you also need third party scripts running at the top level. Omitting allow-top-navigation only prevents iframes from changing the URL of your page (the top). i.e. links such as:

    <a target="_top" href="https://example.com">example.com</a>
    
    open('https://example.com', '_top')
    

    Here’s a demo of the above anchor on an iframe and on the top level context: https://www.youtube.com/shorts/1_Qo74q8SxQ

    How to protect against it?

    You’ll need a known-good version of the 3rd party assets, and load them with a nonce. That will ensure that other versions won’t run in your page.