Confirmed users
81
edits
m (→Uploads) |
|||
| (25 intermediate revisions by 4 users not shown) | |||
| Line 41: | Line 41: | ||
===Password Rotation=== | ===Password Rotation=== | ||
Password rotations have proven to be a little tricky and this should only be used if there is lack of monitoring | Password rotations have proven to be a little tricky and this should only be used if there is lack of monitoring within the applications and there is a mitigating reason to use rotations. Reasons being short password, or lack of password controls. | ||
* Privileged accounts - Password for privileged accounts should be rotated every: 90 to 120 days. | * Privileged accounts - Password for privileged accounts should be rotated every: 90 to 120 days. | ||
* General User Account - It is also recommended to implement password rotations for general users if possible. | * General User Account - It is also recommended to implement password rotations for general users if possible. | ||
| Line 66: | Line 66: | ||
We do not want to provide any information that would allow an attacker to determine if an entered username/email address is valid or invalid. Otherwise an attacker could enumerate valid accounts for phishing attacks or brute force attack. | We do not want to provide any information that would allow an attacker to determine if an entered username/email address is valid or invalid. Otherwise an attacker could enumerate valid accounts for phishing attacks or brute force attack. | ||
=== Email Change and Verification Functions === | |||
Email verification links should not provide the user with an authenticated session. | |||
Email verification codes must expire after the first use or expire after 8 hours if not used. | |||
===Password Storage=== | ===Password Storage=== | ||
Separate from the password policy, we should have the following standards when it comes to storing passwords | Separate from the password policy, we should have the following standards when it comes to storing passwords: | ||
* Passwords stored in a database should using the hmac+bcrypt function. | * Passwords stored in a database should using the hmac+bcrypt function. | ||
The purpose of hmac and bcrypt storage is as follows: | |||
* bcrypt provides a hashing mechanism which can be configured to consume sufficient time to prevent brute forcing of hash values even with many computers | |||
* bcrypt can be easily adjusted at any time to increase the amount of work and thus provide protection against more powerful systems | |||
* The nonce for the hmac value is designed to be stored on the file system and not in the databases storing the password hashes. In the event of a compromise of hash values due to SQL injection, the nonce will still be an unknown value since it would not be compromised from the file system. This significantly increases the complexity of brute forcing the compromised hashes considering both bcrypt and a large unknown nonce value | |||
* The hmac operation is simply used as a secondary defense in the event there is a design weakness with bcrypt that could leak information about the password or aid an attacker | |||
A sample of this code is here: https://github.com/fwenzel/django-sha2 | A sample of this code is here: https://github.com/fwenzel/django-sha2 | ||
Keep in mind that while bcrypt is secure you should still enforce good passwords. | |||
As slow as an algorithm may be if a password is "123" it still would only take a | |||
short amount of time before somebody figures it out. | |||
==== Old Password Hashes ==== | ==== Old Password Hashes ==== | ||
* Password hashes older than a year should be deleted from the system. | * Password hashes older than a year should be deleted from the system. | ||
* After a password hash migration, old hashes should be removed within 3 months if user has yet to | * After a password hash migration, old hashes should be removed within 3 months if user has yet to log in for the conversion process. | ||
====Migration==== | ====Migration==== | ||
The following process can be used to migrate an application that is using a different hashing algorithm than the standard hash listed above. The benefits of this approach is that it instantly upgrades all hashes to the strong, recommended hashing algorithm and it does not require | |||
The following process can be used to migrate an application that is using a different hashing algorithm than the standard hash listed above. The benefits of this approach is that it instantly upgrades all hashes to the strong, recommended hashing algorithm and it does not require users to reset their passwords. | |||
'''Migration Process'''<br> | '''Migration Process'''<br> | ||
| Line 113: | Line 130: | ||
The session tokens should be handled by the web server if possible or generated via a cryptographically secure random number generator. | The session tokens should be handled by the web server if possible or generated via a cryptographically secure random number generator. | ||
===Inactivity Time Out=== | ===Inactivity Time Out=== | ||
Authenticated sessions should timeout after determined period of inactivity - 15 minutes is recommended | Authenticated sessions should timeout after determined period of inactivity - 15 minutes is recommended. | ||
===Secure Flag=== | ===Secure Flag=== | ||
The "Secure" flag should be set during every set-cookie. This will instruct the browser to never send the cookie over HTTP. The purpose of this flag is to prevent the accidental exposure of a cookie value if a user follows an HTTP link. | The "Secure" flag should be set during every set-cookie. This will instruct the browser to never send the cookie over HTTP. The purpose of this flag is to prevent the accidental exposure of a cookie value if a user follows an HTTP link. | ||
| Line 121: | Line 139: | ||
===HTTP-Only Flag=== | ===HTTP-Only Flag=== | ||
The "HTTP-Only" flag should be set to disable malicious script access to the session ID (e.g. XSS) | The "HTTP-Only" flag should be set to disable malicious script access to the session ID (e.g. XSS) | ||
===Login=== | |||
New session IDs should be created on login (to prevent session fixation via XSS on sibling domains or subdomains). | |||
===Logout=== | ===Logout=== | ||
Upon logout the session ID should be invalidated on the server side and deleted on the client via expiration/overwriting the value. | Upon logout the session ID should be invalidated on the server side and deleted on the client via expiration/overwriting the value. | ||
| Line 156: | Line 178: | ||
'''Examples of Good Input Validation Approaches''' | '''Examples of Good Input Validation Approaches''' | ||
For each field define the types of acceptable characters and an acceptable number of characters for the input | For each field define the types of acceptable characters and an acceptable number of characters for the input | ||
* Username: Letters, numbers, 3 to 10 characters | * Username: Letters, numbers, certain special characters, 3 to 10 characters | ||
* Firstname: Letters, single apostrophe, 1 to 30 characters | * Firstname: Letters, single apostrophe, dash, 1 to 30 characters | ||
* Simple Zipcode: Numbers, 5 characters | * Simple US Zipcode: Numbers, 5 characters | ||
Note: These are just examples to illustrate the idea of whitelist input validation. You'll need to adjust based on the type of input you expect. | |||
===JavaScript vs Server Side Validation=== | ===JavaScript vs Server Side Validation=== | ||
| Line 208: | Line 232: | ||
* Ensure that a robust escaping routine is in place to prevent the user from adding additional characters that can be executed by the OS ( e.g. user appends | to the malicious data and then executes another OS command). Remember to use a positive approach when constructing escaping routinges. [http://code.google.com/p/owasp-esapi-java/source/browse/trunk/src/main/java/org/owasp/esapi/codecs/UnixCodec.java Example] | * Ensure that a robust escaping routine is in place to prevent the user from adding additional characters that can be executed by the OS ( e.g. user appends | to the malicious data and then executes another OS command). Remember to use a positive approach when constructing escaping routinges. [http://code.google.com/p/owasp-esapi-java/source/browse/trunk/src/main/java/org/owasp/esapi/codecs/UnixCodec.java Example] | ||
Further Reading: [http://www.owasp.org/index. | Further Reading: [http://www.owasp.org/index.php/Reviewing_Code_for_OS_Injection Reviewing Code for OS Injection] | ||
===Preventing XML Injection=== | ===Preventing XML Injection=== | ||
| Line 224: | Line 248: | ||
* Characteristics of a CSRF Token | * Characteristics of a CSRF Token | ||
** Unique per user & per user session | ** Unique per user & per user session | ||
** Tied to a single user session | |||
** Large random value | ** Large random value | ||
** Generated by a cryptographically secure random number generator | ** Generated by a cryptographically secure random number generator | ||
| Line 273: | Line 298: | ||
==Content Security Policy (CSP)== | ==Content Security Policy (CSP)== | ||
Develop sites without inline JavaScript so adoption of CSP is easier | |||
https://developer.mozilla.org/en/Introducing_Content_Security_Policy | |||
==Logging== | ==Logging== | ||
| Line 282: | Line 310: | ||
1. Controls are in place to prevent brute force attacks<br> | 1. Controls are in place to prevent brute force attacks<br> | ||
Options (any of these are fine): | Options (any of these are fine): | ||
* Admin page behind ssl vpn (most popular option) | |||
* Account Lockout | * Account Lockout | ||
* CAPTCHA's after 5 failed logins | * CAPTCHA's after 5 failed logins | ||
| Line 292: | Line 321: | ||
4. The session id uses the HTTPOnly flag | 4. The session id uses the HTTPOnly flag | ||
[https://wiki.mozilla.org/WebAppSec/Secure_Coding_Details#Word_Press Configuring | [https://wiki.mozilla.org/WebAppSec/Secure_Coding_Details#Word_Press Configuring Wordpress Admin Pages Securely] | ||
== Uploads == | == Uploads == | ||
| Line 339: | Line 368: | ||
== Error Handling == | == Error Handling == | ||
'''Attacks of Concern''': Sensitive Information Disclosure, System Information Disclosure, Aiding exploitation of other vulnerabilities | |||
= | === User Facing Error Messages=== | ||
Error messages displayed to the user should not contain system, diagnostic or debug information. | |||
=== Debug Mode=== | |||
Debug mode is supported by many applications and frameworks and is acceptable for Mozilla applications. However, debug mode should only be enabled in stage. | |||
=== Formatting Error Messages=== | |||
Error messages are often logged to text files or files viewed within a web browser. | |||
* text based log files: Ensure any newline characters (%0A%0C) are appropriately handled to prevent log forging | |||
* web based log files: Ensure any logged html characters are appropriately encoded to prevent XSS when viewing logs | |||
=== Recommended Error Handling Design === | |||
* Log necessary error data to a system log file | |||
* Display a generic error message to the user | |||
* If necessary provide an error code to the user which maps to the error data in the logfile. A user reporting an error can provide this code to help diagnose the issue | |||
[http://www.djangobook.com/en/2.0/chapter20/ Django Security] | =Further Reading= | ||
* [http://www.owasp.org/index.php/File:OWASP_T10_-_2010_rc1.pdf OWASP Top 10] | |||
* [https://www.owasp.org/index.php/Cheat_Sheets OWASP Cheat Sheets] | |||
* [https://www.owasp.org/index.php/Category:OWASP_Guide_Project OWASP Guide Project] | |||
* [http://phpsec.org/library/ Php Sec Library] | |||
* [http://www.djangobook.com/en/2.0/chapter20/ Django Security] | |||
* [http://guides.rubyonrails.org/security.html Ruby Security] | |||
= Contributors = | = Contributors = | ||
Michael Coates - mcoates [at] mozilla.com<br> | Michael Coates - mcoates [at] mozilla.com<br> | ||
Chris Lyon - clyon [at] mozilla.com | Chris Lyon - clyon [at] mozilla.com<br> | ||
Mark Goodwin - mgoodwin [at] mozilla.com | |||