-
Notifications
You must be signed in to change notification settings - Fork 0
Security: sandbox Web Page iframe and enforce http(s) URL allowlist (CWE-1021/CWE-829) #11
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,13 +21,15 @@ | |
| --> | ||
| <template> | ||
| <div class="l-iframe abs"> | ||
| <iframe :src="url"></iframe> | ||
| <iframe :src="url" sandbox="allow-scripts allow-forms" referrerpolicy="no-referrer"></iframe> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script> | ||
| import { sanitizeUrl } from '@braintree/sanitize-url'; | ||
|
|
||
| const BLOCKED_URL = 'about:blank'; | ||
|
|
||
| export default { | ||
| inject: ['openmct', 'domainObject'], | ||
| data: function () { | ||
|
|
@@ -37,7 +39,18 @@ export default { | |
| }, | ||
| computed: { | ||
| url() { | ||
| return sanitizeUrl(this.currentDomainObject.url); | ||
| const url = sanitizeUrl(this.currentDomainObject.url); | ||
|
|
||
| // Only allow http/https absolute urls and same-origin relative urls | ||
| const isSafeAbsoluteUrl = /^https?:\/\//i.test(url); | ||
| const isSafeRelativeUrl = /^\/(?!\/)/.test(url); | ||
| if (!isSafeAbsoluteUrl && !isSafeRelativeUrl) { | ||
| console.warn('Blocked unsafe URL:', url); | ||
|
|
||
| return BLOCKED_URL; | ||
| } | ||
|
|
||
| return url; | ||
|
Comment on lines
+45
to
+53
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📝 Info: Behavior change: previously-rendered scheme-less and relative URLs now blocked Previously the iframe bound whatever Was this helpful? React with 👍 or 👎 to provide feedback. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct and intended. Scheme-less values like |
||
| } | ||
| } | ||
| }; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔍 Sandbox omits allow-same-origin, disabling storage/DOM for same-origin relative URLs
The
sandbox="allow-scripts allow-forms"attribute deliberately omitsallow-same-origin. This means even the allowed same-origin root-relative URLs (/...) matched byisSafeRelativeUrlatsrc/plugins/webPage/components/WebPage.vue:46will be loaded into a unique opaque origin, so framed same-origin pages will lose access to cookies, localStorage, and same-origin DOM/XHR. This is the intended security tradeoff per the PR, but reviewers should confirm no existing deployment relies on embedding a same-origin page that needs storage/session access, since such pages may now silently break.Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intended. Omitting
allow-same-originis deliberate: with it, an attacker-supplied same-origin (orallow-scripts+allow-same-origin) frame could script its way out of the sandbox, defeating the fix. The Web Page object is designed to embed external content (itsurlis free-text and, per the finding, attacker-influenceable via Import-from-JSON/shared persistence), so treating the frame as an untrusted opaque origin is correct. There is no known Open MCT feature that relies on embedding a same-origin page needing cookie/localStorage access through this object. Flagging the tradeoff for reviewers, but not changing it.