This site is the archived OWASP Foundation Wiki and is no longer accepting Account Requests.
To view the new OWASP Foundation website, please visit https://owasp.org
Difference between revisions of "ESAPI Secure Coding Guideline"
(4 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
+ | Here is a typical list of web application security requirements that shows how you can use ESAPI to implement them. All the requirements that are handled automatically by ESAPI have been left out. | ||
+ | |||
+ | |||
=Using Security Controls= | =Using Security Controls= | ||
Line 9: | Line 12: | ||
|- | |- | ||
| align="center" | '''AU001''' | | align="center" | '''AU001''' | ||
− | | The application shall use <code></code> to | + | | All site interaction from page containing the login form to the page confirming logout (inclusive) must use SSL. |
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU002''' | ||
+ | | All requests for pages that require authentication shall call the <code>ESAPI.authenticator().login()</code> method. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU003''' | ||
+ | | The application shall provide the user with a logout link on every page that invokes the <code>ESAPI.authenticator().logout()</code> method. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU004''' | ||
+ | | Form fields used for passwords must use <code>type=password</code> to mask the password from view. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU005''' | ||
+ | | The application shall never put passwords into HTML, including repopulating form fields. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU006''' | ||
+ | | The application shall use the <code>FIXME</code> to set a "remember me" cookie for automatic authentication, but only if a user specifically authorizes it. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU007''' | ||
+ | | The application shall include Javascript in all pages that protects against being nested or framed in other websites. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU008''' | ||
+ | | The application shall reauthenticate users with <code>User.checkPassword()</code> before allowing access to sensitive transactions. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU009''' | ||
+ | | Link and form URLs for all transactions shall be updated with the <code>HTTPUtilities.addCSRFToken()</code> method to add a CSRF token. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU010''' | ||
+ | | All HTTP requests for transactions shall be verified using the <code>HTTPUtilities.verifyCSRFToken()</code> method to check that the request is not forged. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU011''' | ||
+ | | Account creation and registration functions should protect against automated tools. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU012''' | ||
+ | | The application shall generate strong passwords for users with the <code>Authenticator.generateStrongPassword()</code> method. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU013''' | ||
+ | | The application shall verify the strength of any user provided password with the <code>Authenticator.verifyPasswordStrength()</code> method. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU014''' | ||
+ | | The application shall verify the strength of any user account name with the <code>Authenticator.verifyAccountNameStrength()</code> method. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AU015''' | ||
+ | | The application shall display information upon login about the last successful (<code>User.getLastLoginTime()</code>) and last failed (<code>User.getLastFailedLoginTime()</code>) login date and time. | ||
| TBD | | TBD | ||
|} | |} | ||
+ | |||
Line 23: | Line 83: | ||
|- | |- | ||
| align="center" | '''AC001''' | | align="center" | '''AC001''' | ||
− | | The | + | | Only the container provided JSESSIONID should be used as a session identifier. |
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | Every page should contain an obvious link to the logout function. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | The JSESSIONID and any other session identifiers must never be disclosed in links, html content, log files or any other storage. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | The JSESSIONID and any other session identifiers must never be used as an identifier for any other purpose. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | URL rewriting must never be enabled. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | Call <code>ESAPI.authentiator().logoff()</code> to end the user's session. | ||
| TBD | | TBD | ||
|} | |} | ||
Line 91: | Line 171: | ||
− | ==Input Validation | + | ==Input Validation== |
{|class="wikitable" style="text-align:left;" width="100%" | {|class="wikitable" style="text-align:left;" width="100%" | ||
|- | |- | ||
Line 99: | Line 179: | ||
|- | |- | ||
| align="center" | '''AC001''' | | align="center" | '''AC001''' | ||
− | | The application shall use <code></code> to | + | | The application shall avoid the use of hidden fields. |
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | The application shall avoid the use of custom cookies or other HTTP headers. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | The application shall add all custom cookies with <code>ESAPI.httpUtilities().safeAddCookie()</code> or <code>ESAPI.httpUtilities().safeSetCookie()</code> to ensure they are properly secured. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | The application shall perform validation at the boundary of all major application components. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | All input must be validated against a strict whitelist pattern using the Validator.* methods before used. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | The application shall process all requests containing file uploads with HTTPUtilities.safeFileUpload() to safely extract uploaded files from a multipart HTTP request. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | If custom headers must be used, the HttpUtilities.safeAddHeader() and .safeSetHeader() must be used to prevent header injection. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | All requests must be validated with the HTTPUtilities.validateHTTPRequest() method to ensure global whitelist character set validation on all incoming HTTP requests. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | Ensure that all input is validated on the server, even if it has already been validated on the client. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | All redirects must use HTTPUtilities.safeSendRedirect() to check redirect target against an allowable set or pattern for valid destinations. | ||
| TBD | | TBD | ||
|} | |} | ||
Line 105: | Line 221: | ||
+ | |||
+ | ==Encoding== | ||
+ | {|class="wikitable" style="text-align:left;" width="100%" | ||
+ | |- | ||
+ | ! ID | ||
+ | ! width="45%" | Requirement | ||
+ | ! width="45%" | Code Example | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | All data sent to interpreters or external systems must be encoded with the appropriate Encoder.encodeFor*() method to prevent injection. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | The application shall use <code></code> to | ||
+ | | TBD | ||
+ | |} | ||
Line 113: | Line 245: | ||
! width="45%" | Requirement | ! width="45%" | Requirement | ||
! width="45%" | Code Example | ! width="45%" | Code Example | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | Requests containing sensitive data should use the POST method. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | Pages containing sensitive data should call the [HTTPUtilities.setCachingHeaders()] method to set appropriate caching headers. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | Use the [Encryptor.encrypt()] method to encrypt and the [Encryptor.decrypt()] method to decrypt all sensitive information before storing. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | Use the [Encryptor.hash()] method to generate message digests for integrity purposes. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | Data that expires after an elapsed time should be generated with the [Encryptor.seal()] method and verified with the [Encryptor.verifySeal()] method. | ||
+ | | TBD | ||
+ | |- | ||
+ | | align="center" | '''AC001''' | ||
+ | | The application shall use <code></code> to | ||
+ | | TBD | ||
|- | |- | ||
| align="center" | '''AC001''' | | align="center" | '''AC001''' | ||
Line 120: | Line 276: | ||
+ | | Forms containing sensitive data should include the "autocomplete=off" attribute on the FORM tag as well as individual form elements. | ||
| The application shall use an EncryptedProperties to store all security relevant data, such as passwords, credentials, codes, configuration information, addresses, etc… | | The application shall use an EncryptedProperties to store all security relevant data, such as passwords, credentials, codes, configuration information, addresses, etc… | ||
Line 379: | Line 536: | ||
− | [[Category:OWASP | + | [[Category:OWASP Enterprise Security API]] |
Latest revision as of 20:10, 4 May 2008
Here is a typical list of web application security requirements that shows how you can use ESAPI to implement them. All the requirements that are handled automatically by ESAPI have been left out.
Using Security Controls
Authentication
ID | Requirement | Code Example |
---|---|---|
AU001 | All site interaction from page containing the login form to the page confirming logout (inclusive) must use SSL. | TBD |
AU002 | All requests for pages that require authentication shall call the ESAPI.authenticator().login() method.
|
TBD |
AU003 | The application shall provide the user with a logout link on every page that invokes the ESAPI.authenticator().logout() method.
|
TBD |
AU004 | Form fields used for passwords must use type=password to mask the password from view.
|
TBD |
AU005 | The application shall never put passwords into HTML, including repopulating form fields. | TBD |
AU006 | The application shall use the FIXME to set a "remember me" cookie for automatic authentication, but only if a user specifically authorizes it.
|
TBD |
AU007 | The application shall include Javascript in all pages that protects against being nested or framed in other websites. | TBD |
AU008 | The application shall reauthenticate users with User.checkPassword() before allowing access to sensitive transactions.
|
TBD |
AU009 | Link and form URLs for all transactions shall be updated with the HTTPUtilities.addCSRFToken() method to add a CSRF token.
|
TBD |
AU010 | All HTTP requests for transactions shall be verified using the HTTPUtilities.verifyCSRFToken() method to check that the request is not forged.
|
TBD |
AU011 | Account creation and registration functions should protect against automated tools. | TBD |
AU012 | The application shall generate strong passwords for users with the Authenticator.generateStrongPassword() method.
|
TBD |
AU013 | The application shall verify the strength of any user provided password with the Authenticator.verifyPasswordStrength() method.
|
TBD |
AU014 | The application shall verify the strength of any user account name with the Authenticator.verifyAccountNameStrength() method.
|
TBD |
AU015 | The application shall display information upon login about the last successful (User.getLastLoginTime() ) and last failed (User.getLastFailedLoginTime() ) login date and time.
|
TBD |
Session Management
ID | Requirement | Code Example |
---|---|---|
AC001 | Only the container provided JSESSIONID should be used as a session identifier. | TBD |
AC001 | Every page should contain an obvious link to the logout function. | TBD |
AC001 | The JSESSIONID and any other session identifiers must never be disclosed in links, html content, log files or any other storage. | TBD |
AC001 | The JSESSIONID and any other session identifiers must never be used as an identifier for any other purpose. | TBD |
AC001 | URL rewriting must never be enabled. | TBD |
AC001 | Call ESAPI.authentiator().logoff() to end the user's session.
|
TBD |
Access Control
ID | Requirement | Code Example |
---|---|---|
AC001 | The application shall use assertAuthorizedForURL() to verify authorization before allowing access to each URL.
|
TBD |
AC002 | The application shall use assertAuthorizedForFunction() to verify authorization before allowing access to each business function.
|
TBD |
AC003 | The application shall use assertAuthorizedForFile() to verify authorization before allowing access to files.
|
TBD |
AC004 | The application shall use assertAuthorizedForData() to verify authorization before allowing access to data.
|
TBD |
AC005 | The application shall use assertAuthorizedForService() to verify authorization before allowing access to each backend service.
|
TBD |
AC006 | The application shall use isAuthorizedFor* methods to verify authorization before including user interface controls in HTML output.
|
TBD |
AC007 | The application shall use AccessReferenceMap.getIndirectReference() to reference all application objects such as filenames, directory paths, and database keys.
|
TBD |
AC008 | The application shall prevent access to all resources that should not be directly accessed by users (such as resources, XML files, JSP files, properties) by storing them in a protected directory, such as WEB-INF .
|
TBD |
AC009 | The application shall use HTTPUtilities.sendSafeForward() for all forwards, to ensure that they cannot be used to bypass access checks.
|
TBD |
AC0010 | The appplication must use only trusted data used in access control decisions. | TBD |
AC0011 | Administrative functions for the application shall be deployed as a separate application with increased authentication controls. | TBD |
Input Validation
ID | Requirement | Code Example |
---|---|---|
AC001 | The application shall avoid the use of hidden fields. | TBD |
AC001 | The application shall avoid the use of custom cookies or other HTTP headers. | TBD |
AC001 | The application shall add all custom cookies with ESAPI.httpUtilities().safeAddCookie() or ESAPI.httpUtilities().safeSetCookie() to ensure they are properly secured.
|
TBD |
AC001 | The application shall perform validation at the boundary of all major application components. | TBD |
AC001 | All input must be validated against a strict whitelist pattern using the Validator.* methods before used. | TBD |
AC001 | The application shall process all requests containing file uploads with HTTPUtilities.safeFileUpload() to safely extract uploaded files from a multipart HTTP request. | TBD |
AC001 | If custom headers must be used, the HttpUtilities.safeAddHeader() and .safeSetHeader() must be used to prevent header injection. | TBD |
AC001 | All requests must be validated with the HTTPUtilities.validateHTTPRequest() method to ensure global whitelist character set validation on all incoming HTTP requests. | TBD |
AC001 | Ensure that all input is validated on the server, even if it has already been validated on the client. | TBD |
AC001 | All redirects must use HTTPUtilities.safeSendRedirect() to check redirect target against an allowable set or pattern for valid destinations. | TBD |
Encoding
ID | Requirement | Code Example |
---|---|---|
AC001 | All data sent to interpreters or external systems must be encoded with the appropriate Encoder.encodeFor*() method to prevent injection. | TBD |
AC001 | The application shall use to
|
TBD |
Data Protection
ID | Requirement | Code Example |
---|---|---|
AC001 | Requests containing sensitive data should use the POST method. | TBD |
AC001 | Pages containing sensitive data should call the [HTTPUtilities.setCachingHeaders()] method to set appropriate caching headers. | TBD |
AC001 | Use the [Encryptor.encrypt()] method to encrypt and the [Encryptor.decrypt()] method to decrypt all sensitive information before storing. | TBD |
AC001 | Use the [Encryptor.hash()] method to generate message digests for integrity purposes. | TBD |
AC001 | Data that expires after an elapsed time should be generated with the [Encryptor.seal()] method and verified with the [Encryptor.verifySeal()] method. | TBD |
AC001 | The application shall use to
|
TBD |
AC001 | The application shall use to
|
TBD |
| Forms containing sensitive data should include the "autocomplete=off" attribute on the FORM tag as well as individual form elements.
| The application shall use an EncryptedProperties to store all security relevant data, such as passwords, credentials, codes, configuration information, addresses, etc…
Using Services Securely
ID | Requirement | Code Example |
---|---|---|
AC001 | The application shall use to
|
TBD |
Error Handling
ID | Requirement | Code Example |
---|---|---|
AC001 | The application shall use to
|
TBD |
Logging and Intrusion Detection
ID | Requirement | Code Example |
---|---|---|
AC001 | The application shall use to
|
TBD |
Secure Configuration and Deployment
ID | Requirement | Code Example |
---|---|---|
SC001 | Production code shall not contain code not intended for use, such as debug, test, and dead code. | TBD |
SC002 | The application's source code shall not contain secrets that would compromise security if disclosed. | TBD |
SC003 | The application team shall run code quality tools such as FindBugs and PMD to find quality problems. | TBD |
Avoiding Specific Risks
Cross Site Scripting
ID | Requirement | Code Example |
---|---|---|
AC001 | The application shall use to
|
TBD |
Cross Site Request Forgery
ID | Requirement | Code Example |
---|---|---|
AC001 | The application shall use to
|
TBD |
Thread Safety Problems
ID | Requirement | Code Example |
---|---|---|
AC001 | The application shall avoid the use of shared storage, such as class variables, instance variables, or singletons, in all multithreaded code. | TBD |
Denial of Service
ID | Requirement | Code Example |
---|---|---|
AC001 | The application shall use to
|
TBD |
Banned APIs
The following calls are dangerous and should be replaces with the safer calls provided by ESAPI.
ID | Banned Call | ESAPI Replacement | Code Example |
---|---|---|---|
BAN001 | System.out.println() | Logger.* | TBD |
BAN002 | Throwable.printStackTrace() | Logger.* | TBD |
BAN003 | Runtime.exec() | Executor.safeExec() | TBD |
BAN004 | Session.getId() | Randomizer.getRandomString (better not to use at all) | TBD |
BAN005 | ServletRequest.getUserPrincipal() | Authenticator.getCurrentUser() | TBD |
BAN006 | ServletRequest.isUserInRole() | AccessController.isAuthorized*() | TBD |
BAN007 | Session.invalidate() | Authenticator.logout() | TBD |
BAN008 | Math.Random.* | Randomizer.* | TBD |
BAN009 | File.createTempFile() | Randomizer.getRandomFilename() | TBD |
BAN010 | ServletResponse.setContentType() | HTTPUtilities.setContentType() | TBD |
BAN011 | ServletResponse.sendRedirect() | HTTPUtilities.safeSendRedirect() | TBD |
BAN012 | RequestDispatcher.forward() | HTTPUtilities.safeSendForward() | TBD |
BAN013 | ServletResponse.addHeader() | HTTPUtilities.safeSetHeader()/safeSetHeader() | TBD |
BAN014 | ServletResponse.addCookie() | HTTPUtilities.safeAddCookie() | TBD |
BAN015 | ServletRequest.isSecure() | HTTPUtilties.isSecureChannel() | TBD |
BAN016 | Properties.* | EncryptedProperties.* | TBD |
BAN017 | ServletContext.log() | Logger.* | TBD |
BAN018 | java.security and javax.crypto | Encryptor.* | TBD |
BAN019 | java.net.URLEncoder/Decoder | Encoder.encodeForURL()/decodeForURL() | TBD |
BAN020 | java.sql.Statement.execute | PreparedStatement.execute | TBD |
BAN021 | ServletResponse.encodeURL | HTTPUtilities.safeEncodeURL() (better not to use at all) | TBD |
BAN022 | ServletResponse.encodeRedirectURL | HTTPUtilities.safeEncodeRedirectURL() (better not to use at all) | TBD |