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

Browser API: expose SSL info (securitychange event) #8544

Closed
paulrouget opened this issue Nov 16, 2015 · 10 comments
Closed

Browser API: expose SSL info (securitychange event) #8544

paulrouget opened this issue Nov 16, 2015 · 10 comments
Labels
A-content/dom Interacting with the DOM from web content A-network A-security

Comments

@paulrouget
Copy link
Contributor

mozbrowsersecuritychange properties: https://github.com/paulrouget/mozBrowserAPI/blob/master/BrowserAPI.md#the-mozbrowsersecuritychange-event

Could someone describe what needs to be done to expose SSL information (no ssl, non valid cert, valid cert, mixed content, …)? At least, we'd like to start with basic info: ssl or no ssl.

@jdm
Copy link
Member

jdm commented Nov 16, 2015

I would add an enum to the Metadata struct, and store this as a field in Document. This would allow it to be updated for mixed content that is added subsequently, and trigger these events. The field of the enum would be set around http://mxr.mozilla.org/servo/source/components/net/http_loader.rs#711 .

@jdm jdm added A-content/dom Interacting with the DOM from web content A-network labels Nov 16, 2015
@paulrouget
Copy link
Contributor Author

Understood.

I'd like to start by implementing event.details.state, with these 2 possible values:

  • "insecure" indicates that the data corresponding to the request was received over an insecure channel.
  • "secure" indicates that the data corresponding to the request was received over a secure channel.

Is it enough to just use: hsts_list.read().unwrap().is_host_secure(domain) ?

@jdm
Copy link
Member

jdm commented Nov 17, 2015

No, since that only corresponds to domains included in the HSTS preload list and any domains that have included the Strict-Transport-Settings header in a previous response. It should be enough to check that the scheme of the final request URL is https if there's a successful response received, I believe, since we deal with certificate errors before that.

@paulrouget
Copy link
Contributor Author

ok. I think the event should be dispatched once the document and its resources are all loaded, not once the document page request has loaded, since we will eventually add mixed content information to the event.

So probably along the mozbrowserloadend event.

@jdm
Copy link
Member

jdm commented Nov 17, 2015

What about if mixed content is added after the document's load event occurs? Does a new event get dispatched in that case?

@paulrouget
Copy link
Contributor Author

With gecko, securitychange is dispatched right after load starts, and is dispatched again as mixed content gets added to the document. Which I guess makes sense.

@paulrouget
Copy link
Contributor Author

I'm trying to bring the load status to document.rs.

it looks like that: https://gist.github.com/paulrouget/852cd69e2830d381f3d3

Does that look right? I could use the metadata field instead, it holds a status value as well (RawStatus though), but I had trouble with moved values issues (but I believe I can work around that, I haven't try hard).

The patch above doesn't work though.
status is a Result<(),String>, and I believe it needs to be a Result<StatusCode,String> to then check if it's a 200 status.

Using Result<StatusCode,String> instead of Result<(),String> throws this error:

   Compiling net_traits v0.0.1 (file:///Users/paul/git/servo/components/servo)
/Users/paul/git/servo/components/net_traits/lib.rs:177:23: 177:32 error: the trait `serde::ser::Serialize` is not implemented for the type `hyper::status::StatusCode` [E0277]
/Users/paul/git/servo/components/net_traits/lib.rs:177 #[derive(Deserialize, Serialize)]
                                                                             ^~~~~~~~~
/Users/paul/git/servo/components/net_traits/lib.rs:177:23: 177:32 note: in this expansion of #[derive_Serialize] (defined in /Users/paul/git/servo/components/net_traits/lib.rs)
/Users/paul/git/servo/components/net_traits/lib.rs:177:23: 177:32 help: run `rustc --explain E0277` to see a detailed explanation
/Users/paul/git/servo/components/net_traits/lib.rs:177:23: 177:32 note: required by `serde::ser::Serializer::visit_newtype_variant`
/Users/paul/git/servo/components/net_traits/lib.rs:177:21: 177:21 error: the trait `serde::de::Deserialize` is not implemented for the type `hyper::status::StatusCode` [E0277]
/Users/paul/git/servo/components/net_traits/lib.rs:177 #[derive(Deserialize, Serialize)]
                                                                           ^
/Users/paul/git/servo/components/net_traits/lib.rs:177:10: 177:21 note: in this expansion of try! (defined in <std macros>)
/Users/paul/git/servo/components/net_traits/lib.rs:177:21: 177:21 help: run `rustc --explain E0277` to see a detailed explanation
error: aborting due to 2 previous errors
Could not compile `net_traits`.

If this approach makes sense, what would be the right way to solve the above issue?
Or maybe I should not switch to Result<StatusCode,String>, and somehow cast the () value to StatusCode (is that even possible)?

@jdm
Copy link
Member

jdm commented Nov 20, 2015

I'm not convinced that Result<StatusCode/RawStatus, String> is really the right thing to do here, since we're duplicating information between the Metadata structure that's received in headers_available, and the final result is an indication that the response was received in its entirety. I think storing the status code separately in consumers that require it makes the most sense to me.

@paulrouget
Copy link
Contributor Author

Previous approach was wrong. I was trying to rely on the HTTP status code, which makes no sense.

Here is a simpler approach: master...paulrouget:securitychange

This is basic, but it covers enough for what we need for browser.html.

@jdm, can you take a quick look and tell me if this is what you had in mind?

You mentioned adding an enum to the Metadata struct. Afaict, metadata are not stored anywhere. I added a simple field to the document. Maybe that's enough.

@jdm
Copy link
Member

jdm commented Jan 8, 2016

Yep, that's more like what I was expecting. I think we should store a value in Document that reflects https://html.spec.whatwg.org/multipage/dom.html#concept-document-https-state instead of secure/broken/insecure and store the brokenness via a separate boolean field. Additionally, instead of inspecting the scheme of the final URL, we should add a field to Metadata and rely on that value.

bors-servo pushed a commit that referenced this issue Feb 9, 2016
mozbrowsersecuritychange event

Fixes #8544

No test yet. Is there a way to mock a https connection?

Also, I wish I could use the `HTTPSState` enum instead of a `String` when calling `trigger_mozbrowser_event` (https://github.com/servo/servo/compare/master...paulrouget:securitychange?expand=1#diff-30a18e04d7e0b66aafdf192e416cad44R306) but that would require `constellation_msg.rs` to know about `HTTPSState`, which is defined in `document.rs`, which would add a dependency to `components/msg`. I could define `HTTPSState` somewhere else maybe? Or maybe it's fine to use a `String`. But then, should I use the HTTPSState strings (`"modern/deprecated/none"`) or the mozbrowser strings (`"secure/insecure/broken"`) (as it is now)

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/9244)
<!-- Reviewable:end -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-content/dom Interacting with the DOM from web content A-network A-security
Projects
None yet
Development

No branches or pull requests

3 participants