if (a == "Hello" && a == "world") { //Huh? document.write("Hello world") }
var a = { t: false, valueOf: function() { return (this.t = !this.t) ? "Hello" : "world" } }
http://example.com/#/inbox/32
pushState()
<ul> <% emails.each(function(email) { %> <li><a href="#/emails/<%= email.get("id") %>"><%= email.get("subject") %></a></li> <% }); %> </ul>
<ul> <% emails.each(function(email) { %> <li><a href="#/emails/{{ email.get("id") }}">{{ email.get("subject") }}</a></li> <% }); %> </ul>
<% %>
- evaluate code<%= %>
- output<%- %>
- HTML-escaped output<img src=xxx/update?site_name[name]=yyy>
<html> <form action="http://example.com" method="post" enctype="text/plain"> <input name='{"a":1,"b":{"c":3}, "ignore_me":"' value='test"}' type='hidden'> <input type=submit> </form> </html>
{"a":1,"b":{"c":3}, "ignore_me":"=test"}
function fileUpload(url, fileData, fileName) { var fileSize = fileData.length; var boundary = "xxxxxxxxx"; var xhr = new XMLHttpRequest(); xhr.open("POST", url, true); xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary); xhr.setRequestHeader("Content-Length", fileSize); var body = "--" + boundary + "\r\n"; body += 'Content-Disposition: form-data; name="contents"; filename="' + fileName + '"\r\n'; body += "Content-Type: application/octet-stream\r\n\r\n"; body += fileData + "\r\n"; body += "--" + boundary + "--"; xhr.send(body); return true; }
$("body").bind("ajaxSend", function(elm, xhr, s){ if (s.type === "POST" || s.type === "DELETE" || s.type === "PUT") { xhr.setRequestHeader('X-CSRF-Token', authentication.csrf_token); } });
http://conference.cfn/#talks/1/edit
http://conference.cfn/#talks/1/delete
http://conference.cfn/#talks/1/delete
http://example.com/?error=Invalid+name
<div class="error">Invalid name</div>
http://example.com/?error=<script>alert(1)</script>
<div class="error"><script>alert(1)</script></div>
X-Content-Type-Options: nosniff
Content-Disposition: attachment; filename=data.json
http://ex.fm/#!/explore/<script>alert("@vlycser");</script>
<% %>
- evaluate code<%= %>
- output<%- %>
- HTML-escaped output_.escape = function(string) { return (''+string).replace(/&/g, '&'). replace(/</g, '<'). replace(/>/g, '>'). replace(/"/g, '"'). replace(/'/g, '''). replace(/\//g,'/'); };
<button onclick="return confirm('Really delete <%- model.title %>')">Delete</button>
<button onclick="return confirm('Really delete ');alert(&x27;XSS')">Delete</button>
<img title=<%- model.title %> ... >
<img title=monkey onmouseover=alert(/XSS/.source) ... >
style
attributes or tagsscript
tagsFor more info - see the OWASP XSS Prevention Cheat sheet
<% %>
- evaluate code<%- %>
- unescaped/raw output<%= %>
- contextually escape output or refuse output<a href=<%=url%> title="Buy <%=number%> at <%=price%> = $<%=cost%>/month AND SAVE $$$">BUY NOW</a>
{"url":"","number":42,"price":"onmouseover","cost":"=alert(1)/"}
<a href="title="Buy" 42="" at="" onmouseover="$=alert(1)//month" and="" save="" $$$"="">BUY NOW</a>
<svg> <a xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#"> <set attributeName="xlink:href" begin="0s" to="<%= url %>" /><circle r=40> </a> </svg>
{"url":"javascript:alert(1)"}
Content-Security-Policy: default-src 'self'; script-src 'self' *.googleapis.com
eval/setTimeout/setInterval/new Function
X-Frame-Options: DENY
Content-Disposition: attachment; filename=data.json
http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
/*!
* jQuery JavaScript Library v1.5.1
jQuery.fn.jquery
Handlebars.VERSION
$ retire --help
Usage: retire [options]
Options:
-h, --help output usage information
-V, --version output the version number
-p, --package limit node scan to packages where parent is mentioned in package.json (ignore node_modules)
-n, --node Run node dependency scan only
-j, --js Run scan of JavaScript files only
-v, --verbose Show identified files (by default only vulnerable files are shown)
-x, --dropexternal Don't include project provided vulnerability repository
-c, --nocache Don't use local cache
--jspath <path> Folder to scan for javascript files
--nodepath <path> Folder to scan for node files
--path <path> Folder to scan for both
--jsrepo <path> Local version of repo
--noderepo <path> Local version of repo
--proxy <url> Proxy url (http://some.sever:8080)
--ignore <paths> Comma delimited list of paths to ignore
Most web sites are using the jQuery version available when the site was first built