A. All forms should have "autocomplete=false".
B. Every request should go through a controller except for the static content
C. Block GET in all web applications irrespective of whether it takes a parameter or not
D. Every request sent to a container must be secure. If there are any data that need to be served w/o authentication check, then serve them from a different webapplication/container.
E. Any file retrieval API should look only in the specific folders.
F. Do not use SOP in the code, especially never put e.PrintStakTrace();
G. Run Fortify Static code analysis
H. Think abut buying a penetration testing tool - https://www.acunetix.com/vulnerability-scanner/
I. Use an open source penetration testing tool - https://ironwasp.org
J. Never put an incoming data in an target URL
K. Never send back sensitive data to an URL that is coming as part of the query string without validating it against a whitelist.
L. All pages/responses except the file downloads from IE must contain the following headers.
Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0
M. Add the following headers in every response.
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains X-Frame-Options: DENY
XSS
C. Untrusted data should only be treated as displayable text. Never treat untrusted data as code or markup within JavaScript code.
D. Always JavaScript encode and delimit untrusted data as quoted strings when entering the application. Ex: var x = “<%=encodedJavaScriptData%>”;
E. Do not use element.setAttribute(“…”,”value”) for adding behavior with untrusted data. For example, you should not do element.setAttribute("onClick","<request.getParameter("myInput")>").
F. If you use any of the below methods, then use Encoder.encodeForJS for all attributes passed to these methods.
element.innerHTML = “…”;
element.outerHTML = “…”;
document.write(…);
document.writeln(…);
G. Don’t eval() JSON to convert it to native JavaScript objects. Instead use JSON.toJSON() and JSON.parse() (Chris Schmidt).
H. Anything that you write back - data from DB, paramenter from URL, cookies, user agent - if it is within an executable context (i.e., within the HTML markup), then encode them with appropriate encoder.
I. Never use an input value as a CSS class / style value
XSS - ESAPI Encoders:
RULE #0 - Never Insert Untrusted Data. Always use an encoder
RULE #1 - HTML Escape Before Inserting Untrusted Data into HTML Element Content
Sample: <div>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</div>
Mitigation: String safe = ESAPI.encoder().encodeForHTML( request.getParameter( "input" ) );
RULE #2 - Attribute Escape Before Inserting Untrusted Data into HTML Common Attributes
Sample: <div attr=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...>content</div>
Mitigation: String safe = ESAPI.encoder().encodeForHTMLAttribute( request.getParameter( "input" ) );
RULE #3 - JavaScript Escape Before Inserting Untrusted Data into JavaScript Data Values
Sample:
<script>x='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'</script> one side of a quoted expression
<div onmouseover="x='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'"</div> inside quoted event handler
window.setInterval('...EVEN IF YOU ESCAPE UNTRUSTED DATA YOU ARE XSSED HERE...');
Mitigation: String safe = ESAPI.encoder().encodeForJavaScript( request.getParameter( "input" ) );
RULE #4: HTML escape JSON values in an HTML context and read the data with JSON.parse
// external js file
var dataElement = document.getElementById('init_data');
// unescape the content of the span
var jsonText = dataElement.textContent || dataElement.innerText
var initData = JSON.parse(html_unescape(jsonText));
RULE #5 - URL Escape Before Inserting Untrusted Data into HTML URL Parameter Values
Sample: <a href="http://www.somesite.com?test=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...">link</a >
Mitigation: String safe = ESAPI.encoder().encodeForURL( request.getParameter( "input" ) );
WARNING: Do not encode complete or relative URL's with URL encoding! If untrusted input is meant to be placed into href, src or other URL-based attributes, it should be validated to make sure it does not point to an unexpected protocol, especially
Javascript links.
String userURL = request.getParameter( "userURL" )
boolean isValidURL = ESAPI.validator().isValidInput("URLContext", userURL, "URL", 255, false);
if (isValidURL) {
<a href="<%=encoder.encodeForHTMLAttribute(userURL)%>">link</a>
}
RULE #6 - Sanitize HTML Markup with a Library Designed for the Job - JSoup or HTML Sanitizer
OWASP Java HTML Sanitizer - https://www.owasp.org/index.php/OWASP_Java_HTML_Sanitizer_Project
import org.owasp.html.Sanitizers;
import org.owasp.html.PolicyFactory;
PolicyFactory sanitizer = Sanitizers.FORMATTING.and(Sanitizers.BLOCKS);
String cleanResults = sanitizer.sanitize("<p>Hello, <b>World!</b>");
DOM Based XSS
RULE #1 - HTML Escape then JavaScript Escape Before Inserting Untrusted Data into HTML Subcontext within the Execution Context
element.innerHTML = “<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”;
element.outerHTML = “<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”;
document.write(“<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”);
document.writeln(“<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”);
RULE #2 - JavaScript Escape Before Inserting Untrusted Data into HTML Attribute Subcontext within the Execution Context
var x = document.createElement(“input”);
x.setAttribute(“name”, “company_name”);
x.setAttribute(“value”, ‘<%=Encoder.encodeForJS(companyName)%>’);
var form1 = document.forms[0];
form1.appendChild(x);
RULE #3 - Be Careful when Inserting Untrusted Data into the Event Handler and JavaScript code Subcontexts within an Execution Context
Never have a code such as below which tries to set an untrusted incoming data as a JS attribute.
// In the line of code below, the encoded data on the right (the second argument to setAttribute)
// is an example of untrusted data that was properly JavaScript encoded but still executes.
x.setAttribute("onclick", "\u0061\u006c\u0065\u0072\u0074\u0028\u0032\u0032\u0029");
An alternative to using Element.setAttribute(...) to set DOM attributes is to set the attribute directly. Directly setting event handler attributes will allow JavaScript encoding to mitigate against DOM based XSS.
/The following does NOT work because the event handler is being set to a string. "alert(7)" is JavaScript encoded.
document.getElementById("bb").onclick = "\u0061\u006c\u0065\u0072\u0074\u0028\u0037\u0029";
//The following DOES WORK because the encoded value is a valid variable name or function reference. "testIt" is JavaScript encoded - Vulnerable to XSS
document.getElementById("bb").onmouseover = \u0074\u0065\u0073\u0074\u0049\u0074;
RULE #4 - JavaScript Escape Before Inserting Untrusted Data into the CSS Attribute Subcontext within the Execution Context
document.body.style.backgroundImage = "url(<%=Encoder.encodeForJS(Encoder.encodeForURL(companyName))%>)";
RULE #5 - URL Escape then JavaScript Escape Before Inserting Untrusted Data into URL Attribute Subcontext within the Execution Context
x.setAttribute(“href”, ‘<%=Encoder.encodeForJS(Encoder.encodeForURL(userRelativePath))%>’);
RULE #6: Use encodeForURL() when you add any URL in the page.
Reference:
https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#Output_Encoding_Rules_Summary
Clickjacking .
Every page template should have the X-Frame-Options Header set with ALLOW-FROM header.
<script >
if (self === top) {
var antiClickjack = document.getElementById("antiClickjack");
antiClickjack.parentNode.removeChild(antiClickjack);
} else {
top.location = self.location;
}
</script>
Cross-Site Reference Forgery - CSRF / XSRF / Sea Surf / Session Riding / Hostile Linking / One-Click attack
Do not support HTTP GET
Every form submit must have a CSRF token attached to it.
Use OWASP CSRFGuard for mitigating this.
PRG
Use the flashScope Request parameters in Spring MVC.
http://www.tikalk.com/redirectattributes-new-feature-spring-mvc-31/
http://sectooladdict.blogspot.co.uk/2012/07/2012-web-application-scanner-benchmark.html
http://sectools.org/
http://www.acunetix.com/vulnerability-scanner/
http://sectoolmarket.com/price-and-feature-comparison-of-web-application-scanners-unified-list.html
https://ironwasp.org
http://www.veracode.com/security/application-vulnerability
http://www.ibm.com/developerworks/library/se-prevent/
B. Every request should go through a controller except for the static content
C. Block GET in all web applications irrespective of whether it takes a parameter or not
D. Every request sent to a container must be secure. If there are any data that need to be served w/o authentication check, then serve them from a different webapplication/container.
E. Any file retrieval API should look only in the specific folders.
F. Do not use SOP in the code, especially never put e.PrintStakTrace();
G. Run Fortify Static code analysis
H. Think abut buying a penetration testing tool - https://www.acunetix.com/vulnerability-scanner/
I. Use an open source penetration testing tool - https://ironwasp.org
J. Never put an incoming data in an target URL
K. Never send back sensitive data to an URL that is coming as part of the query string without validating it against a whitelist.
L. All pages/responses except the file downloads from IE must contain the following headers.
Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0
M. Add the following headers in every response.
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains X-Frame-Options: DENY
XSS
C. Untrusted data should only be treated as displayable text. Never treat untrusted data as code or markup within JavaScript code.
D. Always JavaScript encode and delimit untrusted data as quoted strings when entering the application. Ex: var x = “<%=encodedJavaScriptData%>”;
E. Do not use element.setAttribute(“…”,”value”) for adding behavior with untrusted data. For example, you should not do element.setAttribute("onClick","<request.getParameter("myInput")>").
F. If you use any of the below methods, then use Encoder.encodeForJS for all attributes passed to these methods.
element.innerHTML = “…”;
element.outerHTML = “…”;
document.write(…);
document.writeln(…);
G. Don’t eval() JSON to convert it to native JavaScript objects. Instead use JSON.toJSON() and JSON.parse() (Chris Schmidt).
H. Anything that you write back - data from DB, paramenter from URL, cookies, user agent - if it is within an executable context (i.e., within the HTML markup), then encode them with appropriate encoder.
I. Never use an input value as a CSS class / style value
XSS - ESAPI Encoders:
RULE #0 - Never Insert Untrusted Data. Always use an encoder
RULE #1 - HTML Escape Before Inserting Untrusted Data into HTML Element Content
Sample: <div>...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...</div>
Mitigation: String safe = ESAPI.encoder().encodeForHTML( request.getParameter( "input" ) );
RULE #2 - Attribute Escape Before Inserting Untrusted Data into HTML Common Attributes
Sample: <div attr=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...>content</div>
Mitigation: String safe = ESAPI.encoder().encodeForHTMLAttribute( request.getParameter( "input" ) );
RULE #3 - JavaScript Escape Before Inserting Untrusted Data into JavaScript Data Values
Sample:
<script>x='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'</script> one side of a quoted expression
<div onmouseover="x='...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...'"</div> inside quoted event handler
window.setInterval('...EVEN IF YOU ESCAPE UNTRUSTED DATA YOU ARE XSSED HERE...');
Mitigation: String safe = ESAPI.encoder().encodeForJavaScript( request.getParameter( "input" ) );
RULE #4: HTML escape JSON values in an HTML context and read the data with JSON.parse
// external js file
var dataElement = document.getElementById('init_data');
// unescape the content of the span
var jsonText = dataElement.textContent || dataElement.innerText
var initData = JSON.parse(html_unescape(jsonText));
RULE #5 - URL Escape Before Inserting Untrusted Data into HTML URL Parameter Values
Sample: <a href="http://www.somesite.com?test=...ESCAPE UNTRUSTED DATA BEFORE PUTTING HERE...">link</a >
Mitigation: String safe = ESAPI.encoder().encodeForURL( request.getParameter( "input" ) );
WARNING: Do not encode complete or relative URL's with URL encoding! If untrusted input is meant to be placed into href, src or other URL-based attributes, it should be validated to make sure it does not point to an unexpected protocol, especially
Javascript links.
String userURL = request.getParameter( "userURL" )
boolean isValidURL = ESAPI.validator().isValidInput("URLContext", userURL, "URL", 255, false);
if (isValidURL) {
<a href="<%=encoder.encodeForHTMLAttribute(userURL)%>">link</a>
}
RULE #6 - Sanitize HTML Markup with a Library Designed for the Job - JSoup or HTML Sanitizer
OWASP Java HTML Sanitizer - https://www.owasp.org/index.php/OWASP_Java_HTML_Sanitizer_Project
import org.owasp.html.Sanitizers;
import org.owasp.html.PolicyFactory;
PolicyFactory sanitizer = Sanitizers.FORMATTING.and(Sanitizers.BLOCKS);
String cleanResults = sanitizer.sanitize("<p>Hello, <b>World!</b>");
DOM Based XSS
RULE #1 - HTML Escape then JavaScript Escape Before Inserting Untrusted Data into HTML Subcontext within the Execution Context
element.innerHTML = “<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”;
element.outerHTML = “<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”;
document.write(“<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”);
document.writeln(“<%=Encoder.encodeForJS(Encoder.encodeForHTML(untrustedData))%>”);
RULE #2 - JavaScript Escape Before Inserting Untrusted Data into HTML Attribute Subcontext within the Execution Context
var x = document.createElement(“input”);
x.setAttribute(“name”, “company_name”);
x.setAttribute(“value”, ‘<%=Encoder.encodeForJS(companyName)%>’);
var form1 = document.forms[0];
form1.appendChild(x);
RULE #3 - Be Careful when Inserting Untrusted Data into the Event Handler and JavaScript code Subcontexts within an Execution Context
Never have a code such as below which tries to set an untrusted incoming data as a JS attribute.
// In the line of code below, the encoded data on the right (the second argument to setAttribute)
// is an example of untrusted data that was properly JavaScript encoded but still executes.
x.setAttribute("onclick", "\u0061\u006c\u0065\u0072\u0074\u0028\u0032\u0032\u0029");
An alternative to using Element.setAttribute(...) to set DOM attributes is to set the attribute directly. Directly setting event handler attributes will allow JavaScript encoding to mitigate against DOM based XSS.
/The following does NOT work because the event handler is being set to a string. "alert(7)" is JavaScript encoded.
document.getElementById("bb").onclick = "\u0061\u006c\u0065\u0072\u0074\u0028\u0037\u0029";
//The following DOES WORK because the encoded value is a valid variable name or function reference. "testIt" is JavaScript encoded - Vulnerable to XSS
document.getElementById("bb").onmouseover = \u0074\u0065\u0073\u0074\u0049\u0074;
RULE #4 - JavaScript Escape Before Inserting Untrusted Data into the CSS Attribute Subcontext within the Execution Context
document.body.style.backgroundImage = "url(<%=Encoder.encodeForJS(Encoder.encodeForURL(companyName))%>)";
RULE #5 - URL Escape then JavaScript Escape Before Inserting Untrusted Data into URL Attribute Subcontext within the Execution Context
x.setAttribute(“href”, ‘<%=Encoder.encodeForJS(Encoder.encodeForURL(userRelativePath))%>’);
RULE #6: Use encodeForURL() when you add any URL in the page.
Reference:
https://www.owasp.org/index.php/DOM_based_XSS_Prevention_Cheat_Sheet
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet
https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#Output_Encoding_Rules_Summary
Clickjacking .
Every page template should have the X-Frame-Options Header set with ALLOW-FROM header.
<script >
if (self === top) {
var antiClickjack = document.getElementById("antiClickjack");
antiClickjack.parentNode.removeChild(antiClickjack);
} else {
top.location = self.location;
}
</script>
Cross-Site Reference Forgery - CSRF / XSRF / Sea Surf / Session Riding / Hostile Linking / One-Click attack
Do not support HTTP GET
Every form submit must have a CSRF token attached to it.
Use OWASP CSRFGuard for mitigating this.
PRG
Use the flashScope Request parameters in Spring MVC.
http://www.tikalk.com/redirectattributes-new-feature-spring-mvc-31/
http://sectooladdict.blogspot.co.uk/2012/07/2012-web-application-scanner-benchmark.html
http://sectools.org/
http://www.acunetix.com/vulnerability-scanner/
http://sectoolmarket.com/price-and-feature-comparison-of-web-application-scanners-unified-list.html
https://ironwasp.org
http://www.veracode.com/security/application-vulnerability
http://www.ibm.com/developerworks/library/se-prevent/