...
A3
...
Cross-Site
...
Scripting
...
(XSS)
...
XSS flaws occur whenever an application takes untrusted data and sends it to a web browser without proper validation or escaping. XSS allows attackers to execute scripts in the victim’s browser which can hijack user sessions, deface web sites, or redirect the user to malicious sites.
A 3.1 Defenses:
Encode untrusted data:
Data Type | Context | Code Sample | Defense |
String | HTML Body | <span>UNTRUSTED DATA</span> | |
String | Safe HTML Attributes | <input value="UNTRUSTED DATA"> |
|
String | GET Parameter | <a href="/site/search?value=UNTRUSTED DATA">clickme</a> | |
String | Untrusted URL in a SRC or HREF attribute | <a href="UNTRUSTED URL">clickme</a> |
|
String | CSS Value | <div style="width:UNTRUSTED DATA">Selection</div> |
|
String | JavaScript Variable | <script>var currentValue='UNTRUSTED DATA'</script> |
|
HTML | HTML Body | <div>UNTRUSTED HTML</div> | |
String | DOM XSS | <script>document.write("UNTRUSTED INPUT: " + document.location.hash);<script/> |
A 3.2. Sanitizers:
A 3.2.1 OWASP Java HTML Sanitizer Project
If you are using Maven then follow the maven directions to add a dependency. Otherwise, download prebuilt jars;or;git clone git@github.com:OWASP/java-html-sanitizer.git;and build the latest source.
Unless maven is managing your CLASSPATH for you, you need to add both owasp-java-html-sanitizer.jar and the Guava JAR.
Once you have your CLASSPATH set up correctly with the relevant JARs you should be able to addimport org.owasp.html.HtmlPolicyBuilder;to one of your project's;.java;files and compile it.
Unless maven is managing your CLASSPATH for you, you need to add both owasp-java-html-sanitizer.jar;and the Guava JAR.
A 3.2.2 OWASP Java Encoder
https://www.owasp.org/index.php/OWASP_Java_
...
...
Project#tab=Use_the_Java_Encoder_Project
HTML Content Context
Code Block |
---|
<textarea><%= Encode.forHtmlContent(UNTRUSTED)%></textarea>
|
HTML Attribute context
Code Block |
---|
<input value="<%= Encode.forHtmlAttribute(UNTRUSTED)%>"
|
Generally Encode.forHtml(UNTRUSTED) is also safe but slightly less efficient for the above two contexts (for textarea content and input value text) since it encodes more characters than necessary but might be easier for developers to use.
CSS contexts
Code Block |
---|
<div style="width:<= Encode.forCssString(UNTRUSTED)%>">
<div style="background:<= Encode.forCssUrl(UNTRUSTED)%>">
|
*Javascript Block context;
Code Block |
---|
<script>
var msg = "<%= Encode.forJavaScriptBlock(UNTRUSTED)%>";
alert(msg);
</script>
|
*Javascript Variable context
Code Block |
---|
<button onclick="alert('<%= Encode.forJavaScriptAttribute(UNTRUSTED)%>');">click me
</button>
|
JavaScript Content Notes:
Code Block |
---|
Encode.forJavaScript(UNTRUSTED);
|
Is safe for the above two contexts, but encodes more characters and is less efficient.
Encode URL parameter values
Code Block |
---|
<a href="/search?value=<%= Encode.forUriComponent(UNTRUSTED)%>&order=1#top">
|
Encode REST URL parameters
Code Block |
---|
<a href="/page/<%= Encode.forUriComponent(UNTRUSTED)%>">
|
Handling an Full Untrusted URL
When handling a full url with the OWASP Java encoder, first verify the URL is a legal URL.
Code Block |
---|
String url = validateURL(untrustedInput);
|
Then encode the URL as an HTML attribute when outputting to the page. Note the linkable text needs to be encoded in a different context.
Code Block |
---|
<a href="<%= Encode.forHtmlAttribute(untrustedUrl)%>">
<%= Encode.forHtmlContent(untrustedLinkName);%>
</a>
|
To use in a JSP with EL
Code Block |
---|
<%@page contentType="text/html" pageEncoding="UTF-8"%> <\!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <%@taglib prefix="e" uri="https://www.owasp.org/index.php/AJAXOWASP_SecurityJava_Cheat_Sheet#Avoid_building_XML_or_JSON_dynamically] * [Never transmit secrets to the client|https://www.owasp.org/index.php/AJAX_Security_Cheat_Sheet#Never_transmit_secrets_to_the_client] * [Don't perform encryption in client side code|https://www.owasp.org/index.php/AJAX_Security_Cheat_Sheet#Don.27t_perform_encryption_in_client_side_code] * [Don't perform security impacting logic on client side|https://www.owasp.org/index.php/AJAX_Security_Cheat_Sheet#Don.27t_perform_security_impacting_logic_on_client_side] ** [1.2 Server Side|Encoder_Project"%> <html> <head> <title><e:forHtml value="${param.title}" /></title> </head> <body> <h1>${e:forHtml(param.data)} </h1> </body> </html> |
Other contexts can be found in the org.owasp.Encode class methods, including CSS strings, CSS urls, XML contexts, URIs and URI components.
A 3.2.3 DOMPurify
A 3.2.4 MentalJS
MentalJS is a JavaScript parser and sandbox. It whitelists JavaScript code by adding a "$" suffix to variables and accessors.
A 3.2.5 OWASP JSON Sanitizer
A 3.2.6 Third Party Javascript Management Cheat Sheet
https://www.owasp.org/index.php/
...
3rd_Party_Javascript_Management_Cheat_
...
A 3.3 AJAX Security Best Practices:
- Client Side (Javascript)
- Use .innerText instead of .innerHtml
- Don't use eval
- Canonicalize data to consumer (read: encode before use)
- Don't rely on client logic for security
- Don't rely on client business logic
- Avoid writing serialization code
- Avoid building XML or JSON dynamically
- Never transmit secrets to the client
- Don't perform encryption in client side code
- Don't perform security impacting logic on client side
- Server Side
- Protect against JSON Hijacking for Older BrowsersUse CSRF Protection
- Always return JSON with an Object on the outside
- Avoid writing serialization code. Remember ref vs. value types!
- Services can be called by users directly
- Avoid building XML or JSON by hand, use the framework
- Use JSON And XML Schema for Webservices
A 3.4 HTTP Response Splitting
Attacks:
Major form of attacks can result from HTTP Response Splitting:
- Phishing
- Cross-site Scripting
- Web Cache Poisoning
- Hijacking pages
- Browser cache Poisoning
- Cross User attacks (single user, single page, temporary defacement)
Best Practices:
Investigate all uses of HTTP headers, such as:
- setting cookies
- using location (or redirect() functions)
- setting mime-types, content-type, file size, etc.
- or setting custom headers
If these contain unvalidated user input, the application is vulnerable when used with application frameworks that cannot detect this issue.
If the application has to use user-supplied input in HTTP headers, it should check for double “\n” or “\r\n” values in the input data and eliminate it.
Many application servers and frameworks have basic protection against HTTP response splitting, but it is not adequate to task, and you should not allow unvalidated user input in HTTP headers.
A 3.5. General Recommedations:
A 3.5.1 Avoid nested context
But if you must have it the right order to encode is as follows:
- JS encode first
- HTML attribute encode second
Code Block Encoder.encodeForHtml(Encoder.encoderForJavaScript(request.getParameter(error)));
...
A 3.5.2
...
Encode
...
every
...
variable
...
before
...
showing
...
to user
Code Block |
---|
useraa href="%=Encode.forHTMLAttribute(UNTRUSTED_URL)%>"> Encode.forHTMLcontext(URL)\\ h4. |
3.5.3.
...
Safe
...
way
...
to
...
populate DOM
Code Block |
---|
DOMelemelem.textContent formfield.value document.createTextnode\\ h4. |
3.5.4
...
Safe JSON parsing
Code Block |
---|
JSON parsingJSON.parse()
|
Do
...
not
...
use
...
eval()
...
3.5.5
...
jQuery
...
most
...
unsafe
...
ways
...
to
...
populate
...
data.html
Code Block |
---|
.before\\ h4. |
3.5.6
...
jQuery
...
safe
...
ways
...
to
...
populate data
Code Block |
---|
data.text(UNTRUSTED_DATA) .val(UNTRUSTED_DATA)\\ \\ h4. |
3.5.7
...
Sandboxing
...
Code Block |
---|
JavaScriptECMAScript
Object.seal ( O )
\\
|
When
...
the
...
seal
...
function
...
is
...
called,
...
the
...
following
...
steps
...
are
...
taken:
...
1.
...
If
...
Type(O)
...
is
...
not
...
Object,
...
return
...
O.
...
2.
...
Let
...
status
...
be
...
Set Integrity Level(
...
O,
...
"sealed").
...
3.
...
Return IfAbrupt(status).
...
4.
...
If
...
status
...
is
...
false,
...
throw
...
a
...
TypeError
...
exception.
...
5.
...
Return
...
O.
...
Reference:
...
www.
...
ecmascript
...
.org
...
Code Block |
---|
iFrame Sandboxing (HTML5)\\ <iframe src="demo_iframe_sandbox.jsp sandbox=""></iframe>Allow> </iframe> |
Allow-same-origin,
...
allow-top-navigation,
...
allow-forms,
...
allow-scripts
...
3.5.8.
...
HTML
...
Response
...
Headersx-xss-protection:0-1
...
(mode=block1;
...
1;
...
mode=block)
...
*
xframe-options:
...
DENY
...
(prevent
...
any
...
domain
...
from
...
framing
...
your
...
page),
...
SAMEORIGIN
...
(only
...
allows
...
the
...
current
...
site
...
to
...
frame
...
your
...
page)***
...
ALLOW
...
FROM
...
X
...
Set
...
X-Frame-Options
...
to
...
SAMEORIGIN
...
to
...
stop
...
framing
...
and
...
limit
...
clickjacking.
...
Must
...
be
...
added
...
to
...
response
...
header
...
because
...
x-frame-option
...
http
...
request
...
headers
...
does
...
nothing.
...
x-content-type-options:
...
nosniffTo
...
stop
...
guessing
...
of
...
mime
...
type,
...
applies
...
to
...
IE
...
and
...
Chrome
...
Implement
...
x-content-security-policyx-content-security-policy
...
Powerful
...
mechanism
...
for
...
controlling
...
which
...
sites
...
can
...
execute
...
JS,
...
current
...
standard.
...
Implement
...
secure
...
headers:
...
allow-control-allow-origin,
...
xdomain
...
use
...
image
...
strict-transport-security,
...
forces
...
browser
...
to
...
use
...
https,
...
critical
...
cache-control:
...
no-store,
...
no-cache,
...
must-revalidate,
...
expiresz;
...
-1
...
(expire
...
in
...
the
...
past)
...
References:
...
https://github.com/twitter/secureheaders\
...
3.5.9
...
Output
...
encoding
...
JSF
...
output
...
components
...
filter
...
output
...
and
...
escape
...
dangerous
...
characters
...
as
...
XHTML
...
entities
...
Code Block |
---|
<h:outputText Value="#{param.name}"/>\\ \\ h4. |
3.5.10
...
XXE
...
prevention
...
Set
...
the
...
IS_SUPPORTING_EXTERNAL_ENTITIES
...
property
...
in
...
xalan
...
to
...
FALSE:
...
Code Block |
---|
XMLInputFactory factory = XMLInputFactory.newInstance(); factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
|
Set
...
the
...
IS_SUPPORT_DTD
...
property
...
in
...
xalan
...
to
...
FALSE:
...
Code Block |
---|
XMLInputFactory factory = XMLInputFactory.newInstance(); factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);\\ [http://web-in-security.blogspot.in/2016/03/xxe-cheat-sheet.html|http://web-in-security.blogspot.in/2016/03/xxe-cheat-sheet.html] [http://web-in-security.blogspot.de/2016/03/xml-parser-evaluation.html|http://web-in-security.blogspot.de/2016/03/xml-parser-evaluation.html] http://lists.owasp.org/pipermail/owasp_sonarqube/2015-March/000023.html = XMLInputFactory.newInstance(); factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); |
Learn More
- OWASP XSS Prevention Cheat Sheet
- XSS Prevention Rules Summary
- OWASP Cross-Site Scripting Article
- Unraveling Some Mysteries around DOM-based XSS
- ESAPI Project Home Page
- ESAPI Encoder API
- ASVS: Output Encoding/Escaping Requirements (V6)
- ASVS: Input Validation Requirements (V5)
- Testing Guide: 1st3 Chapters on Data Validation Testing
- OWASP Code Review Guide: Chapter on XSS Review
- CWE Entry 79 on Cross-Site Scripting
- Rsnake’s XSS Attack Cheat Sheet
- XXE Cheat Sheet
- XML Parser Evaluation
- RSPEC proposal about Java and XXE