# Iframes in XSS and CSP ## Iframes in XSS There are 3 ways to indicate the content of an iframed page: * Via `src` indicating an URL (the URL may be cross origin or same origin) * Via `src` indicating the content using the `data:` protocol * Via `srcdoc` indicating the content #### Accesing Parent & Child vars ```html ``` ```html ``` If you access the previous html via a http server (like `python3 -m http.server`) you will notice that all the scripts will be executed (as there is no CSP preventing it)., **the parent won’t be able to access the `secret` var inside any iframe** and **only the iframes if2 & if3 (which are considered to be same-site) can access the secret** in the original window.\ Note how if4 is considered to have `null` origin. ### Iframes with CSP {% hint style="info" %} Please, note how in the following bypasses the response to the iframed page doesn't contain any CSP header that prevents JS execution. {% endhint %} The `self` value of `script-src` won’t allow the execution of the JS code using the `data:` protocol or the `srcdoc` attribute.\ However, even the `none` value of the CSP will allow the execution of the iframes that put a URL (complete or just the path) in the `src` attribute.\ Therefore it’s possible to bypass the CSP of a page with: ```html ``` Note how the **previous CSP only permits the execution of the inline script**.\ However, **only `if1` and `if2` scripts are going to be executed but only `if1` will be able to access the parent secret**. ![](<../../.gitbook/assets/image (627) (1) (1).png>) Therefore, it’s possible to **bypass a CSP if you can upload a JS file to the server and load it via iframe even with `script-src 'none'`**. This can **potentially be also done abusing a same-site JSONP endpoint**. You can test this with the following scenario were a cookie is stolen even with `script-src 'none'`. Just run the application and access it with your browser: ```python import flask from flask import Flask app = Flask(__name__) @app.route("/") def index(): resp = flask.Response('') resp.headers['Content-Security-Policy'] = "script-src 'self'" resp.headers['Set-Cookie'] = 'secret=THISISMYSECRET' return resp @app.route("/cookie_s.html") def cookie_s(): return "" if __name__ == "__main__": app.run() ``` ### Other Payloads found on the wild ```html ``` ### Iframe sandbox The `sandbox` attribute enables an extra set of restrictions for the content in the iframe. **By default, no restriction is applied.** When the `sandbox` attribute is present, and it will: * treat the content as being from a unique origin * block form submission * block script execution * disable APIs * prevent links from targeting other browsing contexts * prevent content from using plugins (through ``, ``, ``, or other) * prevent the content to navigate its top-level browsing context * block automatically triggered features (such as automatically playing a video or automatically focusing a form control) The value of the `sandbox` attribute can either be empty (then all restrictions are applied), or a space-separated list of pre-defined values that will REMOVE the particular restrictions. ```html ```