Skip to content
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

security: post OAuth token to client webapps if any #1149

Merged
merged 1 commit into from
Apr 11, 2019

Conversation

rzr
Copy link
Contributor

@rzr rzr commented Jun 29, 2018

When loaded from window.opener CORS is blocked by default,
so this is workaraounding security issues like:

Uncaught DOMException: Blocked a frame with origin (...)
from accessing a cross-origin frame. at (...)

For any security concern this change can be reverted anytime.

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Signed-off-by: Philippe Coval p.coval@samsung.com

@mrstegeman mrstegeman requested a review from hobinjk June 29, 2018 11:39
@hobinjk
Copy link
Contributor

hobinjk commented Jun 29, 2018

At this level of integration you would be better of setting up a proper OAuth service by editing src/models/oauthclients.ts as described in this setup document.

@rzr
Copy link
Contributor Author

rzr commented Jun 29, 2018

Yea I tried this once, but on some browsers was not possible from file://... origin (tizen local webapp) so I hacked around to make it work somehow, until a better solution is found.

FYI, I used this bit for PWA app:
https://vimeo.com/277663462#webthing-webapp-pwa-20180629rzr

Maybe I will refactor this proof of concept later, but I wished the code could support several platforms.

@hobinjk
Copy link
Contributor

hobinjk commented Jul 9, 2018

Yeah, unfortunately this would make it really easy for an attacker to embed a frame of the local token service in their page and trick the user into giving them complete access to their gateway.

I think it's possible to limit the message listener to only respond if the message originates from a file:// URL through ev.origin or something. That would make this PR much more secure.

@rzr
Copy link
Contributor Author

rzr commented Jul 9, 2018

Yes I was about to suggest this, meanwhile I got proper OAuth on http.
but Instead of testing file:// protocol I prefer to test location.hostname != null, in case other protocol to be used, would that be fine ?

@hobinjk
Copy link
Contributor

hobinjk commented Jul 9, 2018

I would prefer a whitelist of specific protocols so that the exact behavior is completely specified.

@rzr rzr force-pushed the sandbox/rzr/review/master branch from 6965369 to c7d0f4f Compare July 9, 2018 18:51
rzr added a commit to TizenTeam/gateway that referenced this pull request Jul 9, 2018
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Signed-off-by: Philippe Coval <p.coval@samsung.com>
@rzr rzr force-pushed the sandbox/rzr/review/master branch from c7d0f4f to 99336c0 Compare July 23, 2018 10:42
rzr added a commit to TizenTeam/gateway that referenced this pull request Jul 23, 2018
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Signed-off-by: Philippe Coval <p.coval@samsung.com>
@rzr rzr changed the title WIP: security: post OAuth token to client webapps if any security: post OAuth token to client webapps if any Jul 23, 2018
rzr added a commit to TizenTeam/gateway that referenced this pull request Jul 25, 2018
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Signed-off-by: Philippe Coval <p.coval@samsung.com>
@rzr rzr force-pushed the sandbox/rzr/review/master branch from 99336c0 to 3689ead Compare August 3, 2018 09:05
rzr added a commit to TizenTeam/gateway that referenced this pull request Aug 3, 2018
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

It was tested on Tizen5 on TM1.

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Origin: https://github.com/tizenteam/gateway
Signed-off-by: Philippe Coval <p.coval@samsung.com>
rzr added a commit to TizenTeam/gateway that referenced this pull request Aug 4, 2018
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Signed-off-by: Philippe Coval <p.coval@samsung.com>
rzr added a commit to TizenTeam/gateway that referenced this pull request Aug 21, 2018
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

It was tested on Tizen5 on TM1.

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Origin: https://github.com/tizenteam/gateway
Signed-off-by: Philippe Coval <p.coval@samsung.com>
rzr added a commit to TizenTeam/gateway that referenced this pull request Aug 21, 2018
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

It was tested on Tizen5 on TM1.

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Origin: https://github.com/tizenteam/gateway
Signed-off-by: Philippe Coval <p.coval@samsung.com>
rzr added a commit to TizenTeam/gateway that referenced this pull request Oct 23, 2018
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

It was tested on Tizen5 on TM1.

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Origin: https://github.com/tizenteam/gateway
Signed-off-by: Philippe Coval <p.coval@samsung.com>
@rzr rzr force-pushed the sandbox/rzr/review/master branch from 3689ead to ab96de7 Compare October 24, 2018 09:42
rzr added a commit to TizenTeam/gateway that referenced this pull request Oct 24, 2018
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

It was tested on Tizen5 on TM1.

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Origin: https://github.com/tizenteam/gateway
Signed-off-by: Philippe Coval <p.coval@samsung.com>
@mrstegeman mrstegeman force-pushed the sandbox/rzr/review/master branch from ab96de7 to a0fbcdc Compare January 29, 2019 20:00
mrstegeman pushed a commit to TizenTeam/gateway that referenced this pull request Jan 29, 2019
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

It was tested on Tizen5 on TM1.

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Origin: https://github.com/tizenteam/gateway
Signed-off-by: Philippe Coval <p.coval@samsung.com>
@ghost ghost assigned mrstegeman Jan 29, 2019
@WebThingsIO WebThingsIO deleted a comment from codecov-io Jan 29, 2019
@mrstegeman mrstegeman removed their assignment Jan 29, 2019
@codecov-io
Copy link

codecov-io commented Jan 29, 2019

Codecov Report

Merging #1149 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1149      +/-   ##
==========================================
+ Coverage   72.32%   72.32%   +<.01%     
==========================================
  Files         126      126              
  Lines        6898     6899       +1     
  Branches     1031     1031              
==========================================
+ Hits         4989     4990       +1     
  Misses       1664     1664              
  Partials      245      245
Impacted Files Coverage Δ
config/default.js 100% <ø> (ø) ⬆️
src/router.js 98.52% <100%> (+0.02%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3198c40...14d3bd2. Read the comment docs.

@rzr rzr force-pushed the sandbox/rzr/review/master branch from a0fbcdc to 0f70e4e Compare February 14, 2019 09:43
rzr added a commit to TizenTeam/gateway that referenced this pull request Feb 14, 2019
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

It was tested on Tizen5 on TM1.

Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Origin: https://github.com/tizenteam/gateway
Signed-off-by: Philippe Coval <p.coval@samsung.com>
@mrstegeman mrstegeman removed the review label Apr 3, 2019
@mrstegeman
Copy link
Contributor

@rzr @hobinjk Is this still needed for anything?

@rzr
Copy link
Contributor Author

rzr commented Apr 5, 2019

I think so it was needed for an "offline" webapp PoC... (loaded from file:// protocol), I made it evolve to support various frameworks (eg: aframe) , so it would be nice to have it in.

@hobinjk
Copy link
Contributor

hobinjk commented Apr 5, 2019

👍, after #1712 this just needs an additional modification to https://github.com/mozilla-iot/gateway/blob/master/src/router.js#L46 to have 'filesystem:' instead of 'none'

@hobinjk
Copy link
Contributor

hobinjk commented Apr 5, 2019

Additionally, since this adds the ability for any random file:// page to clickjack the gateway, the modification to the content-security policy should be guarded by a config option (like 7fbaf56)

@rzr rzr force-pushed the sandbox/rzr/review/master branch from 0f70e4e to 23a1ab2 Compare April 10, 2019 13:35
rzr added a commit to TizenTeam/gateway that referenced this pull request Apr 10, 2019
When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

It was tested on Tizen5 on TM1:
BUILD_ID=tizen-unified_20180528.1_mobile-wayland-armv7l-tm1

Relate-to: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#
Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Origin: https://github.com/tizenteam/gateway
Signed-off-by: Philippe Coval <p.coval@samsung.com>
@@ -74,5 +74,6 @@ module.exports = {
ssid_base: 'WebThings Gateway',
},
},
oauthPostToken: !false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should default to false.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I used !false as reminder

@@ -123,6 +123,15 @@ let text = client.get("<span class="origin">https://gateway.local</span>/things"
</div>
</div>
</section>
<script>
/* postToken to client apps if any */
if (config.get('oauthPostToken') && (window.location.protocol === "file:") {
Copy link
Contributor

@mrstegeman mrstegeman Apr 10, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a handlebars template that gets used in the UI. Instead of using config, you'll need to pass a value into the template.

You're also missing a paren at the end of this line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes that code didnt work actually I figured out I used other hack to get token, next version works anyway

Copy link
Contributor

@hobinjk hobinjk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update! There are just a few minor changes then this LGTM

@@ -123,6 +123,15 @@ let text = client.get("<span class="origin">https://gateway.local</span>/things"
</div>
</div>
</section>
<script>
/* postToken to client apps if any */
if (config.get('oauthPostToken') && (window.location.protocol === "file:") {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Content-Security-Policy setting means we'll only be embedded in trusted situations so this doesn't need the config.get here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still use oauthPostToken to prevent a not wanted post action
see next revison

@@ -74,5 +74,6 @@ module.exports = {
ssid_base: 'WebThings Gateway',
},
},
oauthPostToken: !false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be false

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

if (ev.data.message === "token") {
ev.source.postMessage({ message: { token: "{{token}}" }}, "*");
}
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indentation of this is a bit off and the close brace from the initial if statement is missing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

When client is loaded from file oauth can't be used
because location.hostname is null.

So we fallback by using postMessage API,
instead of parsing the token page.

Test could have been done on location.hostname,
but for security concerns only file:// protocol is whitelisted

It was tested on Tizen5 on TM1:
BUILD_ID=tizen-unified_20180528.1_mobile-wayland-armv7l-tm1

Relate-to: https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage#
Change-Id: I42af71ae822491150c019cff9688356b1a0e2532
Bug: WebThingsIO#1149
Origin: https://github.com/tizenteam/gateway
Signed-off-by: Philippe Coval <p.coval@samsung.com>
@rzr rzr force-pushed the sandbox/rzr/review/master branch from 23a1ab2 to 14d3bd2 Compare April 11, 2019 11:06
Copy link
Contributor

@mrstegeman mrstegeman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, other than the one comment.

response.set('Content-Security-Policy', 'frame-ancestors \'none\'');
response.set('Content-Security-Policy',
config.get('oauthPostToken') ?
'frame-ancestors filesystem:' :
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@rzr rzr Apr 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems not , well with quotes I got an alert that they were ignored:

Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:66.0) Gecko/20100101 Firefox/66.0
Content Security Policy: Couldn’t parse invalid host 'filesystem:'

On Tizen:

D/ConsoleMessage( 1681): [WebThings0] file:///js/index.js:438: Mozilla/5.0 (Linux; Tizen 5.0; SAMSUNG TM1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/ Mobile Safari/537.36

The source list for Content Security Policy directive 'frame-ancestors' contains an invalid source: ''filesystem:''. It will be ignored.

... now i am unsure if scheme should be quoted or not, see:

edit: I will file a bug on MDN

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right. Confusing docs on MDN.

Copy link
Contributor Author

@rzr rzr Apr 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrstegeman
Copy link
Contributor

@hobinjk Any other objections?

@mrstegeman mrstegeman merged commit 151f7d3 into WebThingsIO:master Apr 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants