diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 283ba09..86053f0 100755 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -28,6 +28,8 @@ //= require jquery.easy-pie-chart.js //= require jquery-fileupload/basic //= require jquery-fileupload/vendor/tmpl +//= require jsapi +//= html5.js function rubyCodeFormat() { diff --git a/app/assets/javascripts/html5.js b/app/assets/javascripts/html5.js new file mode 100644 index 0000000..6168aac --- /dev/null +++ b/app/assets/javascripts/html5.js @@ -0,0 +1,8 @@ +/* + HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed +*/ +(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag(); +a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x"; +c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode|| +"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f); +if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d\x3c/script>"):(D("safari")||D("konqueror"))&&g[y](S,10)),O[m](a)):P(g,"load",a)};K("google.setOnLoadCallback",google.T); +function P(a,b,c){if(a.addEventListener)a.addEventListener(b,c,!1);else if(a.attachEvent)a.attachEvent("on"+b,c);else{var e=a["on"+b];a["on"+b]=null!=e?aa([c,e]):c}}function aa(a){return function(){for(var b=0;b\x3c/script>'):"css"==a&&h.write('')}; +K("google.loader.writeLoadTag",google[z].d);google[z].Q=function(a){N=a};K("google.loader.rfm",google[z].Q);google[z].S=function(a){for(var b in a)"string"==typeof b&&b&&":"==b[q](0)&&!M[b]&&(M[b]=new T(b[A](1),a[b]))};K("google.loader.rpl",google[z].S);google[z].R=function(a){if((a=a.specs)&&a[w])for(var b=0;b - diff --git a/app/views/layouts/tutorial/insecure_components/_insecure_components_first.html.erb b/app/views/layouts/tutorial/insecure_components/_insecure_components_first.html.erb index b5192d5..208412e 100644 --- a/app/views/layouts/tutorial/insecure_components/_insecure_components_first.html.erb +++ b/app/views/layouts/tutorial/insecure_components/_insecure_components_first.html.erb @@ -1,7 +1,7 @@
- A9 - Using Components with Known Vulnerabilities + A9 - Using Components with Known Vulnerabilities (Rack / Rails)
diff --git a/app/views/layouts/tutorial/insecure_components/_insecure_components_second.html.erb b/app/views/layouts/tutorial/insecure_components/_insecure_components_second.html.erb new file mode 100644 index 0000000..0c424c4 --- /dev/null +++ b/app/views/layouts/tutorial/insecure_components/_insecure_components_second.html.erb @@ -0,0 +1,109 @@ +
+
+
+ A9 - Using Components with Known Vulnerabilities (DOM XSS / JQuery Snippet) +
+
+
+
+
+ +
+
+ JQuery Snippet contains at least one DOM-Based XSS vulnerability that can be confirmed in IE11. Unknowingly, the Railsgoat development team used this library. Credit for vulnerability discovery as well as submission to <%= link_to "@raesene", "http://github.com/raesene", {:style => "color: rgb(181, 121, 158)", :target => "_blank"}%>. This was unintentional but goes to show how easily vulnerabilities can creep in when using third-party libraries. +
+
+
+
+ +
+
+

+ Within the file app/assets/javascripts/jquery.snippet.js: +

+
+				<%= %{
+// snippet new window popup function
+function snippetPopup(content) \{
+	 top.consoleRef=window.open('','myconsole',
+	  'width=600,height=300'
+	   +',left=50,top=50'
+	   +',menubar=0'
+	   +',toolbar=0'
+	   +',location=0'
+	   +',status=0'
+	   +',scrollbars=1'
+	   +',resizable=1');
+	 top.consoleRef.document.writeln(
+	  'Snippet :: Code View :: '+}%><span style="background-color:yellow">location.href</span><%= %{+''
+	   +''
+	   +'
'+content+'
' + +'' + ); + top.consoleRef.document.close(); +\}}%>
+

+ We can see that the location.href DOM property is used to dynamically generate a title for the text box pop-up. This value is string concatenated directly from the DOM without first performing some escaping routine or HTML encoding. +

+
+
+
+
+ +
+
+

Using Components with Known Vulnerabilities (DOM XSS) - ATTACK

+

+ In order to demonstrate that you can indeed perform DOM XSS through this coding error, we will use a simple alert box. This does not appear to work in Chrome, Safari, or Firefox as they first URL encoded the script portion of the url before rendering which complicates browser interpretation. IE on the other hand, true to form, is totally vulnerable. The following example assumes you are running Railsgoat on localhost, port 3000. If this is the case, open IE, paste the URL (below) into IE. +

+
+<%= "http://localhost:3000/tutorials/injection#" %>
+				  
+

+ The portion after the pound (#) symbol will close off the title and head portions of the HTML and then allow for properly generated JavaScript to be rendered and executed. After browsing to this URL, navigate to the tutorial where code snippets are shown and click on the "pop-up" link that appears after hovering over the code snippet. This should be all that is required to demonstrate DOM-XSS. +

+

Using Components with Known Vulnerabilities (DOM XSS) - SOLUTION

+

+ Use the hoganEscape() function defined in application.js to solve this problem. For instance: +

+
+<%=%{'Snippet :: Code View :: '+}%><span style="background-color:yellow">hoganEscape(location.href)</span> <%=%{+'' }%>
+			      
+
+
+
+
+ +
+
+ Review the JQuery Code Snippet for any content that might be mirrored or reflected back and that is under our control. +
+
+
+
+
+
\ No newline at end of file diff --git a/app/views/layouts/tutorials.html.erb b/app/views/layouts/tutorials.html.erb index 3a398b9..b1b2d26 100755 --- a/app/views/layouts/tutorials.html.erb +++ b/app/views/layouts/tutorials.html.erb @@ -5,15 +5,11 @@ <%= stylesheet_link_tag "application", :media => "all" %> <%= javascript_include_tag "application" %> <%#= csrf_meta_tags %> - - - - diff --git a/app/views/tutorials/insecure_components.html.erb b/app/views/tutorials/insecure_components.html.erb index 271f7a9..66d9863 100644 --- a/app/views/tutorials/insecure_components.html.erb +++ b/app/views/tutorials/insecure_components.html.erb @@ -5,6 +5,11 @@ <%= render :partial => "layouts/tutorial/insecure_components/insecure_components_first" %>
+
+
+ <%= render :partial => "layouts/tutorial/insecure_components/insecure_components_second" %> +
+