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

Securing http requests from gallium #16

Open
ernesto-jimenez opened this issue Sep 28, 2016 · 11 comments
Open

Securing http requests from gallium #16

ernesto-jimenez opened this issue Sep 28, 2016 · 11 comments

Comments

@ernesto-jimenez
Copy link
Contributor

There will be different security requirements for the HTTP connections from libchromiumcontent.

  1. Restricting what domains/URLs libchromiumcontent has access to.
  2. Starting an HTTP server embedded in the app that only libchromiumcontent has access to.
  3. Preventing sniffing of the traffic between libchromiumcontent and the embedded server.

@alexflint, I have some ideas about how to address this, I can create issues for each of these points and outline some proposals if you want.

@kirillDanshin
Copy link

I didn't get your point in 1.. Why we're required to do that?
Also, I think that 2. may be done only as an option because developers could use the server from other microservices if they want.
But I absolutely agree and support 3.. Also, it can be done, for example, with IETF RFC7539 (also known as ChaCha20 and Poly1305).

@ernesto-jimenez
Copy link
Contributor Author

hi @kirillDanshin

I didn't get your point in 1.. Why we're required to do that?

It is pretty standard to whitelist the domains your web view can access. E.g., information from the Cordova project (PhoneGap) about this: http://cordova.apache.org/docs/en/latest/guide/appdev/whitelist/index.html

If you allow your web view to access anything, there is a bunch of security and UX considerations:

  • What happens if you get redirected to some other page due to a mistake in the app? How do you get back to the app's web page without a back button or an address bar?
  • Could an attacker make the gallium app load an untrusted domain?
  • If a malicious actor can trick the user/app into loading an untrusted domain, Is there a risk for phishing? How could the user be aware without an address bar? What other risks are there?

Also, I think that 2. may be done only as an option because developers could use the server from other microservices if they want.

Developers will always be able to spin up their servers from a gallium app.

By default, however, I would have gallium start a web server using its own http.Handler that handles authentication before forwarding the request to http.DefaultServeMux. With that setup, libchromiumcontent would point by default to that server.

You would always be able to start a second server serving http.DefaultSeveMux or anything else. But then it is up to you to manage authentication and security.

But I absolutely agree and support 3.. Also, it can be done, for example, with IETF RFC7539 (also known as ChaCha20 and Poly1305).

I'm sure there must be a way. It's probably just a matter of looking into what is supported by libchromiumcontent.

@kirillDanshin
Copy link

no, please, don't use net/http, it's slowing down your performance (take a look on fasthttp).

as soon as I can run gallium on linux, I'll write some default handlers and boilerplate code so you will be able to use something like gallium.NewApp function and register some route handlers, websocket handlers etc. in it.
also it will secure traffic between the app and libchromiumcontent automatically and it will be optimized to get maximal security while saving or improving performance.

also I think that developer should be able to disable whitelisting and allow all domains, if he want.

@ernesto-jimenez
Copy link
Contributor Author

@kirillDanshin the server is only going to have one client: the gallium app. Going with fasthttp is an overkill :)

@joeblew99
Copy link

joeblew99 commented Sep 30, 2016

its too early for fasthttp. Why ?

  1. echo framework dropped support for fasthttp. See issue 665. They found that its was way too much work to support it as things go bigger.
  2. For a single user environment, the perf difference will be not worth it. I agree with @ernesto-jimenez .
  3. We have bigger fix to fry still. We can start with standard, and then later do fasthttp IF some want it.

The idea of a good base that allows websockets, route handlers is great though.
What framework were you wanting to use ?

@kirillDanshin
Copy link

I don't use echo framework because it works disgusting and can't handle even 10% of project's workload. I don't use net/http because it terribly ineffective. I want to give developers a simple API while using lowest as possible resources and give the best performance so they can give end users the best user experience ever. I can do it that way and keep API as simple and stable as possible. if you really want, we can support both fasthttp and net/http.

@iMaxopoly
Copy link

@kirillDanshin I'm a newbie developer and just dropping in to say that I basically agree with @kirillDanshin . I have used iris in 3~4 of my older projects at the company where I work and we basically decided to replace it with Iris which uses fasthttp.

It's truewhat @ernesto-jimenez says regarding fasthttp being an "overkill", however, if there is something better that we can do, why not do it?

It's your project so I am certain you will choose to do what suits you the best, but my recommendation and request is to use fasthttp until net/http gains the performance optimizations that we see in fasthttp package.

Kind regards, thank you for the wonderful project "Gallium". I cannot wait for it to be ported to Ubuntu and Windows.

@renannprado
Copy link

renannprado commented Oct 2, 2016

I am with @ernesto-jimenez and also I believe that HTTP routers should not be in the scope of this issue.

@alexflint
Copy link
Owner

@ernesto-jimenez thanks for starting this conversation! Sorry for coming so late, I've been knee deep in the chromium codebase :)

Restricting what domains/URLs libchromiumcontent has access to.

I agree this is important. One option would be to investigate what chromium itself can do for us here. I believe there is a way to intercept and override page loads using one of the WebContents callbacks. I would be interested in your suggestions on this

Starting an HTTP server embedded in the app that only libchromiumcontent has access to.

Agreed, although for starters I think we should just focus on setting up a reliable communication channel between go and js (e.g. how does js find out what endpoint to contact the go server on? What if there are multiple instances of the same gallium app, how do they avoid trying to bind to the same port?)

Preventing sniffing of the traffic between libchromiumcontent and the embedded server.

I actually wonder if we should leave this for later on. Whenever you ship code to run on a user's computer I think you should assume that a motivated adversary will eventually disassemble all your client-side code and discover all its secrets, so projects that use gallium should never rely on it keeping adversaries out on the client side. I do think it's worth having some countermeasures to make this as difficult as possible, but I suspect we can leave this until later.

ernesto-jimenez added a commit to ernesto-jimenez/gallium that referenced this issue Oct 5, 2016
With these changes:

- gallium.App will have a local HTTP server running on a free port.
- the server is protected with a random token generated on startup.
- it exposes http.DefaultServerMux

Re: alexflint#16
@ernesto-jimenez
Copy link
Contributor Author

Restricting what domains/URLs libchromiumcontent has access to.

I agree this is important. One option would be to investigate what chromium itself can do for us here. I believe there is a way to intercept and override page loads using one of the WebContents callbacks. I would be interested in your suggestions on this

I have never worked with chromium, so I can only speculate. If libchromiumcontent allows filtering requests, that would be an option. Another option could be to configure a proxy for libchromiumcontent and have it setup to be one started within the Go app.

Starting an HTTP server embedded in the app that only libchromiumcontent has access to.

Agreed, although for starters I think we should just focus on setting up a reliable communication channel between go and js (e.g. how does js find out what endpoint to contact the go server on? What if there are multiple instances of the same gallium app, how do they avoid trying to bind to the same port?)

See #20 for a proposal on how to implement it. It addresses all your concerns except for communication from Go to JS, which is straightforward and I can tackle next.

Preventing sniffing of the traffic between libchromiumcontent and the embedded server.

I actually wonder if we should leave this for later on. Whenever you ship code to run on a user's computer I think you should assume that a motivated adversary will eventually disassemble all your client-side code and discover all its secrets, so projects that use gallium should never rely on it keeping adversaries out on the client side. I do think it's worth having some countermeasures to make this as difficult as possible, but I suspect we can leave this until later.

It would be worthwhile to check what are the configuration options for libchromiumcontent regarding TLS. If it allows adding a Root CA certificate, securing the traffic with the embedded server would be trivial since we would be able to use a generated self-signed cert.

ernesto-jimenez added a commit to ernesto-jimenez/gallium that referenced this issue Oct 5, 2016
With these changes:

- gallium.App will have a local HTTP server running on a free port.
- the server is protected with a random token generated on startup.
- it exposes http.DefaultServerMux

Re: alexflint#16
@ghost
Copy link

ghost commented Oct 17, 2016

I agree this subject area is very important.

The idea of doing the security at the libchromium level is nice, because it 100℅ avoids the golang router so people can use whatever they like.

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

No branches or pull requests

6 participants