[Ur] Securing sessions in Ur/Web

Simon Van Casteren simon.van.casteren at gmail.com
Mon Jan 21 02:22:59 EST 2019


Hey Adam,

As always, thanks a lot for your insights.

1. Yeah after some experimentation I understood the builtin cookie security
mechanism is there for XSRF attacks only. That's why I made my own cookie
forgery protection by hashing the contents of the cookie and always
checking that digest when reading the cookie. I feel that that is pretty
safe (and much faster than always hitting the database) since the only
problem I can think of with that is somebody actually getting a hold of the
cookie itself, but once that happens you're pretty much screwed anyway?

2. Agreed on the password business. The authentication part of my
application is not final, but at the moment I'm supporting two methods.
One, which is the preferred one, is via email: You input your email, I send
you a email with a (limited time) authentication link, you click it and
you're authenticated. I saw it used in a few places, I liked it and it was
easy for me to implement, so I thought I'd steal it. Secondly I have
classic username-password, since I want that as a last resort anyway. I
also still plan to provide sign in via Twitter / Google / Facebook but
haven't had the time to implement them yet (all of them take quite some
time to implement). The more of these I get implemented, the more I'll hide
the username-password route.

All of these sign-in strategies can probably be packaged up as nicely as
with the GitHub example you've implemented. A ready made directory of
authorization strategies should be available at some point for the Ur/Web
community, much easier to use that in any other language, exciting!

However, the way how to authenticate is orthogonal to the authorization
part and how I save that in cookies/DB tables, but point well taken.

3. Getenv being tagged as only having bening effect is much appreciated! I
was thinking that seemed weird, but wasn't sure. You have a point with the
key being in the binary. One thing I did think was nice about environment
variables was that I could pass a different key to each of my server
processes. I run a seperate Ur/Web server for each of my clients, so if one
key gets compromised, it doesn't affect the others.

Anyway, thanks a lot for the advice, you're an inspiration. For me it
basically comes down to either A. Trusting my signed cookie-setup to be
secure, or B. refactoring my app to mitigate the performance hit from using
the database to check the role of a user based on just a SessionId in a
cookie. With that I mean, ensuring I only "get" the session once in every
page generation function and passing the session around to all the
"repository" functions.

Op zo 20 jan. 2019 om 23:10 schreef Adam Chlipala <adamc at csail.mit.edu>:

> On 1/18/19 10:14 AM, Simon Van Casteren wrote:
>
> When a person logs in, username-password style, I make a cookie with this
> form:
>
> { Role: <ADT, admin or not basically>
> , Email: string
> , CreatedOn: time}
>
> I'm saving the role in the cookie, so subsequent security checks in the
> page generators and rpc functions don't need to hit the database.
>
> Actually, that's an insecure method.  The Ur/Web implementation is not
> meant to prevent cookie forgery!  Rather, it just tries to make sure any
> side-effecting operation that reads a cookie was triggered by an explicit
> form submission within your application (that's XSRF protection).
>
> 1. Is this safe? Is this a good solution? Or am I better off abandoning
> the whole thing and going back to putting just a SessionId inside a cookie
> and going to the database with that SessionId to check for authorization?
> Or another solution that I'm not thinking of at the moment?
>
> Creating a unique and effectively unguessable session identifier to store
> in the database is a pretty good solution.  Actually, however, I recommend
> avoiding implementing your own authentication whenever possible!  You could
> consider using the Ur/Web World library <https://github.com/urweb/world>,
> which is growing in a lazy manner, as different usage modes are requested.
> Specifically, it's only been used for authentication via GitHub, as far as
> I know.
>
> Passwords are just a sordid business, so best to avoid or at least push
> off onto some other web service, IMO.
>
> 2. A problem I'm having is storing the key that is needed to run the
> digest. My plan was to pass it via an environment variable to my program,
> but getenv inside a page generator causes the compiler to complain, saying
> that it could cause side-effects... Anybody have any ideas how to handle
> this? I feel like putting my key in plain text inside my source code is not
> very good, but maybe I'm wrong about that?
>
> I don't see a fundamental security advantage of a sensitive value in a
> source file (and therefore compiled into the application) vs. in an
> environment variable (and therefore presumably appearing as plaintext in a
> script somewhere to set the variable).  I would even think there is a teeny
> bit of extra security in compiling the key into a binary on a build machine
> and then uploading the binary to a server that will only have the key
> appearing in the binary instead of a more-easily-viewed text file.  (Of
> course, even a modestly sophisticated adversary can grab a password out of
> a binary.)
>
> However... it was an oversight that the compiler didn't recognize getenv
> as having only benign effects!  I believe I have fixed that issue now in
> the compiler, so please let me know if that method hasn't switched to
> working.
> _______________________________________________
> Ur mailing list
> Ur at impredicative.com
> http://www.impredicative.com/cgi-bin/mailman/listinfo/ur
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.impredicative.com/pipermail/ur/attachments/20190121/a639dfab/attachment.html>


More information about the Ur mailing list