Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Date: Mon, 20 Jun 2016 12:20:30 +0300
From: Anton Dedov <adedov@...il.com>
To: passwords@...ts.openwall.com
Subject: Re: Am I Overlooking any Practical Attacks?

Hi Scott,

JFYI, you can rate limit "known" and "unknown" clients differently, without
relying on IP addresses:
https://www.owasp.org/index.php/Slow_Down_Online_Guessing_Attacks_with_Device_Cookies

On Sun, Jun 19, 2016 at 10:12 AM, Scott Arciszewski <scott@...agonie.com>
wrote:

> Hi,
>
> I'm building a free software project that, I hope, will one day be the
> secure alternative to CMS platforms like WordPress, Drupal, Joomla, and so
> many others. One of the more interesting problems I tried to solve was
> secure code delivery for our plugin architecture. (If you've read about the
> triangle of secure code delivery, you've probably already got an idea of
> what that entails.)
>
> More importantly, I'm trying to eliminate the practical exploits against
> user authentication systems. I'd like to think I've covered most of them,
> but if anyone has any avenues for exploitation that I hadn't already
> addressed (except for "implant malware on the user's computer and log
> keystrokes" types of attacks, obviously), I would love to hear about them.
>
> Current security features that will be implemented as of v0.3.0 (releasing
> soon):
>
> * Weak passwords are rejected. Weak means a Zxcvbn score < 3 (this
> parameter can be configured). The rejection takes place server-side, but we
> also use zxcvbn.js to give users immediate feedback. Consequently, one of
> the 10,000 most common passwords will be accepted. The password feedback
> messages also strongly encourage the use of password managers.
>
> * In case your password gets leaked, two-factor authentication (HOTP/TOTP
> for things like Google Authenticator; emphatically NOT sending a SMS) is
> built-in. I'm going to expand this functionality to support hardware
> devices very soon.
>
> * Database dumps: We use Argon2i for password hashing (provided by
> libsodium). Hashes are then encrypted using Halite's symmetric encryption
> feature. The idea here is if you're using RDS (or otherwise have the
> database on separate bare metal than the webserver), finding a SQLi doesn't
> even give an attacker the hashes to begin cracking. (Even in absence of
> hardware separation, they're still Argon2i hashes!)
>
> Quick clarification: Halite is a libsodium wrapper. The symmetric
> encryption feature uses HKDF-BLAKE2b + Xsalsa20-then-keyedBLAKE2b with a
> 192-bit nonce, 256-bit key-splitting salt (to derive an encryption key and
> authentication key) and a 4-byte versioned header. This sounds like a lot,
> but developers' experience with this feature looks like this:
>
>     $ciphertext = Symmetric::encrypt($someString, $encryptionKeyObject);
>     try {
>         $plaintext = Symemtric::decrypt($ciphertext, $encryptionKeyObject);
>     } catch (InvalidMessage $ex) {
>         // Chosen-ciphertext attack?
>         // Or maybe the wrong encryption key key?
>         // Doesn't matter really. Fail appropriately.
>     }
>
> * Long-term cookie-based authentication: We use a two-part token. The
> first part is a unique random identifier used in the database lookups
> (which are assumed to leak timing information like most search operations).
> The second is stored wholesale in the cookie (but a hash is stored in the
> database). The user's cookie is re-hashed and compared with the stored hash
> (in constant time) to refresh a user's session automatically. If you reset
> your password, all long-term-auth tokens are invalidated server-side.
>
> * Account recovery: Most importantly, it's optional. Users can uncheck a
> box to prevent this from being used as a backdoor. Alternatively, they can
> leave it enabled and provide a PGP public key. Or they can throw caution to
> the wind and trust STARTTLS to not get stripped. The actual password
> recovery email contains a two-part random token (modeled after the
> long-term authentication tokens) that expires in (by default) an hour.
> There also exists a configuration option that invalidates all of the user's
> other browsing sessions the second they change their password.
>
> * Session attacks: If the current connection is over TLS, we send HSTS
> headers and all cookies are set to secure=1 (httpOnly=1 is enforced either
> way). We explicitly enforce the session ID to use the operating system's
> CSPRNG. Session IDs are rotated upon privilege change.
>
> * User accounts are totally separate from Author profiles -- blog posts
> and comments are attributed to Authors, not users. Many users can share
> access to a specific Author, and each user can have access to many authors.
>
> * Usernames aren't even used in the course of interacting with other users
> (e.g. to invite another user to your Author profile). Instead you have a
> Public ID (a randomly generated Base64UrlSafe string) which is also used in
> your uploaded files "directory" (the filesystem is virtual; I don't trust
> Apache nor most user's configuration knowledge to not accidentally make an
> uploaded file executable) and a "display name", which you can change at any
> time. Your username is strictly used for authentication.
>
> * Login and account recovery attempts have progressive throttling -- based
> on IP subnet (configurable by the site administrator; defaults to /32 for
> IPv4 and /48 for IPv6) or username. You can set the initial delay (default:
> 250ms) and the cap (default: 30s); it will double with each successive
> failed attempt. This helps to prevent users from hammering the RAM/CPU with
> a barrage of Argon2i calculations and amplifying a DDoS attempt. The delay
> can be configured in two modes: fast-exit (aborts and tells them to wait a
> while before trying again) or sleep (avoids a UX wart, but is worse for
> security -- an attacker might be able to use this to fill up the worker
> process pool and block legitimate traffic). Conversely, in the fast-exit
> case, someone who guesses your username would be able to deny a specific
> user from logging in.
>
> * Although I can't say it's completely gone, to minimize the risk of
> username enumeration via timing information, we "verify" a hash of a dummy
> password. Unlike my Underhanded Crypto Contest entry last year, this isn't
> a backdoor. (Feel free to verify if you're curious!)
>
> * Just in case something weird happens during the login process, passwords
> are obfuscated from stack traces by the use of a HiddenString class.
>
> I like to think I've got everything covered. What am I missing?
>
> Links/references in case anyone wants to read more:
>
>     The project I'm building: https://github.com/paragonie/airship
>
>     The triangle of secure code delivery:
> https://defuse.ca/triangle-of-secure-code-delivery.htm
>
>     How Airship will tackle secure code delivery:
> https://paragonie.com/blog/2016/05/keyggdrasil-continuum-cryptography-powering-cms-airship
>
>     Zxcvbn: https://github.com/dropbox/zxcvbn
>
>     Libsodium: https://github.com/jedisct1/libsodium
>
>     Halite: https://github.com/paragonie/halite
>
>     Proactively secure long-term user authentication:
> https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence#title.2.1
>
>     My UnderCrypto contest entry write-up:
> https://paragonie.com/blog/2016/01/on-design-and-implementation-stealth-backdoor-for-web-applications
>
> Kind regards,
>
> Scott Arciszewski
> Chief Development Officer
> Paragon Initiative Enterprises <https://paragonie.com>
>



-- 
Anton Dedov

Content of type "text/html" skipped

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.