Java - Client Side Template Injection (CSTI)
Last updated
Last updated
Now that the app is running let's go hacking!
This application has a very cool interface, powered by a very cool framework that, every time the page is rendered, will scan the page for template expressions and evaluate them.
Before we deep dive in the exploitation phase, let's introduce how a template engins renders elements inside the page and how we can detect a Client Side Template Injection. If we look at the index.html
page in the source code, we can see that a variable {{csti}}
is used in the page
This can look like a XSS, but if we try to inject HTML tags we get a nice print-out from the application. Let's try!
We are going to use the same payload of the XSS lab
Unfortunately the alert does not trigger :(
This is becuase AngularJS sanitize by default the input that will be reflected in the page.
How do we get XSS?
AngularJS parses and renders every expression between curly brackets. So if we pass an arithmentic expression, such as {{7*7}}
, we should expect 49
as a result.
Bingo!!
Now that we know that the frontend is vulnerable to a client side template injection, we want to do more than just printing out nice numbers.
Because Angular uses parsers to evaluate every expression in curly brackets, sanitize HTML values (through ng-bind-html attributes, if explicitly) and uses a sandbox to avoid JavaScript code to call functions outside of the Angular scope object, we need to go though the following steps to have a successful exploit:
break the sanitizer
escape the sandbox
forge a working payload
In this case, we do not need to find new way to do this, but we can just see if we can re-use a payload available for our version of Angular.
We want to identify wich version is used in the frontend. If we look at the source code we can see that in the <head>
tag Angular v1.5.0 is loaded.
We need a payload that will allow us to inject JavaScript commands in the DOM and escape the sandbox, and, of course, pop up an alert box (just as a PoC)
Looking at possible payloads we found a working one for this version of Angular
We are not going in the details on how the exploit works, but you can refer to a nice blog post from PortsWigger. What we can say, is that the escape, breaks out of the sandbox (we are not in the scope object anymore) and allows us to execute JS in the DOM itself.
As we can see, our alert(1)
is present in the payload. If we copy it in our input box we see that the full payload is reflected 'as-it-is', but the JavaScript is executed
Now we are able to execute JavaScript code in our DOM.
This would work if we would have used the latest version of Angular and escaped malicious characters.
!