{"id":316,"date":"2014-09-18T23:16:38","date_gmt":"2014-09-18T21:16:38","guid":{"rendered":"https:\/\/blogs.gentoo.org\/mgorny\/?p=316"},"modified":"2014-09-19T00:33:22","modified_gmt":"2014-09-18T22:33:22","slug":"password-security-in-network-applications","status":"publish","type":"post","link":"https:\/\/blogs.gentoo.org\/mgorny\/2014\/09\/18\/password-security-in-network-applications\/","title":{"rendered":"Password security in\u00a0network applications"},"content":{"rendered":"<p>While we have many interesting modern authentication methods, password authentication is still the\u00a0most popular choice for network applications. It&#8217;s simple, it doesn&#8217;t require any special hardware, it doesn&#8217;t discriminate anyone in\u00a0particular. It just works\u2122.<\/p>\n<p>The\u00a0key requirement for maintaining security of a\u00a0secret-based authentication mechanism is the\u00a0secrecy of\u00a0the\u00a0secret (password).  Therefore, it is very important for the\u00a0designer of\u00a0network applications regard the\u00a0safety of\u00a0password as\u00a0essential and\u00a0do\u00a0their best to protect it.<\/p>\n<p>In\u00a0particular, the\u00a0developer can affect the\u00a0security of\u00a0password<br \/>\nin\u00a0three manners:<\/p>\n<ol>\n<li>through the\u00a0security of\u00a0server-side key storage,<\/li>\n<li>through the\u00a0security of\u00a0the\u00a0secret transmission,<\/li>\n<li>through encouraging user to follow the\u00a0best practices.<\/li>\n<\/ol>\n<p>I will expand on\u00a0each of\u00a0them in\u00a0order.<\/p>\n<p><!--more--><\/p>\n<h2>Security of\u00a0server-side key storage<\/h2>\n<p>For the\u00a0secret-based authentication to work, the\u00a0server needs to store some kind of\u00a0secret-related information. Commonly, it stores the\u00a0complete user password in\u00a0a\u00a0database. Since it can be a\u00a0valuable information, it should be\u00a0especially protected so that even in\u00a0case of\u00a0unauthorized access to the\u00a0system the\u00a0attacker can not obtain it easily.<\/p>\n<p>This could be\u00a0achieved through use of\u00a0key derivation functions, for\u00a0example. In\u00a0this case, a\u00a0derived key is\u00a0computed from user-provided password and\u00a0used in\u00a0the\u00a0system. With a\u00a0good design, the\u00a0password could actually never leave client&#8217;s computer \u2014 it can be\u00a0converted straight to the\u00a0derived key there, and\u00a0the\u00a0derived key may be used from this point forward. Therefore, the\u00a0best than an\u00a0attacker could get is the\u00a0derived key with no\u00a0trivial way of\u00a0obtaining the\u00a0original secret.<\/p>\n<p>Another interesting possibility is restricting access to the\u00a0password store. In\u00a0this case, the\u00a0user account used to run the\u00a0application does not have read or\u00a0write access to the\u00a0secret database. Instead, a\u00a0proxy service is used that provides necessary primitives such as:<\/p>\n<ul>\n<li>authenticating the\u00a0user,<\/li>\n<li>changing user&#8217;s password,<\/li>\n<li>and allowing user&#8217;s password reset.<\/li>\n<\/ul>\n<p>It is\u00a0crucial that none of\u00a0those primitives can be\u00a0used without proving necessary user authorization. The\u00a0service must provide no means to\u00a0obtain the\u00a0current password, or to\u00a0set a\u00a0new password without proving user authorization. For\u00a0example, a\u00a0password reset would have to be\u00a0confirmed using authentication token that is sent to\u00a0user&#8217;s e-mail address (note that the\u00a0e-mail address must be\u00a0securely stored too) directly by\u00a0the\u00a0password service \u2014 that is, omitting the\u00a0potentially compromised application.<\/p>\n<p>Examples of\u00a0such services are PAM and\u00a0LDAP. In\u00a0both cases, only the\u00a0appropriately privileged system or\u00a0network administrator has access to\u00a0the\u00a0password store, while every user can access the\u00a0common authentication and\u00a0password setting functions. In\u00a0case a\u00a0bug in\u00a0the\u00a0application serves as a\u00a0backdoor to\u00a0the\u00a0system, the\u00a0attacker does not have sufficient privileges to read the\u00a0passwords.<\/p>\n<h2>Security of\u00a0secret transmission<\/h2>\n<p>The\u00a0authentication process and\u00a0other functions involving transmitting secrets over network are the\u00a0most security-concerning processes in\u00a0the\u00a0password&#8217;s lifetime.<\/p>\n<p>I think this topic has been satisfactorily described multiple times, so I will just summarize the\u00a0key points shortly:<\/p>\n<ol>\n<li>Always use secured (TLS) connection both for\u00a0authentication and\u00a0post-authentication operations. This has multiple advantages, including protection against eavesdropping, message tampering, replay and\u00a0man-in-the-middle attacks.<\/li>\n<li>Use sessions to avoid having to re-authenticate on\u00a0every request.  However, re-authentication may be\u00a0desired when accessing data crucial to security \u2014 changing e-mail address, for example.<\/li>\n<li>Protect the\u00a0secrets as\u00a0early as\u00a0possible. For\u00a0example, if\u00a0derived key is\u00a0used for\u00a0authentication, prefer deriving it client-side before the\u00a0request is sent. In\u00a0case of\u00a0webapps, this could be done using ECMAScript, for example.<\/li>\n<li>Use secure authentication methods if\u00a0possible. For\u00a0example, you can use challenge-response authentication to avoid transmitting the\u00a0secret at\u00a0all.<\/li>\n<li>Provide alternate authentication methods to reduce the\u00a0use of\u00a0the\u00a0secret. Asymmetric key methods (such as\u00a0client certificates or\u00a0SSH pre-authentication) are both convenient and\u00a0secure.  Alternative one-time passwords can benefit the\u00a0use of\u00a0application on\u00a0public terminals that can&#8217;t be\u00a0trusted being secure from\u00a0keylogging.<\/li>\n<li>Support two-factor authentication if\u00a0possible. For\u00a0example, you can supplement password authentication with TOTP. Preferably, you may use the\u00a0same TOTP parameters as\u00a0Google Authenticator uses, effectively enabling your users to\u00a0use multiple applications designed to\u00a0serve that purpose.<\/li>\n<li>And\u00a0most importantly, <em>never ever send user&#8217;s password back to him<\/em> or\u00a0show it to\u00a0him. For preventing mistakes, ask user to type the\u00a0password twice. For providing password recovery, generate and\u00a0send pseudorandom authorization token, and\u00a0ask the\u00a0user to\u00a0set a\u00a0new password after using it.<\/li>\n<\/ol>\n<h2>Best practices for\u00a0user management of\u00a0passwords<\/h2>\n<p>Server-side key storage and\u00a0authentication secured, the\u00a0only potential weakness left is the\u00a0user&#8217;s system. While the\u00a0application administrator can&#8217;t \u2014 or\u00a0often shouldn&#8217;t \u2014 control it, he should encourage user to use best practices for password security.<\/p>\n<p>Those practices include:<\/p>\n<ol>\n<li>Using a secure, hard-to-guess password. Including a\u00a0properly working password strength meter and\u00a0a\u00a0few tips is a\u00a0good way of\u00a0encouraging this. However, as\u00a0explained below, weak password should merely issue a\u00a0warning rather than a\u00a0fatal error.<\/li>\n<li>Using different passwords for separate applications to\u00a0reduce the\u00a0damage resulting from an\u00a0attack resulting in\u00a0obtaining the\u00a0secret.<\/li>\n<li>If the\u00a0user can&#8217;t memorize the\u00a0password, using a\u00a0dedicated, <em>encrypted<\/em> key store or\u00a0a\u00a0secure password derivation method. Examples of\u00a0the\u00a0former include built-in browser and\u00a0system-wide password stores, and\u00a0also dedicated applications such as\u00a0<a rel='external' href='http:\/\/keepass.info\/'>KeePass<\/a>. Example of\u00a0the\u00a0latter is <a rel='external' href='http:\/\/rampantlogic.com\/entropass\/'>Entropass<\/a> that uses a\u00a0user-provided master password and\u00a0salt constructed from the\u00a0site&#8217;s domain.<\/li>\n<li>Using the\u00a0password only in\u00a0response to\u00a0properly authenticated requests. In\u00a0particular, the\u00a0application should have a\u00a0clear policy when the\u00a0password can be\u00a0requested and\u00a0how the\u00a0authenticity of\u00a0the\u00a0application can be\u00a0verified.<\/li>\n<\/ol>\n<p>A\u00a0key point is that all the\u00a0good practices should be encouraged, and\u00a0the\u00a0developer should never attempt to force them. If\u00a0there should be any limitations on\u00a0allowed passwords, they should be\u00a0rather technical and\u00a0rather flexible.<\/p>\n<p>If\u00a0there should be\u00a0a\u00a0minimum length for a\u00a0password, it should only focus on\u00a0withstanding the\u00a0first round of\u00a0a\u00a0brute force attack. Technically saying, any limitation actually reduces entropy since the\u00a0attacker can safely omit short passwords. However, with the\u00a0number of\u00a0possibilities growing incrementally this doesn&#8217;t even matter.<\/p>\n<p>Similarly, requiring the\u00a0password to contain characters from a\u00a0specific set is a\u00a0bad idea. While it may sound good at\u00a0first, it is yet another way of\u00a0reducing entropy and\u00a0making the\u00a0passwords more predictable. Think of\u00a0the\u00a0sites that require the\u00a0password to contain at\u00a0least one digit. How many users have passwords ending with the digit one (1), or\u00a0maybe their birth year?<\/p>\n<p>The\u00a0worst case are the\u00a0sites that do not support setting your own password, and\u00a0instead force you to use a\u00a0password generated using some kind of\u00a0pseudo-random algorithm. Simply said, this is an\u00a0open invitation to write the\u00a0password down. And\u00a0once written down in\u00a0cleartext, the\u00a0password is no\u00a0longer a\u00a0secret.<\/p>\n<p>Setting low upper limits on\u00a0passwords is not a\u00a0good idea either. It is reasonable to set some technical limitations, say, 255\u00a0bytes of\u00a0ASCII printable characters. However, setting the\u00a0limit much lower may actually reduce the\u00a0strength of\u00a0some of\u00a0user passwords and\u00a0collide with some of\u00a0the\u00a0derived keys.<\/p>\n<p>Lastly, the\u00a0service should clearly state when it may ask for user&#8217;s password and\u00a0how to check the\u00a0authenticity of\u00a0the\u00a0request. This can involve generic instructions involving TLS certificate and\u00a0domain name checks. It may also include site-specific measures like user-specific images on\u00a0login form.<\/p>\n<p>Having a\u00a0transparent security-related announcements policy and\u00a0information page is a\u00a0good idea as\u00a0well. If\u00a0a\u00a0site provides more than one service (e.g. e-mail accounts), the\u00a0website can list certificate fingerprints for the\u00a0other services. Furthermore, any certificate or\u00a0IP address changes can be\u00a0preceded by\u00a0a\u00a0GPG-signed mail announcement.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>While we have many interesting modern authentication methods, password authentication is still the\u00a0most popular choice for network applications. It&#8217;s simple, it doesn&#8217;t require any special hardware, it doesn&#8217;t discriminate anyone in\u00a0particular. It just works\u2122. The\u00a0key requirement for maintaining security of a\u00a0secret-based authentication mechanism is the\u00a0secrecy of\u00a0the\u00a0secret (password). Therefore, it is very important for the\u00a0designer of\u00a0network &hellip; <a href=\"https:\/\/blogs.gentoo.org\/mgorny\/2014\/09\/18\/password-security-in-network-applications\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Password security in\u00a0network applications&#8221;<\/span><\/a><\/p>\n","protected":false},"author":137,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true},"categories":[9],"tags":[],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/316"}],"collection":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/users\/137"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/comments?post=316"}],"version-history":[{"count":12,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/316\/revisions"}],"predecessor-version":[{"id":329,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/posts\/316\/revisions\/329"}],"wp:attachment":[{"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/media?parent=316"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/categories?post=316"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.gentoo.org\/mgorny\/wp-json\/wp\/v2\/tags?post=316"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}