Difference between revisions of "LII:Web Application Security Guide/Checklist"
From LIMSWiki
Jump to navigationJump to searchShawndouglas (talk | contribs) m (→Special files: Missing link) |
Shawndouglas (talk | contribs) (Updated.) |
||
(One intermediate revision by the same user not shown) | |||
Line 1: | Line 1: | ||
{{TOC right}} | {{TOC right}} | ||
==Miscellaneous points== | ==Miscellaneous points== | ||
* Do '''not''' rely on | * Do '''not''' rely on web application firewalls (WAFs) for security (however, consider using them to improve security). | ||
* If external libraries (e.g. for database access, XML parsing) are used, always use current versions | * If external libraries (e.g. for database access, XML parsing) are used, always use current versions. | ||
* If you need random numbers, obtain them from a secure/cryptographic random number generator | * If you need random numbers, obtain them from a secure/cryptographic random number generator. | ||
* For every action or retrieval of data, always check access rights | * For every action or retrieval of data, always check access rights. | ||
* Do '''not''', under any circumstances, attempt to implement cryptographic algorithms yourself. Use high-level libraries for cryptography. | * Do '''not''', under any circumstances, attempt to implement cryptographic algorithms yourself. Use high-level libraries for cryptography. | ||
* Ensure debug output and error messages do not leak sensitive information | * Ensure debug output and error messages do not leak sensitive information. | ||
* Mark problematic debug output in your code (e.g. <code>//TODO DEBUG REMOVE</code>) even if you intend to remove it after just one test | * Mark problematic debug output in your code (e.g. <code>//TODO DEBUG REMOVE</code>) even if you intend to remove it after just one test. | ||
* Do not use “<code>eval()</code>” and similar functions | * Do not use “<code>eval()</code>” and similar functions. | ||
** Avoid “<code>system()</code>” and similar functions if possible | ** Avoid “<code>system()</code>” and similar functions if possible. | ||
* Ensure database servers are not directly reachable from the outside | * Ensure database servers are not directly reachable from the outside. | ||
* Consider to block old browsers from using your application | * Consider to block old browsers from using your application. | ||
==File inclusion and disclosure== | ==File inclusion and disclosure== | ||
Line 21: | Line 21: | ||
==File upload vulnerabilities== | ==File upload vulnerabilities== | ||
* Avoid unnecessary file uploads | * Avoid unnecessary file uploads. | ||
* Ensure that files uploaded by the user cannot be interpreted as script files by the web server, e.g. by checking the file extension (or whatever means your web server uses to identify script files) | * Ensure that files uploaded by the user cannot be interpreted as script files by the web server, e.g. by checking the file extension (or whatever means your web server uses to identify script files). | ||
* Ensure that files cannot be uploaded to unintended directories (directory traversal) | * Ensure that files cannot be uploaded to unintended directories (directory traversal). | ||
* Try to disable script execution in the upload directory | * Try to disable script execution in the upload directory. | ||
* Ensure that the file extension matches the actual type of the file content | * Ensure that the file extension matches the actual type of the file content. | ||
* If only images are to be uploaded, consider re-compressing them using a secure library to ensure they are valid | * If only images are to be uploaded, consider re-compressing them using a secure library to ensure they are valid. | ||
* Ensure that uploaded files are specified with the correct Content-type when delivered to the user | * Ensure that uploaded files are specified with the correct Content-type when delivered to the user. | ||
* Prevent users from uploading problematic file types like HTML, CSS, JavaScript, XML, SVG and executables using a whitelist of allowed file types | * Prevent users from uploading problematic file types like HTML, CSS, JavaScript, XML, SVG and executables using a whitelist of allowed file types. | ||
* Prevent users from uploading special files (e.g. .htaccess, web.config, robots.txt, crossdomain.xml, clientaccesspolicy.xml) | * Prevent users from uploading special files (e.g. .htaccess, web.config, robots.txt, crossdomain.xml, clientaccesspolicy.xml). | ||
* Prevent users from overwriting application files | * Prevent users from overwriting application files. | ||
* Consider delivering uploaded files with the “Content-disposition: attachment” header | * Consider delivering uploaded files with the “Content-disposition: attachment” header. | ||
==SQL injection== | ==SQL injection== | ||
* | * Use prepared statements to access the database ''– or –''. | ||
* | * Use stored procedures, accessed using appropriate language/library methods or prepared statements. | ||
* Always ensure the DB login used by the application has only the rights that are needed | * Always ensure the DB login used by the application has only the rights that are needed. | ||
==Cross-site scripting (XSS)== | ==Cross-site scripting (XSS)== | ||
* Escape anything that is not a constant before including it in a response as close to the output as possible (i.e. right in the line containing the “echo” or “print” call) | * Escape anything that is not a constant before including it in a response as close to the output as possible (i.e. right in the line containing the “echo” or “print” call). | ||
* If not possible (e.g. when building a larger HTML block), escape when building and indicate the fact that the variable content is pre-escaped and the expected context in the name | * If not possible (e.g. when building a larger HTML block), escape when building and indicate the fact that the variable content is pre-escaped and the expected context in the name. | ||
* Consider the context when escaping: Escaping text inside HTML is different from escaping HTML attribute values, and very different from escaping values inside CSS or JavaScript, or inside HTTP headers. | * Consider the context when escaping: Escaping text inside HTML is different from escaping HTML attribute values, and very different from escaping values inside CSS or JavaScript, or inside HTTP headers. | ||
** This may mean that you need to escape for multiple contexts and/or multiple times. For example, when passing a HTML fragment as a JS constant for later includsion in the document, you need to escape for JS string inside HTML when writing the constant to the JavaScript source, then escape again for HTML when your script writes the fragment to the document. (See rationale for examples) | ** This may mean that you need to escape for multiple contexts and/or multiple times. For example, when passing a HTML fragment as a JS constant for later includsion in the document, you need to escape for JS string inside HTML when writing the constant to the JavaScript source, then escape again for HTML when your script writes the fragment to the document. (See rationale for examples.) | ||
** The attacker must not be able to put anything where it is not supposed to be, even if you think it is not exploitable (e.g. because attempts to exploit it result in broken JavaScript). | ** The attacker must not be able to put anything where it is not supposed to be, even if you think it is not exploitable (e.g. because attempts to exploit it result in broken JavaScript). | ||
* Explicitly set the correct character set at the beginning of the document (i.e. as early as possible) and/or in the header. | * Explicitly set the correct character set at the beginning of the document (i.e. as early as possible) and/or in the header. | ||
* Ensure that URLs provided by the user start with an allowed scheme (whitelisting) to avoid dangerous schemes (e.g. javascript:-URLs ) | * Ensure that URLs provided by the user start with an allowed scheme (whitelisting) to avoid dangerous schemes (e.g. javascript:-URLs). | ||
* | * Don’t forget URLs in redirector scripts. | ||
* A [http://www.html5rocks.com/en/tutorials/security/content-security-policy/ | * A [http://www.html5rocks.com/en/tutorials/security/content-security-policy/ content security policy] may be used as an additional security measure, but is not sufficient by itself to prevent attacks. | ||
==XML and internal data escaping== | ==XML and internal data escaping== | ||
Line 57: | Line 57: | ||
==XML, JSON and general API security== | ==XML, JSON and general API security== | ||
* Ensure proper access control to the API | * Ensure proper access control to the API. | ||
* Do not forget that you need to [[Web Application Security Guide/Cross- | * Do not forget that you need to [[LII:Web Application Security Guide/Cross-site scripting (XSS)|correctly escape all output to prevent XSS attacks]], that data formats like XML require [[LII:Web Application Security Guide/XML and internal data escaping|special consideration]], and that protection against [[LII:Web Application Security Guide/Cross-site request forgery (CSRF)|cross-site request forgery (CSRF)]] is needed in many cases. | ||
* Use standard data formats like JSON with proven libraries, and use them correctly. This will probably take care of all your escaping needs. | * Use standard data formats like JSON with proven libraries, and use them correctly. This will probably take care of all your escaping needs. | ||
* Make sure browsers do not misinterpret your document or allow cross-site loading | * Make sure browsers do not misinterpret your document or allow cross-site loading. | ||
** Ensure your document is well-formed | ** Ensure your document is well-formed. | ||
** Send the correct content type | ** Send the correct content type. | ||
** Use the | ** Use the <code><nowiki>X-Content-Type-Options: nosniff</nowiki></code> header. | ||
** For XML, provide a charset and ensure attackers cannot insert arbitrary tags | ** For XML, provide a charset and ensure attackers cannot insert arbitrary tags. | ||
** For JSON, ensure the top-level data structure is an object and all characters with special meaning in HTML are escaped | ** For JSON, ensure the top-level data structure is an object and all characters with special meaning in HTML are escaped. | ||
==(Un)trusted input== | ==(Un)trusted input== | ||
* Thoroughly filter/escape any untrusted content | * Thoroughly filter/escape any untrusted content. | ||
* If the allowed character set for certain input fields is limited, check that the input is valid before using it | * If the allowed character set for certain input fields is limited, check that the input is valid before using it. | ||
* If in doubt about a certain kind of data (e.g. server variable), treat it as untrusted | * If in doubt about a certain kind of data (e.g. server variable), treat it as untrusted. | ||
* If you are sure, but there is no '''real''' need to treat it as trusted, treat it as untrusted | * If you are sure, but there is no '''real''' need to treat it as trusted, treat it as untrusted. | ||
* The request URL (e.g. in environment variables) is untrusted | * The request URL (e.g. in environment variables) is untrusted. | ||
* Data coming from HTTP headers is untrusted | * Data coming from HTTP headers is untrusted. | ||
** Referer | ** Referer | ||
** X-Forwarded-For | ** X-Forwarded-For | ||
** Cookies | ** Cookies | ||
** Server name (!) | ** Server name (!) | ||
* All POST and GET data is untrusted | * All POST and GET data is untrusted. | ||
** | ** Includes non-user-modifiable input fields like select | ||
* All content validation is to be done server side | * All content validation is to be done server side. | ||
==Cross-site request forgery (CSRF)== | ==Cross-site request forgery (CSRF)== | ||
* Include a hidden form field with a random token bound to the user’s session (and preferably the action to be performed), and check this token in the response | * Include a hidden form field with a random token bound to the user’s session (and preferably the action to be performed), and check this token in the response. | ||
* Make sure the token is non-predictable and cannot be obtained by the attacker | * Make sure the token is non-predictable and cannot be obtained by the attacker. | ||
** | ** Do not include it in files the attacker could load into his site using <code><nowiki><script></nowiki></code> tags. | ||
* Referer checks are not secure, but can be used as an additional measure | * Referer checks are not secure, but can be used as an additional measure. | ||
==Clickjacking== | ==Clickjacking== | ||
* Prevent (i)framing of your application in current browsers by including the HTTP response header “<tt>X-Frame-Options: deny</tt>” | * Prevent (i)framing of your application in current browsers by including the HTTP response header “<tt>X-Frame-Options: deny</tt>”. | ||
* Prevent (i)framing in outdated browsers by including a JavaScript frame breaker which checks for (i)framing and refuses to show the page if it is detected | * Prevent (i)framing in outdated browsers by including a JavaScript frame breaker which checks for (i)framing and refuses to show the page if it is detected. | ||
* For applications with high security requirements where you expect users to use outdated browsers with JavaScript disabled, consider requiring users of older browsers to enable JavaScript | * For applications with high security requirements where you expect users to use outdated browsers with JavaScript disabled, consider requiring users of older browsers to enable JavaScript. | ||
==Insecure data transfer== | ==Insecure data transfer== | ||
* Use SSL/TLS (https) for any and all data transfer | * Use SSL/TLS (https) for any and all data transfer. | ||
* Do '''not''' start communicating via http, only redirecting to https when “needed” | * Do '''not''' start communicating via http, only redirecting to https when “needed”. | ||
* Mark cookies with the “secure” attribute | * Mark cookies with the “secure” attribute. | ||
* Use the Strict-Transport-Security header where possible | * Use the Strict-Transport-Security header where possible. | ||
* Educate users to visit the <tt>https://</tt> URL directly | * Educate users to visit the <tt>https://</tt> URL directly. | ||
* If your web application performs HTTPS requests, make sure it verifies the certificate and host name | * If your web application performs HTTPS requests, make sure it verifies the certificate and host name. | ||
** Consider limiting trusted CAs if connecting to internal servers | ** Consider limiting trusted CAs if connecting to internal servers. | ||
==Session fixation== | ==Session fixation== | ||
* Regenerate (change) the session ID as soon as the user logs in (destroying the old session) | * Regenerate (change) the session ID as soon as the user logs in (destroying the old session). | ||
* Prevent the attacker from making the user use his session by accepting session IDs only from cookies, not from GET or POST parameters (PHP: php.ini setting “<tt>session.use_only_cookies</tt>”) | * Prevent the attacker from making the user use his session by accepting session IDs only from cookies, not from GET or POST parameters (PHP: php.ini setting “<tt>session.use_only_cookies</tt>”). | ||
==Session stealing== | ==Session stealing== | ||
* Set the “HttpOnly” attribute for session cookies | * Set the “HttpOnly” attribute for session cookies. | ||
* Generate random session IDs with secure randomness and sufficient length | * Generate random session IDs with secure randomness and sufficient length. | ||
* Do not leak session IDs | * Do not leak session IDs. | ||
==Truncation attacks, trimming attacks== | ==Truncation attacks, trimming attacks== | ||
* Avoid truncating input. Treat overlong input as an error instead. | * Avoid truncating input. Treat overlong input as an error instead. | ||
* If truncation is necessary, ensure to check the value after truncation and use only the truncated value | * If truncation is necessary, ensure to check the value after truncation and use only the truncated value. | ||
* Make sure trimming does not occur or checks are done consistently | * Make sure trimming does not occur or checks are done consistently. | ||
* Introduce length checks | * Introduce length checks. | ||
** | ** Care about different lengths due to encoding. | ||
* Make sure SQL treats truncated queries as errors by setting an appropriate <tt>SQL MODE</tt> | * Make sure SQL treats truncated queries as errors by setting an appropriate <tt>SQL MODE</tt>. | ||
==Password security== | ==Password security== | ||
* Do not store plain-text passwords | * Do not store plain-text passwords; store only hashes. | ||
* Use scrypt, bcrypt, or some other hashing algorithm specifically designed for secure password "storage".<ref name="NielsenStoring12">{{cite web |url=https://patrickmn.com/security/storing-passwords-securely/ |title=Storing Passwords Securely |author=Nielsen, P.M. |work=Patrick on |date=06 June 2012 |accessdate=10 August 2016}}</ref><ref name="CryptWB">{{cite web |url=https://en.wikibooks.org/wiki/Cryptography/Secure_Passwords |title=Cryptography/Secure Passwords |work=Cryptography |publisher=WikiBooks |date=23 September 2015 |accessdate=10 August 2016}}</ref> | * Use scrypt, bcrypt, or some other hashing algorithm specifically designed for secure password "storage".<ref name="NielsenStoring12">{{cite web |url=https://patrickmn.com/security/storing-passwords-securely/ |title=Storing Passwords Securely |author=Nielsen, P.M. |work=Patrick on |date=06 June 2012 |accessdate=10 August 2016}}</ref><ref name="CryptWB">{{cite web |url=https://en.wikibooks.org/wiki/Cryptography/Secure_Passwords |title=Cryptography/Secure Passwords |work=Cryptography |publisher=WikiBooks |date=23 September 2015 |accessdate=10 August 2016}}</ref> | ||
* Use a secure hashing algorithm (e.g. [[wikipedia:SHA-256|SHA-256]] as of 2011) | * Use a secure hashing algorithm (e.g. [[wikipedia:SHA-256|SHA-256]] as of 2011). | ||
* Use per-user salts | * Use per-user salts. | ||
* Use strengthening (i.e. multi-iteration hashing to slow down brute force attempts) | * Use strengthening (i.e. multi-iteration hashing to slow down brute force attempts). | ||
* Limit login attempts per IP (not per user account) | * Limit login attempts per IP (not per user account). | ||
* Enforce reasonable, but not too strict, password policies | * Enforce reasonable, but not too strict, password policies. | ||
* If a password reset process is implemented, make sure it has adequate security. Questions like “mother’s maiden name” can often be guessed by attackers and are not sufficient. | * If a password reset process is implemented, make sure it has adequate security. Questions like “mother’s maiden name” can often be guessed by attackers and are not sufficient. | ||
==Comparison issues== | ==Comparison issues== | ||
* Know comparison types in your programming language and use the correct one | * Know comparison types in your programming language and use the correct one. | ||
* When in doubt (especially with PHP), use a strict comparison (PHP: "<code><nowiki>===</nowiki></code>") | * When in doubt (especially with PHP), use a strict comparison (PHP: "<code><nowiki>===</nowiki></code>"). | ||
* When comparing strings for equality, make sure you actually check that the strings are equal and not that one string contains the other | * When comparing strings for equality, make sure you actually check that the strings are equal and not that one string contains the other. | ||
==PHP-specific issues== | ==PHP-specific issues== | ||
* Do not use the short form “<code><nowiki><?</nowiki></code>”, always use the full form “<code><nowiki><?php</nowiki></code>” | * Do not use the short form “<code><nowiki><?</nowiki></code>”, always use the full form “<code><nowiki><?php</nowiki></code>”. | ||
* When using the nginx web server, make sure to correctly follow the '''official''' installation instructions and pay attention to the [http://wiki.nginx.org/Pitfalls#Passing_Uncontrolled_Requests_to_PHP "Pitfalls" page]. Beware of tutorials that often contain working but insecure configuration examples. | * When using the nginx web server, make sure to correctly follow the '''official''' installation instructions and pay attention to the [http://wiki.nginx.org/Pitfalls#Passing_Uncontrolled_Requests_to_PHP "Pitfalls" page]. Beware of tutorials that often contain working but insecure configuration examples. | ||
* <code><nowiki>preg_replace</nowiki></code> can act as <code><nowiki>eval()</nowiki></code> in certain cases. Avoid passing user input to it. If you must, correctly filter and escape it. | * <code><nowiki>preg_replace</nowiki></code> can act as <code><nowiki>eval()</nowiki></code> in certain cases. Avoid passing user input to it. If you must, correctly filter and escape it. | ||
* Use the [http://www.hardened-php.net/suhosin/ Suhosin] (including the patch, if possible) and configure it with strict rules | * Use the [http://www.hardened-php.net/suhosin/ Suhosin] (including the patch, if possible) and configure it with strict rules. | ||
** Enable <code><nowiki>suhosin.executor.disable_emodifier</nowiki></code> | ** Enable <code><nowiki>suhosin.executor.disable_emodifier</nowiki></code>. | ||
** Enable <code><nowiki>suhosin.executor.disable_eval</nowiki></code> if possible | ** Enable <code><nowiki>suhosin.executor.disable_eval</nowiki></code> if possible. | ||
** Set <code><nowiki>suhosin.mail.protect</nowiki></code> to 2 if possible | ** Set <code><nowiki>suhosin.mail.protect</nowiki></code> to 2 if possible. | ||
* When updating PHP to PHP 5.4 from an older version, ensure legacy applications do not rely on magic quotes for security. | * When updating PHP to PHP 5.4 from an older version, ensure legacy applications do not rely on magic quotes for security. | ||
==Prefetching and spiders== | ==Prefetching and spiders== | ||
* Use POST requests instead of GETs for anything that triggers an action | * Use POST requests instead of GETs for anything that triggers an action. | ||
==Special files== | ==Special files== | ||
* Know the meaning of these files | * Know the meaning of these files. | ||
* Ensure robots.txt does not disclose "secret" paths | * Ensure robots.txt does not disclose "secret" paths. | ||
* Ensure crossdomain.xml and clientaccesspolicy.xml do not exist unless needed | * Ensure crossdomain.xml and clientaccesspolicy.xml do not exist unless needed. | ||
* If used, ensure crossdomain.xml and clientaccesspolicy.xml allow access from trusted domains only | * If used, ensure crossdomain.xml and clientaccesspolicy.xml allow access from trusted domains only. | ||
* Prevent users from uploading/changing special files (see [[LII:Web Application Security Guide/File upload vulnerabilities|file upload vulnerabilities section]]) | * Prevent users from uploading/changing special files (see [[LII:Web Application Security Guide/File upload vulnerabilities|file upload vulnerabilities section]]). | ||
==SSL, TLS and HTTPS basics== | ==SSL, TLS and HTTPS basics== | ||
* '''Follow [https://www.ssllabs.com/projects/best-practices/ SSLLabs best practices]''' including: | * '''Follow [https://www.ssllabs.com/projects/best-practices/ SSLLabs best practices]''' including: | ||
** Ensure SSLv2 is disabled | ** Ensure SSLv2 is disabled. | ||
** Generate private keys for certificates yourself, do not let your CA do it | ** Generate private keys for certificates yourself, do not let your CA do it. | ||
** Use an appropriate key length (usually 2048 bit in 2013) | ** Use an appropriate key length (usually 2048 bit in 2013). | ||
** If possible, disable client-initiated renegotiation | ** If possible, disable client-initiated renegotiation. | ||
** Consider | ** Consider manually limiting/setting cipher suites. | ||
==References== | ==References== |
Latest revision as of 22:06, 10 August 2016
Miscellaneous points
- Do not rely on web application firewalls (WAFs) for security (however, consider using them to improve security).
- If external libraries (e.g. for database access, XML parsing) are used, always use current versions.
- If you need random numbers, obtain them from a secure/cryptographic random number generator.
- For every action or retrieval of data, always check access rights.
- Do not, under any circumstances, attempt to implement cryptographic algorithms yourself. Use high-level libraries for cryptography.
- Ensure debug output and error messages do not leak sensitive information.
- Mark problematic debug output in your code (e.g.
//TODO DEBUG REMOVE
) even if you intend to remove it after just one test. - Do not use “
eval()
” and similar functions.- Avoid “
system()
” and similar functions if possible.
- Avoid “
- Ensure database servers are not directly reachable from the outside.
- Consider to block old browsers from using your application.
File inclusion and disclosure
- Do not take file names for inclusions from user input, only from trusted lists or constants.
- If user input is to be used, validate it against a whitelist. Checking if the file exists or if the input matches a certain format is not sufficient.
- Avoid having scripts read and pass through files if possible.
- If you read and deliver files using user-supplied file names, thoroughly validate the file names to avoid directory traversal and similar attacks and ensure the user is allowed to read the file.
- Ensure the application runs with no more privileges than required.
File upload vulnerabilities
- Avoid unnecessary file uploads.
- Ensure that files uploaded by the user cannot be interpreted as script files by the web server, e.g. by checking the file extension (or whatever means your web server uses to identify script files).
- Ensure that files cannot be uploaded to unintended directories (directory traversal).
- Try to disable script execution in the upload directory.
- Ensure that the file extension matches the actual type of the file content.
- If only images are to be uploaded, consider re-compressing them using a secure library to ensure they are valid.
- Ensure that uploaded files are specified with the correct Content-type when delivered to the user.
- Prevent users from uploading problematic file types like HTML, CSS, JavaScript, XML, SVG and executables using a whitelist of allowed file types.
- Prevent users from uploading special files (e.g. .htaccess, web.config, robots.txt, crossdomain.xml, clientaccesspolicy.xml).
- Prevent users from overwriting application files.
- Consider delivering uploaded files with the “Content-disposition: attachment” header.
SQL injection
- Use prepared statements to access the database – or –.
- Use stored procedures, accessed using appropriate language/library methods or prepared statements.
- Always ensure the DB login used by the application has only the rights that are needed.
Cross-site scripting (XSS)
- Escape anything that is not a constant before including it in a response as close to the output as possible (i.e. right in the line containing the “echo” or “print” call).
- If not possible (e.g. when building a larger HTML block), escape when building and indicate the fact that the variable content is pre-escaped and the expected context in the name.
- Consider the context when escaping: Escaping text inside HTML is different from escaping HTML attribute values, and very different from escaping values inside CSS or JavaScript, or inside HTTP headers.
- This may mean that you need to escape for multiple contexts and/or multiple times. For example, when passing a HTML fragment as a JS constant for later includsion in the document, you need to escape for JS string inside HTML when writing the constant to the JavaScript source, then escape again for HTML when your script writes the fragment to the document. (See rationale for examples.)
- The attacker must not be able to put anything where it is not supposed to be, even if you think it is not exploitable (e.g. because attempts to exploit it result in broken JavaScript).
- Explicitly set the correct character set at the beginning of the document (i.e. as early as possible) and/or in the header.
- Ensure that URLs provided by the user start with an allowed scheme (whitelisting) to avoid dangerous schemes (e.g. javascript:-URLs).
- Don’t forget URLs in redirector scripts.
- A content security policy may be used as an additional security measure, but is not sufficient by itself to prevent attacks.
XML and internal data escaping
- Avoid XML if possible.
- For XML, use well-tested, high-quality libraries, and pay close attention to the documentation. Know your library – some libraries have functions that allow you to bypass escaping without knowing it.
- If you parse (read) XML, ensure your parser does not attempt to load external references (e.g. entities and DTDs).
- For other internal representations of data, make sure correct escaping or filtering is applied. Try to use well-tested, high-quality libraries if available, even if it seems to be more difficult.
- If escaping is done manually, ensure that it handles null bytes, unexpected charsets, invalid UTF-8 characters etc. in a secure manner.
XML, JSON and general API security
- Ensure proper access control to the API.
- Do not forget that you need to correctly escape all output to prevent XSS attacks, that data formats like XML require special consideration, and that protection against cross-site request forgery (CSRF) is needed in many cases.
- Use standard data formats like JSON with proven libraries, and use them correctly. This will probably take care of all your escaping needs.
- Make sure browsers do not misinterpret your document or allow cross-site loading.
- Ensure your document is well-formed.
- Send the correct content type.
- Use the
X-Content-Type-Options: nosniff
header. - For XML, provide a charset and ensure attackers cannot insert arbitrary tags.
- For JSON, ensure the top-level data structure is an object and all characters with special meaning in HTML are escaped.
(Un)trusted input
- Thoroughly filter/escape any untrusted content.
- If the allowed character set for certain input fields is limited, check that the input is valid before using it.
- If in doubt about a certain kind of data (e.g. server variable), treat it as untrusted.
- If you are sure, but there is no real need to treat it as trusted, treat it as untrusted.
- The request URL (e.g. in environment variables) is untrusted.
- Data coming from HTTP headers is untrusted.
- Referer
- X-Forwarded-For
- Cookies
- Server name (!)
- All POST and GET data is untrusted.
- Includes non-user-modifiable input fields like select
- All content validation is to be done server side.
Cross-site request forgery (CSRF)
- Include a hidden form field with a random token bound to the user’s session (and preferably the action to be performed), and check this token in the response.
- Make sure the token is non-predictable and cannot be obtained by the attacker.
- Do not include it in files the attacker could load into his site using
<script>
tags.
- Do not include it in files the attacker could load into his site using
- Referer checks are not secure, but can be used as an additional measure.
Clickjacking
- Prevent (i)framing of your application in current browsers by including the HTTP response header “X-Frame-Options: deny”.
- Prevent (i)framing in outdated browsers by including a JavaScript frame breaker which checks for (i)framing and refuses to show the page if it is detected.
- For applications with high security requirements where you expect users to use outdated browsers with JavaScript disabled, consider requiring users of older browsers to enable JavaScript.
Insecure data transfer
- Use SSL/TLS (https) for any and all data transfer.
- Do not start communicating via http, only redirecting to https when “needed”.
- Mark cookies with the “secure” attribute.
- Use the Strict-Transport-Security header where possible.
- Educate users to visit the https:// URL directly.
- If your web application performs HTTPS requests, make sure it verifies the certificate and host name.
- Consider limiting trusted CAs if connecting to internal servers.
Session fixation
- Regenerate (change) the session ID as soon as the user logs in (destroying the old session).
- Prevent the attacker from making the user use his session by accepting session IDs only from cookies, not from GET or POST parameters (PHP: php.ini setting “session.use_only_cookies”).
Session stealing
- Set the “HttpOnly” attribute for session cookies.
- Generate random session IDs with secure randomness and sufficient length.
- Do not leak session IDs.
Truncation attacks, trimming attacks
- Avoid truncating input. Treat overlong input as an error instead.
- If truncation is necessary, ensure to check the value after truncation and use only the truncated value.
- Make sure trimming does not occur or checks are done consistently.
- Introduce length checks.
- Care about different lengths due to encoding.
- Make sure SQL treats truncated queries as errors by setting an appropriate SQL MODE.
Password security
- Do not store plain-text passwords; store only hashes.
- Use scrypt, bcrypt, or some other hashing algorithm specifically designed for secure password "storage".[1][2]
- Use a secure hashing algorithm (e.g. SHA-256 as of 2011).
- Use per-user salts.
- Use strengthening (i.e. multi-iteration hashing to slow down brute force attempts).
- Limit login attempts per IP (not per user account).
- Enforce reasonable, but not too strict, password policies.
- If a password reset process is implemented, make sure it has adequate security. Questions like “mother’s maiden name” can often be guessed by attackers and are not sufficient.
Comparison issues
- Know comparison types in your programming language and use the correct one.
- When in doubt (especially with PHP), use a strict comparison (PHP: "
===
"). - When comparing strings for equality, make sure you actually check that the strings are equal and not that one string contains the other.
PHP-specific issues
- Do not use the short form “
<?
”, always use the full form “<?php
”. - When using the nginx web server, make sure to correctly follow the official installation instructions and pay attention to the "Pitfalls" page. Beware of tutorials that often contain working but insecure configuration examples.
preg_replace
can act aseval()
in certain cases. Avoid passing user input to it. If you must, correctly filter and escape it.- Use the Suhosin (including the patch, if possible) and configure it with strict rules.
- Enable
suhosin.executor.disable_emodifier
. - Enable
suhosin.executor.disable_eval
if possible. - Set
suhosin.mail.protect
to 2 if possible.
- Enable
- When updating PHP to PHP 5.4 from an older version, ensure legacy applications do not rely on magic quotes for security.
Prefetching and spiders
- Use POST requests instead of GETs for anything that triggers an action.
Special files
- Know the meaning of these files.
- Ensure robots.txt does not disclose "secret" paths.
- Ensure crossdomain.xml and clientaccesspolicy.xml do not exist unless needed.
- If used, ensure crossdomain.xml and clientaccesspolicy.xml allow access from trusted domains only.
- Prevent users from uploading/changing special files (see file upload vulnerabilities section).
SSL, TLS and HTTPS basics
- Follow SSLLabs best practices including:
- Ensure SSLv2 is disabled.
- Generate private keys for certificates yourself, do not let your CA do it.
- Use an appropriate key length (usually 2048 bit in 2013).
- If possible, disable client-initiated renegotiation.
- Consider manually limiting/setting cipher suites.
References
- ↑ Nielsen, P.M. (6 June 2012). "Storing Passwords Securely". Patrick on. https://patrickmn.com/security/storing-passwords-securely/. Retrieved 10 August 2016.
- ↑ "Cryptography/Secure Passwords". Cryptography. WikiBooks. 23 September 2015. https://en.wikibooks.org/wiki/Cryptography/Secure_Passwords. Retrieved 10 August 2016.
Notes
The original source for this page is the associated Wikibooks article and is shared here under the CC BY-SA 3.0 license.