This article is provided by special arrangement with the
Open Web Application Security
Project (OWASP). This article is covered by the
Creative
Commons Share-Alike Attribution 2.5 license. You can find the
latest version of this article and more free and open application
security tools and documentation at
http://www.owasp.org.
Authentication
Objective
To provide secure authentication services to web applications,
by:
- Tying an system identity to an individual user by the use of a
credential
- Providing reasonable authentication controls as per the
application's risk
- Denying access to attackers who use various methods to attack
the authentication system
Environments Affected
All.
Relevant COBIT Topics
DS5 – All sections should be reviewed. This section covers nearly
all COBIT detailed
control objectives.
Best Practices
- Authentication is only as strong as your
user management
processes, and in particular the user issuance and evidence
of identity policies.
The stronger the requirement for non-repudiation, the more
expensive the process. - Use the most appropriate form of
authentication suitable for your asset
classification. For example, username and password is
suitable for low value systems
such as blogs and forums, SMS challenge response is suitable for
low value e-commerce
systems (in 2005), whilst transaction signing is suitable for high
value systems such as
high value e-commerce (all e-commerce sites should consider it by
2007), banking and
trading systems. - Re-authenticate the user for high value
transactions and access to protected areas
(such as changing from user to administrative level access) - Authenticate the transaction, not the
user. Phishers rely on poorly implemented user
authentication schemes - Passwords are trivially broken and are unsuitable for high
value systems. Therefore,
the controls should reflect this. Any password less than 16
characters in length can be
brute forced in less than two weeks, so set your password policy to
be reasonable:
- Train your users as to suitable password construction
- Allow your users to write down their passwords as long as they
keep them safe
- Encourage users to use pass phrases instead of passwords
- Relax password expiry requirements upon the strength of the
password chosen --
passwords between 8 and 16 that cannot be easily cracked should
have an expiry of
no less than 30 days, and pass phrases above 16 characters probably
do not need a
hard expiry limit, but a gentle reminder after (say) 90 days
instead.
Common web authentication techniques
Basic and Digest authentication
Nearly all web and application servers support the use of basic and
digest authentication.
This requires the web browser to put up a dialog box to take the
user's name and password, and
send them through to the web server, which then processes them
against its own user database, or
in the case of IIS, against Active Directory.
- Basic authentication sends the credential in the clear. It
should not be used unless in
combination with SSL - HTTP 1.0 Digest authentication only obfuscates the password. It
should not be used.
- HTTP 1.1 Digest authentication uses a challenge response
mechanism, which is
reasonably safe for low value applications.
The primary reason against the use of basic or digest
authentication is due to:
- Insecure transmission of credentials Both forms of
authentication suffer from replay and man-in-the middle
attacks
- Both require SSL to provide any form of confidentiality and
integrity
- The user interface is reasonably ugly
- Does not provide a great deal of control to the end
application.
This is not to say that basic or digest authentication is not
useful. It can be used to shield
development sites against casual use or to protect low value
administrative interfaces, but other
than that, this form of authentication is not recommended.
Forms based authentication
Forms based authentication provides the web application designer
the most control over the
user interface, and thus it is widely used.
Forms based authentication requires the application to do a fair
amount of work to implement
authentication and authorization. Rarely do web applications get it
right. The sections on how to
determine if you are vulnerable have upwards of 15 specific
controls to check, and this is the
minimum required to authenticate with some safety.
If at all possible, if you choose to use forms based
authentication, try to re-use a trusted
access control component rather than writing your own.
Forms based authentication suffers from:
- Replay attacks
- Man in the middle attacks
- Clear text credentials
- Luring attacks
- Weak password controls
And many other attacks as documented in "How to determine if you
are vulnerable."
It is vital that you protect login interchanges using SSL, and
implement as many controls as
possible. A primary issue for web application designers is the cost
to implement these controls
when the value of the data being protected is not high. A balance
needs to be struck to ensure
that security concerns do not outweigh a complex authentication
scheme.
Integrated authentication
Integrated authentication is most commonly seen in intranet
applications using Microsoft IIS
web server and ASP.NET applications. Most other web servers do not
offer this choice.
Although it can be secure – on a par with client-side certificate
authentication due to the use of
Kerberos-based Active Directory integration (which means no
credentials need to be stored by
the application or typed by the user), it is not common on Internet
facing applications.
If you are developing an Intranet application and your
development environment supports
integrated authentication, you should use it. It means less work
for you to develop authentication
and authorization controls, one less credential for users to
remember, and you can re-use pre-
existing authentication and authorization infrastructure.
Certificate based authentication
Certificate based authentication is widely implemented in many web
and application servers.
The web site issues certificates (or attempts to trust externally
issued certificates). The public
certificates are loaded into the web server's authentication
database, and compared with an
offering from incoming browser sessions. If the certificates match
up, the user is authenticated.
The quality of authentication is directly related to the quality
of the public key infrastructure
used to issue certificates. A certificate issued to anyone who asks
for them is not as trustworthy
as certificates issued after seeing three forms of photo
identification (such as passport, driver's
license or national identification card).
There are some drawbacks to certificate-based logon:
- Many users share PC's and they need to have bring their
certificates along with them.
This is non-trivial if the user had the application install the
certificate for them – most
users are completely unaware of how to export and import
certificates. - The management of certificates on a browser is non-trivial in
many instances.
- Certificate revocation with self-issued certificates is almost
impossible in extranet
environments. - Trust of "private" certificate servers requires end-user trust
decisions, such as importing
root CA certificates, which end users are probably not qualified to
make this trust
decision. - The cost of certificates and their part in the business model
of public certificate
companies is not related to the cost of provision, and thus it is
expensive to maintain a
public certificate database with a large number of users.
Coupled with the poor management of many CA's, particularly
regarding certificate renewal,
certificate-based logon has almost always failed. A good example is
Telstra's online billing
service. At one stage, only digital certificates were acceptable.
Now, this option is being retired.
Strong Authentication
Strong authentication (such as tokens, certificates, etc) provides
a higher level of security
than username and passwords. The generalized form of strong
authentication is "something you
know, something you hold". Therefore, anything that requires a
secret (the "something you
know") and authenticator like a token, USB fob, or certificate (the
"something you hold") is a
stronger control than username and passwords (which is just
"something you know") or
biometrics ("something you are").
When to use strong authentication
Certain applications should use strong authentication:
- For high value transactions
- Where privacy is a strong or legally compelled consideration
(such as health records,
government records, etc) - Where audit trails are legally mandated and require a strong
association between a person
and the audit trail, such as banking applications - Administrative access for high value or high risk
systems
What does high risk mean?
Every organization has a certain threshold for risk, which can
range from complete ignorance
of risk all the way through to paranoia.
For example, forum software discussing gardening does not
require strong authentication,
whereas administrative access to a financial application processing
millions of dollars of
transactions daily should be mandated to use strong
authentication.
Biometrics are not strong authentication … by
themselves
Biometrics can be the "something you hold", but they do not replace
the "something you
know". You should always use biometrics along with username and
passwords, as otherwise, it
significantly weakens the trust in the authentication
mechanism.
Biometrics are not as strong as other forms of strong
authentication for remotely accessible
web applications because:
The devices are in the control of the attacker – and most low
end biometric devices are not
tamperproof nor do they have strong replay protection.
Remote enrollment cannot be trusted – users might substitute
others, enroll a glass eye, or a
picture out of a magazine.
The biometric features being measured cannot be revoked – you
only have two eyes, ten
fingers and one face. This is a deadly combination for high value
systems – attackers have
previously shown they will cut off fingers to obtain a car.
Biometrics are thus too risky for high
value systems.
The biometric features being measured do not change – USB keys
with inbuilt crypto engines
and other fobs have a pseudo-random output that changes every 30
seconds. Distinguishing
features such as loops and whirls do not .
High false positive rates compared to the cost of the
authentication mechanism. With other
forms of strong authentication, there are no false accepts.
Most consumer biometric devices are easily spoofed or subject to
replay attacks. The more
expensive devices are not necessarily much better than their
affordable counterparts, but for the
same price as a high end biometric device, you can own 50 or 60
fobs and upwards of 1000
smart cards.
When used in a single factor authentication method (for example,
just a thumbprint with no
username or password), biometrics are the weakest form of
authentication available and are
unsuitable for even moderate risk applications. Such usage should
be restricted to devices the
user owns without sensitive or risky data.
Relative strengths and uses of strong authentication
One-time passwords
One time password fobs are cheap – many can be obtained for as
little as $5-10, but they
only protect against password replay. One time password fobs
usually have a number displayed
on a screen, and the user will type in their username, pass phrase
and the one time password.
One time passwords do not help with man-in-the-middle attacks
and as they do not present
any details of the use to the user, so spoofed web sites could
collect a one time password and log
on as the user and perform a transaction.
Soft certificates
Soft certificates (also known as client-side certificate
authentication) are a little stronger than
passwords, but suffer from the same problems as passwords and any
authentication method
which automatically processes credentials.
Connected hard
certificates
USB, PC Card, or otherwise connected tokens which can be
programmatically interrogated
by the user's system seem like the best way to store a credential.
Although they typically protect
against unauthorized duplication of the credential and tampering of
the algorithm, as the device
is connected to an untrusted host, the hard certificate might be
used by an attacker's site directly,
bypassing the otherwise robust authentication mechanism
provided.
Most tokens pop up a window that asks the user for permission to
supply the credential. An
attacker could pop up a similar window, obtain the authentication
blob, and forward it to the real
system whilst performing an entirely different transaction. This
attack works due to two reasons:
- Chrome on authentication request window – the pop up has no
clear relationship between
application and authentication. This is a problem with all
Javascript alerts, and not unique
to this functionality - User brain bypass – most users familiar with an application
will simply agree to a dialog
they see all the time. As long as the attacker makes a good
facsimile of the authentication
approval window, they will agree to it.
Many other issues surround connected devices, including desktop
support issues if the
drivers for the hard certificate interfere with the operation of
the user's computer.
Connected devices are suitable for trusted internal access, and
closed and trusted user
communities.
Challenge Response
Challenge response tokens work by taking a value (challenge) from
the system and
processing them in a cryptographically secure fashion to derive a
result.
Challenge response calculators have a keypad, and therefore the
password is usually
considered to the be the PIN required to access the calculator. The
user enters their username and
response into the system, which is verified by the authentication
server.
Although protecting against replay attacks, challenge response
tokens suffer from
authentication disconnection issue discussed above. The user is
approving something, but it is
not clear what.
SMS Challenge Response
SMS challenge works in countries with a high penetration of text
message capable mobile
phones. The typical method is to enrol the user in a trusted
fashion, registering their mobile
phone number. When an authentication or transaction signing is
required, the application sends
the user a transaction number to their mobile phone, hopefully with
some surrounding text to
verify what is being signed (such as the reference ID of the
transaction).
Problems with SMS challenge response include:
- It's a public path; do not send sensitive information with the
challenge.
- If sending the transaction amount, the user may trust this
figure, but an attacker may send
the user one figure and approve another. - You are not the only source of SMS messages; the user can not
verify the source of the
SMS beyond only expecting them when they are using the
system.
Despite this, SMS challenge response is significantly stronger than
username and password
with minimal cost overheads.
Transaction Signing
Transaction signing is performed by offline challenge response
calculators. The user will be
presented with various items to enter into the calculator, and it
will calculate a response based
upon these inputs. This is the strongest form of authentication as
the user has to enter the
transaction details – any other transaction will fail to produce a
suitable response. This type of
authentication has strong non-repudiation properties, is robust
against man in the middle attacks,
cannot be replayed, and is robust against differing transaction
limits.
For the best effect, at least the following should be stirred
into the challenge:
- Reference ID
- From account
- Amount of the transaction
The tokens are usually date and time based, so there's only a
little to be gained by entering
the transaction date. The downsides of these tokens are
- It can take up to 20 to 40 keystrokes to complete a
transaction, which is problematic if the
user has to approve each and every transaction - If a token is connected to the user's computer or uses some
form of automated entry,
although the human factors are better (no details to enter), the
non-repudiation property is
removed as the user no longer is required to think about the value
of the transaction --
they just approve the signing window, which is no better than a
soft-certificate.
Therefore, although most of the calculators for transaction
signing allow connection to the
client computer, this functionality should not be used or made
available.
Although transaction signing calculators and EMV (smart card)
style calculators are identical
in functionality from the application's point of view, they have
different values to the user. A
calculator will be left on a desk for all to see, whereas an EMV
smartcard masquerading as the
user's corporate credit card has the appropriate value to the user
– they will not leave them on the
desk or in their unlocked drawer. The value of the system should
decide which type of
transaction signing token is provided to the user.
Challenges to using strong authentication
Most common application frameworks are difficult to integrate with
strong authentication
mechanisms, with the possible exception of certificate-based logon,
which is supported by J2EE
and .NET.
Your code must be integrated with an authentication server, and
implicitly trust the results it
issues. You should carefully consider how you integrate your
application with your chosen
mechanism to ensure it is robust against injection, replay and
tampering attacks.
Many organizations are wary of strong authentication options are
they are perceived to be
"expensive". They are, but so are passwords. The costs of user
management are not usually
related to the cost of the authentication infrastructure, but
relate instead to the issuance and
maintenance of the user records. If you need to have strong
non-repudiation the most formidable
and costly aspect of user management is enrolment, maintenance and
de-enrolment. Simply
sending any user who asks for an account a token or certificate
provides no certainty that the user
is who they say they are. A robust trusted enrolment path is
required to ensure that the
authentication system is "strong".
Federated Authentication
Federated authentication allows you to outsource your user database
to a third party, or to run
many sites with a single sign on approach. The primary business
reason for federated security is
that users only have to sign on once, and all sites that support
that authentication realm can trust
the sign-on token and thus trust the user and provide personalized
services.
Advantages of federated authentication:
- Reduce the total number of credentials your users have to
remember
- Your site(s) are part of a large trading partnership, such as
an extranet procurement
network - Would like to provide personalized services to otherwise
anonymous users.
You should not use federated authentication unless:
- You trust the authentication provider
- Your privacy compliance requirements are met by the
authentication provider
The Laws of Identity
Kim Cameron, Identity Architect of Microsoft has established a
group blog focusing on the
risks surrounding federated identity schemes. The blog established
a set of papers, with seven
laws of identity. These are:
- User Control and Consent: Digital
identity systems must only reveal
information identifying a user with the user's consent. - Limited Disclosure for Limited Use:
The solution which discloses the least
identifying information and best limits its use is the most stable,
long-term
solution. - The Law of Fewest Parties: Digital
identity systems must limit disclosure of
identifying information to parties having a necessary and
justifiable place in a
given identity relationship. - Directed Identity: A universal
identity metasystem must support both
"omnidirectional" identifiers for use by public entities and
"unidirectional"
identifiers for private entities, thus facilitating discovery while
preventing
unnecessary release of correlation handles. - Pluralism of Operators and
Technologies: A universal identity metasystem
must channel and enable the interworking of multiple identity
technologies run by
multiple identity providers. - Human Integration: A unifying
identity metasystem must define the human user
as a component integrated through protected and unambiguous
human-machine
communications. - Consistent Experience Across
Contexts: A unifying identity metasystem must
provide a simple consistent experience while enabling separation of
contexts
through multiple operators and technologies.
(Source:
http://www.identityblog.com/stories/2005/05/13/TheLawsOfIdentity.html
)
It is unclear at the time of writing if these "laws" will end up
changing the identity landscape,
but many of the issues discussed in the laws should be considered
by implementers of federated
authentication.
SAML
SAML is a part of the Liberty Alliance's mechanism to provide
federated authentication,
although it is not just for federated authentication.
At the time of writing, there is no direct support for SAML in
any major off-the-shelf
application framework (J2EE, PHP, or .NET). Third party libraries,
including open source
implementations, are available for J2EE. Microsoft has (very)
limited support for SAML in the
Web Services Enhancement 2.0 SP2, which requires .NET Framework
1.1.
For more details on how the SAML protocol works, see the Web
Services chapter.
Microsoft Passport
Microsoft Passport is an example of federated authentication, used
for Hotmail, delivery of
software, instant messaging, and for a time, by partners such as
eBay. Microsoft's .NET
framework supports Passport sign-on. There is limited support for
other platforms. However,
Microsoft has withdrawn partner Passport usage, so using Passport
is no longer available and is
not discussed further.
Considerations
There is limited take up of federated sign on at the moment, and
unless your business
requirements state that you need to support single-sign on with
many different bodies, you
should avoid the use of federated sign-on.
Client side authentication controls
Client-side validation (usually written in JavaScript) is a good
control to provide immediate
feedback for users if they violate business rules and to lighten
the load of the web server.
However, client-side validation is trivially bypassed.
How to determine if you are vulnerable
action against the target web server.
You are now free to violate client-side input validation. This
form is also much easier to use
with automated attack tools.
How to protect yourself
To protect your application, ensure that every validation and
account policy / business rule is
checked on the server-side.
For example, if you do not allow blank passwords (and you
shouldn't), this should be tested
at the least on the server-side, and optionally on the client-side.
This goes for "change password"
features, as well.
For more information, please read the Validation section in this
book.
Positive Authentication
Unfortunately, a generic good design pattern for authentication
does not fit all cases.
However, some designs are better than others. If an application
uses the following pseudo-code
to authenticate users, any form of fall through will end up with
the user being authenticated due
to the false assumption that users mostly get authentication
right:
bAuthenticated := true
try {
userrecord := fetch_record(username)
if userrecord[username].password != sPassword then
bAuthenticated := false
end if
if userrecord[username].locked == true then
bAuthenticated := false
end if
…
}
catch {
// perform exception handling, but continue
}
How to determine if you are vulnerable
To test, try forcing the authentication mechanism to fail.
If a positive authentication algorithm is in place, it is likely
that any failure or part failure will
end up allowing access to other parts of the application. In
particular, test any cookies, headers,
or form or hidden form fields extensively. Play around with sign,
type, length, and syntax. Inject
NULL, Unicode and CRLF, and test for XSS and SQL injections. See if
race conditions can be
exploited by single stepping two browsers using a JavaScript
debugger.
How to protect yourself
The mitigation to positive authentication is simple: force negative
authentication at every
step:
bAuthenticated := false
securityRole := null
try {
userrecord := fetch_record(username)
if userrecord[username].password != sPassword then
throw noAuthentication
end if
if userrecord[username].locked == true then
throw noAuthentication
end if
if userrecord[username].securityRole == null or banned then
throw noAuthentication
end if
… other checks …
bAuthenticated := true
securityRole := userrecord[username].securityRole
}
catch {
bAuthenticated := false
securityRole := null
// perform error handling, and stop
}
return bAuthenticated
By asserting that authentication is true and applying the
security role right at the end of the
try block stops authentication fully and forcefully.
Multiple Key Lookups
Code that uses multiple keys to look up user records can lead to
problems with SQL or
LDAP injection. For example, if both the username and password are
used as the keys to finding
user records, and SQL or LDAP injection is not checked, the risk is
that either field can be
abused.
For example, if you want to pick the first user with the
password "password", bypass the
username field. Alternatively, as most SQL lookup queries are
written as "select * from table
where username = username and password = password, this knowledge
may be used by an
attacker to simply log on with no password (ie truncating the query
to "select * from
username='username'; -- and password = 'don't care''"). If username
is unique, it is the key.
How to determine if you are vulnerable
Your application is at risk if all of the following are true:
- More than just the username is used in the lookup query.
- The fields used in the lookup query (eg, username and password)
are unescaped and can
be used for SQL or LDAP injection.
To test this, try performing a SQL injection (or LDAP injection)
against the login page,
masking out one field by making it assert to true:
Login: a' or '1'='1
Password: password
Login: a)(|(objectclass=*)
Password: password
If the above works, you'll authenticate with the first account
with the password "password",
or generate an error that may lead to further breaks. You'd be
surprised how often it works.
How to protect yourself
- Strongly test and reject, or at worst sanitize - usernames
suitable for your user store (i.e.
aim to escape SQL or LDAP meta characters) - Only use the username as the key for queries
- Check that only zero or one record is returned
Java
-----------------------------------------------------------------
public static bool isUsernameValid(string username) {
RegEx r = new Regex("^[A-Za-z0-9]{16}$");
return r.isMatch(username);
}
// java.sql.Connection conn is set elsewhere for brevity.
PreparedStatement ps = null;
RecordSet rs = null;
try {
isSafe(pUsername);
ps = conn.prepareStatement("SELECT * FROM user_table WHERE username = '?'");
ps.setString(1, pUsername);
rs = ps.execute();
if ( rs.next() ) {
// do the work of making the user record active in some way
}
}
catch (…) {
…
}
-----------------------------------------------------------------
.NET (C#)
-----------------------------------------------------------------
public static bool isUsernameValid(string username) {
RegEx r = new Regex("^[A-Za-z0-9]{16}$");
Return r.isMatch(username);
}
…
try {
string selectString = " SELECT * FROM user_table WHERE username = @userID";
// SqlConnection conn is set and opened elsewhere for brevity.
SqlCommand cmd = new SqlCommand(selectString, conn);
if ( isUsernameValid(pUsername) ) {
cmd.Parameters.Add("@userID", SqlDbType.VarChar, 16).Value = pUsername;
SqlDataReader myReader = cmd.ExecuteReader();
If ( myReader.
// do the work of making the user record active in some way.
myReader.Close();
}
catch (…) {
…
}
-----------------------------------------------------------------
PHP
if ( $_SERVER['HTTP_REFERER'] != 'http://www.example.com/index.php' ) {
throw …
}
Referer Checks
Referer is an optional HTTP header field that normally contains the
previous location (i.e. the
referrer) from which the browser came from. As the attacker can
trivially change it, the referrer
must be treated with caution, as attackers are more likely to use
the correct referrer to bypass
controls in your application than to use invalid or damaging
content.
In general, applications are better off if they do not contain
any referrer code.
How to determine if you are vulnerable
The vulnerability comes in several parts:
- Does your code check the referrer? If so, is it completely
necessary?
- Is the referrer code simple and robust against all forms of
user attack?
- If you use it to construct URLs? Don't as it's nearly
impossible test all valid URLs.
For example, if login.jsp can only be invoked from
http://www.example.com/index.jsp, the
referrer should check that the referrer is this value.
How to protect yourself
For the most part, using the referer field is not desirable as it
so easily modified or spoofed
by attackers. Little to no trust can be assigned to its value, and
it can be hard to sanitize and use
properly.
Programs that display the contents of referrer fields such as
web log analyzers must carefully
protect against XSS and other HTML injection attacks.
If your application has to use the referrer, it should only do
so as a defense in depth
mechanism, and not try to sanitize the field, only reject it if
it's not correct. All code has bugs, so
minimize the amount of code dealing with the referrer field.
For example, if login.jsp can only be invoked from
http://www.example.com/index.jsp, the
referrer could check that the referrer is this value.
Java
HttpServletRequest request = getRequest();
if ( ! request.getHeader("REFERER").equals("http://www.example.com/index.jsp") ) {
throw …
}
.NET (C#)
if ( Request.ServerVariables("HTTP_REFERER") != 'http://www.example.com/default.aspx' ) {
throw …
}
PHP
if ( $_SERVER['HTTP_REFERER'] != 'http://www.example.com/index.php' ) {
throw …
}
But compared to simply checking a session variable against an
authorization matrix, referrers
are a weak authorization or sequencing control.
Browser remembers passwords
Modern browsers offer users the ability to manage their multitude
of credentials by storing
them insecurely on their computer.
How to determine if you are vulnerable
- Clear all state from your browser. Often the most reliable way
to do this is to create a
fresh test account on the test computer and delete and re-create
the account between test
iterations - Use a browser and log on to the application
- If the browser offers to remember any account credentials, your
application is at risk.
- This risk is particularly severe for applications that contain
sensitive or financial information.
How to protect yourself
Modern browsers offer users the ability to manage their multitude
of credentials by storing
them insecurely on their computer.
In the rendered HTTP, send the following in any sensitive input
fields, such as usernames,
passwords, password re-validation, credit card and CCV fields, and
so on:
<form … AUTOCOMPLETE="off"> - for all form fields>
<input … AUTOCOMPLETE="off"> - for just one field>
This indicates to most browsers to not to store that field in
the password management feature.
Remember, it is only a polite suggestion to the browser, and not
every browser supports this tag.
Default accounts
A common vulnerability is default accounts - accounts with well
known usernames and/or
passwords. Particularly bad examples are:
- Microsoft SQL Server until SQL 2000 Service Pack 3 with weak or
non-existent security
for "sa" - Oracle -- a large number of known accounts with passwords
(fixed with later versions of
Oracle)
How to determine if you are vulnerable- Determine if the underlying infrastructure has no default
accounts left active (such as
Administrator, root, sa, ora, dbsnmp, etc.). - Determine if the code contains any default, special, debug or
backdoor credentials.
- Determine if the installer creates any default, special, debug
credentials common to all
installations. - Ensure that all accounts, particularly administrative accounts,
are fully specified by the
installer / user.
There should be no examples or images in the documentation with
usernames in them.
How to protect yourself
- New applications should have no default accounts.
- Ensure the documentation says to determine that the underlying
infrastructure has no
default accounts left active (such as Administrator, root, sa, ora,
dbsnmp, etc.). - Do not allow the code to contain any default, special, or
backdoor credentials.
- When creating the installer, ensure the installer does not
create any default, special,
credentials . - Ensure that all accounts, particularly administrative accounts,
are fully specified by the
installer / user. - There should be no examples or images in the documentation with
usernames in them.
Choice of usernames
If you choose a username scheme that is predictable, it's likely
that attackers can perform a
denial of service against you. For example, banks are particularly
at risk if they use
monotonically increasing customer numbers or credit card numbers to
access their accounts.
How to determine if you are vulnerable
- Bad username forms include:
- Firstname.Lastname
- E-mail address (unless the users are random enough that this is
not a problem … or
you're a webmail provider) - Any monotonically increasing number
- Semi-public data, such as social security number (US only –
also known as SSN), employee number, or similar.
In fact, using the SSN as the username is illegal as you can't
collect this without a suitable
purpose.
How to protect yourself
Where possible, allow users to create their own usernames.
Usernames only have to be
unique.
Usernames should be HTML, SQL and LDAP safe – suggest only
allowing A..Z, a..z, and 0-
9. If you wish to allow spaces, @ symbols or apostrophes, ensure
you properly escape the special
characters (see the Data Validation chapter for more details).
Avoid the use of Firstname.Lastname, e-mail address, credit card
numbers or customer
number, or any semi-public data, such as social security number (US
only – also known as SSN),
employee number, or similar.
Change passwords
Where the user has to remember a portion of the credential, it is
sometimes necessary to
change it, for example if the password is accidentally disclosed to
a third party or the user feels it
is time to change the password.
How to determine if you are vulnerable
To test:
- Change the password.
- Change the password again – if there are minimum periods before
new passwords can be
chosen (often 1 day), it should fail.
How to protect yourself- Ensure your application has a change password function.
- The form must include the old password, the new password and a
confirmation of the
new password - Use AUTOCOMPLETE=off to prevent browsers from caching the
password locally
- If the user gets the old password wrong too many times, lock
the account and kill the
session
For higher risk applications or those with compliance issues, you
should include the ability to
prevent passwords being changed too frequently, which requires a
password history. The
password history should consist only of previous hashes, not clear
text versions of the password.
Allow up to 24 old password hashes.
Short passwords
Passwords can be brute forced, rainbow cracked (pre-computed
dictionary attack), or fall to
simple dictionary attacks. Unfortunately, they are also the primary
method of logging users onto
applications of all risk profiles. The shorter the password, the
higher the success rate of password
cracking tools.
How to determine if you are vulnerable
- Determine if the application allows users no password at all.
This should never be
allowed. - Determine if the application allows users to use dangerously
short passwords (less than
four characters). Applications with a stronger authentication
requirement will not allow
this. Average applications should warn the user that it's weak, but
allow the change
anyway. Poor applications will just change the password. - Change the password to be increasingly longer and longer until
the application warns the
user of excessive password size. A good application will allow
arbitrary password
lengths, and thus will not warn at all.
On each iteration, see if a shorter version of the password works
(often only 8 or 16
characters is needed).
How to protect yourself
- Ensure your application does not allow blank passwords
- Enforce a minimum password length. For higher risk
applications, prevent the user from
using (a configurable) too short password length. For low risk
apps, a warning to the user
is acceptable for passwords less than six characters in
length. - Encourage users to use long pass phrases (like "My milk shake
brings all the boys to the
yard" or "Let me not to the marriage of true minds Admit
impediments") by not strictly
enforcing complexity controls for passwords over 14 characters in
length - Ensure your application allows arbitrarily long pass phrases by
using a decent one-way
hash algorithm, such as AES-128 in digest mode or SHA-256
bit.
Weak password controls
ISO 17799 and many security policies require that users use and
select reasonable passwords,
and change them to a certain frequency. Most web applications are
simply non-compliant with
these security policies. If your application is likely to be used
within enterprise settings or
requires compliance with ISO 17799 or similar standards, it must
implement basic authentication
controls. This does not mean that they need to be turned on by
default, but they should exist.
How to determine if you are vulnerable
Determine if the application
- Allows blank passwords.
- Allows dictionary words as passwords. This dictionary should be
the local dictionary, and
not just English. - Allows previous passwords to be chosen. Applications with
stronger authentication or
compliance needs should retain a hashed password history to prevent
password re-use.
How to protect yourself- Allow for languages other than English (possibly allowing more
than one language at a
time for bi-lingual or multi-lingual locales like Belgium or
Switzerland) - The application should have the following controls (but
optionally enforce):
- Password minimum length (but never maximum length)
- Password change frequency
- Password minimum password age (to prevent users cycling through
the password history)
- Password complexity requirements
- Password history
- Password lockout duration and policy (ie no lockout, lockout
for X minutes, lockout
permanently)
For higher risk applications, use a weak password dictionary helper
to decide if the user's
choice for password is too weak.
Note: Complex frequently changed passwords are
counterproductive to security. It is better to
have a long-lived strong passphrase than a 10 character jumble
changed every 30 days. The 30
days will ensure that PostIt™ notes exist all over the organization
with passwords written down.
Reversible password encryption
Passwords are secrets. There is no reason to decrypt them under any
circumstances. Help
desk staff should be able to set new passwords (with an audit
trail, obviously), not read back old
passwords. Therefore, there is no reason to store passwords in a
reversible form.
The usual mechanism is to use a cryptographic digest algorithm,
such as MD5 or SHA1.
However, some forms have recently shown to be weak, so it is
incumbent to move to stronger
algorithms unless you have a large collection of old hashes.
How to determine if you are vulnerable
For custom code using forms-based authentication, examine the
algorithm used by the
authentication mechanism. The algorithm should be using AES-128 in
digest mode, SHA1 in
256 bit mode, with a salt.
- Older algorithms such as MD5 and SHA1 (with 160 bit hash
output) have been shown to
be potentially weak, and should no longer be used. - No algorithm (ie you see a clear text password) is insecure and
should not be used.
- Algorithms, such as DES, 3DES, Blowfish, or AES in cipher mode,
which allow the
passwords to be decrypted should be frowned upon.
How to protect yourself
If you don't understand the cryptography behind password
encryption, you are probably
going to get it wrong. Please try to re-use trusted password
implementations.
- Use AES-128 in digest mode or SHA1 in 256 bit mode
- Use a non-static salting mechanism.
- Never send the password hash or password back to the user in
any form.
Automated password resets
Automated password reset mechanisms are common where organizations
believe that they
need to avoid high help desk support costs from authentication.
From a risk management
perspective, password reset functionality seems acceptable in many
circumstances. However,
password reset functionality equates to a secondary, but much
weaker password mechanism.
From a forthcoming study (see references), it appears that password
reset systems with five
responses are the equivalent to two character passwords and require
reversible or clear text
passwords to be stored in the back end system, which is contrary to
security best practices and
most information security policies.
In general, questions required by password reset systems are
easily found from public records
(mother's maiden name, car color, etc). In many instances, the
password reset asks for data that
is illegal or highly problematic to collect, such as social
security numbers. In most privacy
regimes, you may only collect information directly useful to your
application's needs, and
disclose to the user why you are collecting that information.
In general, unless the data being protected by your
authentication mechanism is practically
worthless, you should not use password reset mechanisms.
How to determine if you are vulnerable
Password reset mechanisms vary in complexity, but are often easily
abused.
- If password reset uses hints, check the hints for publicly
known or semi-public
information such as date of birth, SSN, mother's name, etc. It
should not use these as they
can be found out from other sources and from social
engineering. - There should no further clues in the underlying HTML.
- If password reset uses the e-mail address as the key to
unlocking the account, the
resulting e-mail should not contain a password itself, but a
one-time validation token
valid only for a short period of time (say 15 minutes). If the
token is good for a long
period of time, check to see if the token is predictable or easy to
generate. - If the e-mail contains a clickable link, determine if the link
can be used for phishing.
How to protect yourself- High value transaction systems should not use password reset
systems. It is discouraged
for all other applications. - Consider cheaper and more secure systems, such as pre-sending
the user a password reset
token in a sealed envelope which is replenished upon use. - If the questions and answers are used to identify the user to
the help desk, simply
generate a random number in the "How to call the help desk" page on
your web site and
verify this number when the user calls in. - Be careful when implementing automated password resets. The
easiest to get right is
"e-mail the user" as it creates an audit trail and contains only
one secret – the user's
e-mail address. However, this is risky if the user's e-mail
account has been
compromised. - Send a message to the user explaining that someone has
triggered the password reset
functionality. Ask them if they didn't ask for the reset to report
the incident. If they did
trigger it, provide a short cryptographically unique time limited
token ready for cut and
paste. Do not provide a hyperlink as this is against phishing best
practices and will make
scamming users easier over time. This value should then be entered
into the application
which is waiting for the token. Check that the token has not
expired and it is valid for that
user account. Ask the user to change their password right there. If
they are successful,
send a follow up e-mail to the user and to the admin. Log
everything.
If you have to choose the hint based alternative, use free-form
hints, with non-public
knowledge suggestions, like "What is your favorite color?" "What is
your favorite memory," etc.
Do not use mother's maiden name, SSN, or similar. The user should
enter five hints during
registration, and be presented with three when they reset the
password.
Obviously, both password reset mechanisms should be over SSL to
provide integrity and
privacy.
Brute Force
A common attack is to attempt to log on to a well-known privileged
account name or
otherwise guessed account and attempt brute-force or dictionary
attacks against the password.
Users are notorious at choosing really bad passwords (like
"password"), and so this approach
works surprisingly well.
Applications should be robust in the face of determined
automated brute force and dictionary
attack, such as from Brutus or custom scripts. Determined brute
force attacks cannot easily be
defeated, only delayed.
How to determine if you are vulnerable
To test the application:
- Use a brute force application, such as Brutus or a custom Perl
script. This attack only
works with tools. - Use multiple dictionaries, not just English
- Use "common password" dictionaries. You'd be surprised how
often "root", "password",
"", and so on are used - Does the error message tell you about what went wrong with the
authentication?
- Are the logs for failed authentication attempts tied to a brute
force mechanism? Does it
lock your IP or session out? - Can you restart the brute force by dropping the session with
n-1 attempts left? Example:
If you get your session destroyed at 5 attempts, does using 4 then
starting a new session work?
If the application allows more than five attempts from a single IP
address, or a collection rate
in excess of 10 requests a second, it's likely that the application
will fall to determined brute
force attack.
How to protect yourself
Check the application:
- Has a delay between the user submitting the credential and a
success or failure is
reported. A delay of three seconds can make automated brute force
attacks almost
infeasible. A progressive delay (3 seconds then 15 then 30 then
disconnect) can make
casual brute force attacks completely ineffective warns the user
with a suitable error
message that does not disclose which part of the application
credentials are incorrect by
using a common authentication error page:
- logs failed authentication attempts (in fact, a good
application logs all authentication
attempts) - for applications requiring stronger controls, blocking access
from abusive IP addresses (ie
accessing more than three accounts from the same IP address, or
attempting to lock out
more than one account) - destroys the session after too many retries.
In such a scenario, log analysis might reveal multiple accesses to
the same page from the
same IP address within a short period of time. Event correlation
software such as Simple Event
Correlator (SEC) can be used to define rules to parse through the
logs and generate alerts based
on aggregated events. This could also be done by adding a Snort
rule for alerting on HTTP
Authorization Failed error messages going out from your web server
to the user, and SEC can
then be used to aggregate and correlate these alerts.
Remember Me
On public computers, "Remember Me?" functionality, where a user can
simply return to their
personalized account can be dangerous. For example, in Internet
Cafes, you can often find sites
previous users have logged on to, and post as them, or order goods
as them (for example with
eBay).
How to determine if you are vulnerable
- Does the application possess "remember me" functionality?
- If so, how long does it last? If permanently, how long does the
cookie last before expiry?
- Does it use a predictable cookie value? If so, can this be used
to bypass authentication
altogether?
How to protect yourself- If your application deals with high value transactions, it
should not have "Remember Me"
functionality. - If the risk is minimal, it is enough to warn users of the
dangers before allowing them to
tick the box. - Never use a predictable "pre-authenticated" token. The token
should be kept on record to
ensure that the authentication mechanism is not
bypassable.
Idle Timeouts
Applications that expose private data or that may cause identity
theft if left open should not
be accessible after a certain period of time.
How to determine if you are vulnerable
- Log on to the application
- Does the application have a keep alive or "log me on
automatically" function? If so, the
likelihood is high that the application will fail this test. - Wait 20 minutes
- Try to use the application again.
- If the application allows the use, the application is at
risk.
How to protect yourself- Determine a suitable time out period with the business
- Configure the time out in the session handler to abandon or
close the session after the
time out has expired.
Logout
All applications should have a method of logging out of the
application. This is particularly
vital for applications that contain private data or could be used
for identity theft.
How to determine if you are vulnerable
- Does the application contain a logout button or link somewhere
within it?
- Does every view contain a logout button or link?
- When you use logout, can you re-use the session (ie copy and
paste a URL from two or
three clicks ago, and try to re-use it)? - (High risk applications) When logout is used, does the
application warn you to clear the
browser's cache and history?
How to protect yourself- Implement logout functionality.
- Include a log out link or button in every view and not just in
the index page.
- Ensure that logout abandons or closes out the session, and
clears any cookies left on
the browser. - (High risk applications) Include text to warn the user to clear
their browser's cache and
history if they are on a shared PC.
Account Expiry
Users who have to sign up for your service may wish to discontinue
their association with
you, or for the most part, many users simply never return to
complete another transaction.
How to determine if you are vulnerable
- Does the application have a mechanism to terminate the
account?
- Does this remove all the user's records (modulo records
required to provide adequate
transaction history for taxation and accounting purposes?) - If the records are partially scrubbed, do they eliminate all
non-essential records?
How to protect yourself- Users should have the ability to remove their account. This
process should require
confirmation, but otherwise should not overly make it difficult to
the user to remove their
records. - Accounts that have not logged in for a long period of time
should be locked out, or
preferably removed. - If you retain records, you are required by most privacy regimes
to detail what you keep
and why to the user in your privacy statement.
When partially scrubbing accounts (ie you need to maintain a
transaction history or
accounting history), ensure all personally identifiable information
is not available or reachable
from the front end web application, i.e. export to an external
database of archived users or
CSV format.
Self registration
Self-registration schemes sound like a great idea until you realize
that they allow anonymous
users to access otherwise protected resources. Any application
implementing self-registration
should include steps to protect itself from being abused.
How to determine if you are vulnerable
- Does the self-registration feature allow full access to all
features without human
intervention? - If there are limits, are they enforced if you know about them?
Many applications simply
don't let you see a particular URL, but does that URL work when
cut-n-paste from a
more privileged account? - Can the process for maximizing the account's capabilities be
forced or socially
engineered?
How to protect yourself- Implement self-registration carefully based upon the risk to
your business. For example,
you may wish to put monetary or transaction limits on new
accounts. - If limits are imposed, they should be validated by business
rules, and not just by security
through obscurity. - Ensure the process to maximize the features of an account is
simple and transparent.
- When accounts are modified, ensure that a reasonable trace or
audit of activity is
maintained.
CAPTCHA
CAPTCHA ("completely automated public Turing test to tell computers
and humans apart"
… really!) systems supposedly allow web designers to block out
non-humans from registering
with web sites.
The usual reason for implementing a CAPTCHA is to prevent
spammers from registering
and polluting the application with spam and pornographic links.
This is a particularly bad
problem with blog and forum software, but any application is at
risk if search engines can index
content.
How to determine if you are vulnerable
The primary method of breaking CAPTCHA's is to grab the image and
to use humans to
crack them. This occurs with "free day passes" to adult web sites.
A person who wants to look at
free images is presented with the captured CAPTCHA and more often
than not, they will type
the letters in for a small reward. This completely defeats the
CAPTCHA mechanism.
Visual or audible CAPTCHA mechanisms by their nature are not
accessible to blind (or deaf)
users, and as a consequence of trying to defeat clever optical
character recognition software,
often locks out color blind users (which can be as high as 10 % of
the male population).
Note: Any web site that is mandated or legally required
to be accessible must not use
CAPTCHA's.
How to protect yourself
Do not use CAPTCHA tags. They are illegal if you are required to be
accessible to all users
(often the case for government sites, health, banking, and
nationally protected infrastructure,
particularly if there is no other method of interacting with that
organization).
If you have to:
- Always provide a method by which a user may sign up or register
for your web site
offline or via another method - Deter the use of automated sign ups by using the "no follow"
tag. Search engines will
ignore hyperlinks and pages with this tag set, immensely devaluing
the use of link
spamming - Limit the privileges of newly signed up accounts or similar
until a positive validation has
occurred. This can be as simple as including a unique reference ID
to a registered credit
card, or requiring a certain amount of time before certain features
are unlocked, such as
public posting rights or unfettered access to all
features.
Further Reading- "Body Check", c't Magazine. Very amusing article from
2002
http://www.heise.de/ct/english/02/11/114/ - Klein, A., NTLM Authentication and HTTP proxies don't mix,
posting to webappsec
http://packetstormsecurity.nl/papers/general/NTLMhttp.txt - How much does it take before your signature is verified?
Apparently three plasma screens:
http://www.zug.com/pranks/credit_card/ - Schneier, B., The failure of two factor authentication, blog /
essay
http://www.schneier.com/blog/archives/2005/03/the_failure_of.html - Group blog led by Kim Cameron, The Laws of Identity
http://www.identityblog.com/stories/2004/12/09/thelaws.html - van der Stock, A., "On the entropy of password reset systems",
unpublished research
paper. If you'd like participate in the survey portion of this
research, please contact
vanderaj@owasp.org