<div dir="auto"><div dir="ltr">Hey Adam,<div><br></div><div>As always, thanks a lot for your insights.</div><div><br></div><div>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?</div><div><br></div><div>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.</div><div><br></div><div>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!</div><div><br></div><div>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.</div><div><br></div><div>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. </div><div><br></div><div>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.</div></div><br><div class="gmail_quote"><div dir="ltr" class="m_-4707506011536595182gmail_attr">Op zo 20 jan. 2019 om 23:10 schreef Adam Chlipala <<a href="mailto:adamc@csail.mit.edu" target="_blank" rel="noreferrer">adamc@csail.mit.edu</a>>:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  
    
  
  <div bgcolor="#FFFFFF">
    <div class="m_-4707506011536595182gmail-m_-5798842432911936417moz-cite-prefix">On 1/18/19 10:14 AM, Simon Van Casteren
      wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">When a person logs in, username-password style, I
        make a cookie with this form:
        <div><br>
        </div>
        <div>{ Role: <ADT, admin or not basically></div>
        <div>, Email: string</div>
        <div>, CreatedOn: time}</div>
        <div><br>
        </div>
        <div>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.</div>
      </div>
    </blockquote>
    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).<br>
    <blockquote type="cite">
      <div dir="ltr">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?</div>
    </blockquote>
    <p>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 <a href="https://github.com/urweb/world" target="_blank" rel="noreferrer">the
        Ur/Web World library</a>, 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.</p>
    <p>Passwords are just a sordid business, so best to avoid or at
      least push off onto some other web service, IMO.<br>
    </p>
    <blockquote type="cite">
      <div dir="ltr">
        <div>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?</div>
      </div>
    </blockquote>
    <p>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.)</p>
    <p>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.<br>
    </p>
  </div>

_______________________________________________<br>
Ur mailing list<br>
<a href="mailto:Ur@impredicative.com" target="_blank" rel="noreferrer">Ur@impredicative.com</a><br>
<a href="http://www.impredicative.com/cgi-bin/mailman/listinfo/ur" rel="noreferrer noreferrer" target="_blank">http://www.impredicative.com/cgi-bin/mailman/listinfo/ur</a><br>
</blockquote></div></div>