Fixes #99. We have added the hogan method for escaping user input and added a tutorial
This commit is contained in:
@@ -40,8 +40,36 @@ $("pre.ruby").snippet("ruby",{style:"rand01",transparent:true,showNum:true});
|
|||||||
// with a transparent background
|
// with a transparent background
|
||||||
// without showing line numbers.
|
// without showing line numbers.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$("pre.javascript").snippet("javascript",{style:"rand01",transparent:true,showNum:true});
|
||||||
|
// Finds <pre> elements with the class "js"
|
||||||
|
// and snippet highlights the JAVASCRIPT code within
|
||||||
|
// using a random style from the selection of 39
|
||||||
|
// with a transparent background
|
||||||
|
// without showing line numbers.
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var rAmp = /&/g,
|
||||||
|
rLt = /</g,
|
||||||
|
rGt = />/g,
|
||||||
|
rApos = /\'/g,
|
||||||
|
rQuot = /\"/g,
|
||||||
|
hChars = /[&<>\"\']/;
|
||||||
|
|
||||||
|
function hoganEscape(str) {
|
||||||
|
str = coerceToString(str);
|
||||||
|
return hChars.test(str) ?
|
||||||
|
str
|
||||||
|
.replace(rAmp, '&')
|
||||||
|
.replace(rLt, '<')
|
||||||
|
.replace(rGt, '>')
|
||||||
|
.replace(rApos, ''')
|
||||||
|
.replace(rQuot, '"') :
|
||||||
|
str;
|
||||||
|
}
|
||||||
|
|
||||||
$(document).ready(function(){
|
$(document).ready(function(){
|
||||||
rubyCodeFormat()
|
rubyCodeFormat()
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
<div class="widget">
|
||||||
|
<div class="widget-header">
|
||||||
|
<div class="title">
|
||||||
|
<span class="fs1" aria-hidden="true" data-icon=""></span> A3 - Cross-Site Scripting ("XSS") - DOM Based
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="widget-body">
|
||||||
|
<div id="accordion1" class="accordion no-margin">
|
||||||
|
<div class="accordion-group">
|
||||||
|
<div class="accordion-heading">
|
||||||
|
<a href="#collapseFive" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
|
||||||
|
<i class="icon-info icon-white">
|
||||||
|
</i>
|
||||||
|
Description
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-body in collapse" id="collapseFive" style="height: auto;">
|
||||||
|
<div class="accordion-inner">
|
||||||
|
<p>
|
||||||
|
DOM Based XSS (or as it is called in some texts, “type-0 XSS”) is an XSS attack wherein the attack payload is executed as a result of modifying the DOM “environment” in the victim’s browser used by the original client side script, so that the client side code runs in an “unexpected” manner. That is, the page itself (the HTTP response that is) does not change, but the client side code contained in the page executes differently due to the malicious modifications that have occurred in the DOM environment.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-group">
|
||||||
|
<div class="accordion-heading">
|
||||||
|
<a href="#collapseSix" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
|
||||||
|
<i class="icon-bug icon-white">
|
||||||
|
</i>
|
||||||
|
Bug
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-body collapse" id="collapseSix" style="height: 0px;">
|
||||||
|
<div class="accordion-inner">
|
||||||
|
<p>
|
||||||
|
The following code was taken from app/views/sessions/new.html.erb:
|
||||||
|
</p>
|
||||||
|
<pre class="javascript">
|
||||||
|
<%=
|
||||||
|
%{
|
||||||
|
<script>
|
||||||
|
//document.write("<select style=\"width: 100px;\">");
|
||||||
|
//document.write("<OPTION value=1>English</OPTION>");
|
||||||
|
//document.write("<OPTION value=2>Spanish</OPTION>");
|
||||||
|
try \{
|
||||||
|
var hashParam = location.hash.split("#")[1];
|
||||||
|
var paramName = hashParam.split('=')[0];
|
||||||
|
var paramValue = hashParam.split('=')[1];
|
||||||
|
document.write("<OPTION value=3>" +} %> <span style="background-color:yellow"> paramValue</span> <%= %{ + "</OPTION>");
|
||||||
|
\} catch(err) \{
|
||||||
|
\}
|
||||||
|
//document.write("</select>");
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
%>
|
||||||
|
</pre>
|
||||||
|
<p class="desc">
|
||||||
|
The code (above) takes user input (params), and renders it back on the page without any output encoding or escaping.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-group">
|
||||||
|
<div class="accordion-heading">
|
||||||
|
<a href="#collapseSeven" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
|
||||||
|
<i class="icon-lightning icon-white">
|
||||||
|
</i>
|
||||||
|
Solution
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-body collapse" id="collapseSeven" style="height: 0px;">
|
||||||
|
<div class="accordion-inner">
|
||||||
|
<p><b> Stored Cross-Site Scripting ATTACK:</b></p>
|
||||||
|
<p class="desc">
|
||||||
|
Ensure you are signed out of the application first. Make sure you are using something like Firefox as Safari/Chrome won't work for this exercise. Then, use the following link (substitute hostname for your actual hostname) to execute an alert box:
|
||||||
|
</p>
|
||||||
|
<pre>
|
||||||
|
<%= %{http://127.0.0.1:3000/#test=<script>alert(1)</script>} %>
|
||||||
|
</pre>
|
||||||
|
<p><b> Stored Cross-Site Scripting SOLUTION:</b></p>
|
||||||
|
<p>
|
||||||
|
Leverage the Hogan function for escaping (found in the application.js file) to escape user input:
|
||||||
|
</p>
|
||||||
|
<pre class="javascript">
|
||||||
|
<%= %{
|
||||||
|
<!-- support for multiple languages coming soon! -->
|
||||||
|
<script>
|
||||||
|
//document.write("<select style=\"width: 100px;\">");
|
||||||
|
//document.write("<OPTION value=1>English</OPTION>");
|
||||||
|
//document.write("<OPTION value=2>Spanish</OPTION>");
|
||||||
|
try \{
|
||||||
|
var hashParam = location.hash.split("#")[1];
|
||||||
|
var paramName = hashParam.split('=')[0];
|
||||||
|
var paramValue = hashParam.split('=')[1];
|
||||||
|
document.write("<OPTION value=3>" + } %> <span style="background-color:yellow"> hoganEscape(paramValue)</span> <%= %{ + "</OPTION>");
|
||||||
|
\} catch(err) \{
|
||||||
|
\}
|
||||||
|
//document.write("</select>");
|
||||||
|
</script>
|
||||||
|
}
|
||||||
|
|
||||||
|
%>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-group">
|
||||||
|
<div class="accordion-heading">
|
||||||
|
<a style="background-color: rgb(181, 121, 158)" href="#collapseEight" data-parent="#accordion1" data-toggle="collapse" class="accordion-toggle">
|
||||||
|
<i class="icon-aid icon-white">
|
||||||
|
</i>
|
||||||
|
Hint
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="accordion-body collapse" id="collapseEight" style="height: 0px;">
|
||||||
|
<div class="accordion-inner">
|
||||||
|
<p class="desc">
|
||||||
|
You should view the source of the login page, might be something interesting there.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -5,6 +5,11 @@
|
|||||||
<%= render :partial => "layouts/tutorial/xss/xss_first"%>
|
<%= render :partial => "layouts/tutorial/xss/xss_first"%>
|
||||||
</div> <!-- End Span12 -->
|
</div> <!-- End Span12 -->
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span12"> <!-- Begin Span12 -->
|
||||||
|
<%= render :partial => "layouts/tutorial/xss/dom_xss"%>
|
||||||
|
</div> <!-- End Span12 -->
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user