FAQ

[play-framework] [2.1] HTTPS and WSS (secure websocket) clarifications and documentation

Alex Jarvis
Dec 13, 2012 at 11:31 am
Hi,

I've just been looking at the various, albeit confusing pull-requests &
tickets for the inclusion of SSL/TLS in Play 2.0 and have managed to get
the following understanding from it all, but would appreciate clarification
of my summary:

Firstly thanks for Henry Story for getting the ball-rolling:
https://play.lighthouseapp.com/projects/82401/tickets/215
https://play.lighthouseapp.com/projects/82401-play-20/tickets/215-tls-https-support-in-play-20

The pull-requests I found that are associated:
https://github.com/playframework/Play20/pull/339
https://github.com/playframework/Play20/pull/340
https://github.com/playframework/Play20/pull/475

What works:
- You can specify https.port in application.conf or as a environment
variable for dev mode e.g. run -Dhttps.port=8443

What is missing:
- Client certificate support (moved to 2.2 release, see pull request 475)
- Documentation (aside from that attached to the issues/pull-requests) for
getting SSL to work in 2.1.
- SSL support for Websockets (wss://)

I know that most people will setup lighttpd or nginx for their production
environments (or have to, seeing as this is only for dev mode), terminating
the SSL at that point.

A couple of questions then:
- What were the reasons to only allow TLS connections in dev mode?
- How can you verify that a request is secure? i.e. make a filter that
redirects certain requests to the https scheme and port - should this be
done at the reverse proxy with redirect rules? I think there used to be a
secure attribute on the Request object in Play 1, allowing you to do this.
- Has anyone planned to enable SSL support for Websockets during dev mode,
or has it been left by the wayside?
- Has anyone setup a reverse proxy (nginx maybe) that supports secure
Websockets? I would appreciate any information here before I go and do some
research :)

Thanks for your comments!

--
reply

Search Discussions

5 responses

  • James Roper at Dec 14, 2012 at 2:23 am
    Firstly, you're missing this one, which finished off the SSL support that
    2.1 currently supports:

    https://github.com/playframework/Play20/pull/473

    - You can specify https.port in application.conf or as a environment
    variable for dev mode e.g. run -Dhttps.port=8443

    No, https.port must always be specified on the command line as a system
    property, as with http.port. An older version of the pull request changed
    this, but this was never accepted. It's not read from application.conf.

    - What were the reasons to only allow TLS connections in dev mode?
    What do you mean? TLS works both in prod and in dev.

    - How can you verify that a request is secure? i.e. make a filter that
    redirects certain requests to the https scheme and port - should this be
    done at the reverse proxy with redirect rules? I think there used to be a
    secure attribute on the Request object in Play 1, allowing you to do this.
    Unfortunately, currently that's not possible. Though, these days it's also
    rarely useful, securing only part of an application via HTTPS (eg just the
    login form) is almost always a bad idea, as the firefox plugin that was
    released a few years ago that basically let you hack into anyones facebook,
    google, twitter etc accounts that were using the same wifi hotspot as you
    showed. If you really wanted to you could set a secure cookie, and if the
    next request comes back with that cookie, then the user is using https.

    --
  • Niklas Nylund at Dec 14, 2012 at 5:27 am
    How do you configure your certificate? i.e. something similar to
    Apache's SSLCertificateFile, SSLCertificateKeyFile and SSLCACertificateFile.

    - How can you verify that a request is secure? i.e. make a filter that
    redirects certain requests to the https scheme and port - should this be
    done at the reverse proxy with redirect rules? I think there used to be a
    secure attribute on the Request object in Play 1, allowing you to do this.
    Unfortunately, currently that's not possible. Though, these days it's
    also rarely useful, securing only part of an application via HTTPS (eg just
    the login form) is almost always a bad idea, as the firefox plugin that was
    released a few years ago that basically let you hack into anyones facebook,
    google, twitter etc accounts that were using the same wifi hotspot as you
    showed. If you really wanted to you could set a secure cookie, and if the
    next request comes back with that cookie, then the user is using https.
    Having the secure flag accessible directly in a controller is very handy.
    We have a REST API built on play 1.2 where we for a couple of reasons needs
    both HTTPS and HTTP. For example all of the operations that change any
    state is done over HTTPS and with custom headers for authentication but
    some read-only parts of the API is publicly accessible over both HTTP and
    HTTPS.


    --
  • James Roper at Dec 14, 2012 at 6:30 am

    On Friday, 14 December 2012 16:27:19 UTC+11, Niklas Nylund wrote:

    How do you configure your certificate? i.e. something similar to
    Apache's SSLCertificateFile, SSLCertificateKeyFile and SSLCACertificateFile.

    Using https.* system properties, where * is keyStore, keyStoreType,
    keyStorePassword, keyStoreAlgorithm and trustStore. These system
    properties are pretty self explanatory if you're familiar with JSSE, if
    not, these docs are your friend (whenever I've done any Java keystore work,
    I sleep with this documentation under my pillow):

    http://docs.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html

    In addition, if you don't supply an https.keyStore property, Play generates
    a key and self signed certificate for you (and caches it for all subsequent
    invocations). This is intended for ease of use in development, and
    shouldn't be used in production for obvious reasons. The key/self signed
    certificate generation currently will only work on JVMs that have a Sun
    JSSE provider available.

    --
  • Alex Jarvis at Dec 14, 2012 at 11:54 am
    Thanks for your response James! See my answers below:

    Firstly, you're missing this one, which finished off the SSL support that
    Right you are!

    No, https.port must always be specified on the command line as a system
    property, as with http.port. An older version of the pull request changed
    this, but this was never accepted. It's not read from application.conf.
    This is an interesting development, could you please summarise why this was
    decided?

    What do you mean? TLS works both in prod and in dev.
    So I just realised that the command line system properties are only passed
    when you run 'start..' from INSIDE the sbt/play console. Sorry for the
    confusion, but this was why I thought there was a difference. Any reason
    why the properties cannot be passed into the sbt process from the shell?
    I'm guessing that the target/start script after running the stage task is
    different?

    Unfortunately, currently that's not possible. Though, these days it's
    also rarely useful, securing only part of an application via HTTPS (eg just
    the login form) is almost always a bad idea, as the firefox plugin that was
    released a few years ago that basically let you hack into anyones facebook,
    google, twitter etc accounts that were using the same wifi hotspot as you
    showed. If you really wanted to you could set a secure cookie, and if the
    next request comes back with that cookie, then the user is using https.
    Firesheep? Yeah, well facebook were setting insecure cookies, so if they'd
    used secure cookies like you said then it would have been alright.. Let's
    not let their mistakes detract from our goal here... I think that it would
    be great to have a 'secure' flag in the request object, when the app server
    knows the request is secure (not saying that I personally need this
    anymore, but if especially if the app server is doing the SSL, then why
    not). There must have some forethought before adding it to Play 1.

    I just thought about how Play could identify the https requests from a
    reverse proxy by adding a header to identify them e.g. X-Forwarded-Proto -
    but surely the client could then set this too.. I guess you'd have to make
    sure that this header was stripped/overridden at the reverse proxy/load
    balancer.

    --
  • James Roper at Dec 14, 2012 at 12:59 pm

    No, https.port must always be specified on the command line as a system
    property, as with http.port. An older version of the pull request changed
    this, but this was never accepted. It's not read from application.conf.
    This is an interesting development, could you please summarise why this
    was decided?
    See this
    comment: https://github.com/playframework/Play20/pull/339#issuecomment-9101647

    What do you mean? TLS works both in prod and in dev.
    So I just realised that the command line system properties are only passed
    when you run 'start..' from INSIDE the sbt/play console. Sorry for the
    confusion, but this was why I thought there was a difference. Any reason
    why the properties cannot be passed into the sbt process from the shell?
    I'm guessing that the target/start script after running the stage task is
    different?
    I think they can, start -Dhttps.port=443 should work.

    Unfortunately, currently that's not possible. Though, these days it's also
    rarely useful, securing only part of an application via HTTPS (eg just the
    login form) is almost always a bad idea, as the firefox plugin that was
    released a few years ago that basically let you hack into anyones facebook,
    google, twitter etc accounts that were using the same wifi hotspot as you
    showed. If you really wanted to you could set a secure cookie, and if the
    next request comes back with that cookie, then the user is using https.
    Firesheep? Yeah, well facebook were setting insecure cookies, so if they'd
    used secure cookies like you said then it would have been alright.. Let's
    not let their mistakes detract from our goal here... I think that it would
    be great to have a 'secure' flag in the request object, when the app server
    knows the request is secure (not saying that I personally need this
    anymore, but if especially if the app server is doing the SSL, then why
    not). There must have some forethought before adding it to Play 1.
    We could add it, it's probably a bit late in 2.1 though to do it.

    I just thought about how Play could identify the https requests from a
    reverse proxy by adding a header to identify them e.g. X-Forwarded-Proto -
    but surely the client could then set this too.. I guess you'd have to make
    sure that this header was stripped/overridden at the reverse proxy/load
    balancer.
    Yes. We already honour X-Forwarded-For, if configured to do so.

    --

Related Discussions

Discussion Navigation
viewthread | post