AngularJS expression injection is a security vulnerability that occurs when an attacker can inject malicious expressions into an application, allowing unauthorized code execution. This can lead to XSS (Cross-Site Scripting), data leaks, and privilege escalation.
In this guide, we’ll break down:
What AngularJS expression injection is
How attackers exploit it
How to prevent it
1. Understanding AngularJS Expressions
AngularJS uses expressions inside double curly braces {{ }}
or in directive attributes like ng-bind
, ng-click
, etc. These expressions execute within the AngularJS scope and can perform arithmetic, function calls, and property access.
Example of a Safe AngularJS Expression:
<p>{{ user.name }}</p>
Here, AngularJS evaluates user.name
and displays its value safely.
2. How Expression Injection Works
Expression injection occurs when an attacker injects untrusted data into an AngularJS expression, forcing the app to execute arbitrary code. This can lead to XSS attacks, where malicious JavaScript is executed on the user’s browser.
Example of Vulnerable Code (User-Controlled Input in Expressions)
<p>{{ userInput }}</p>
If userInput
comes from untrusted sources, an attacker can inject a payload like:
{{ constructor.constructor('alert("Hacked!")')() }}
This executes JavaScript in the browser, leading to code execution.
Exploiting ng-bind & Event Handlers
Using ng-bind
can also be dangerous if user input is directly inserted:
<p ng-bind="userInput"></p>
Payload:
constructor.constructor('alert("Hacked!")')()
Similarly, event-based directives (ng-click
, ng-mouseover
, etc.) are vulnerable:
<button ng-click="userInput">Click Me</button>
If userInput
contains:
alert('Hacked!')
Clicking the button triggers arbitrary JavaScript execution.
3. Real-World Attack Scenarios
Scenario 1: Injecting JavaScript Code via Query Parameters
A website displays usernames using AngularJS:
<p>{{ $location.search().username }}</p>
An attacker crafts a URL:
https://example.com/?username={{constructor.constructor('alert("Hacked!")')()}}
When a victim visits the link, AngularJS evaluates the expression and executes alert("Hacked!")
.
4. Preventing AngularJS Expression Injection
1. Use ng-bind Instead of Curly Braces {{ }}
<p ng-bind="user.name"></p>
This prevents direct evaluation of injected expressions.
2. Use $sce.trustAsHtml
with Caution
AngularJS provides $sce.trustAsHtml()
for handling HTML safely.
$scope.safeHTML = $sce.trustAsHtml("<b>Safe Content</b>");
However, do not use this for user input unless sanitized.
3. Disable Automatic Expression Evaluation ($parse
)
In AngularJS versions before 1.6, expressions were evaluated automatically. To disable this, set:
$interpolateProvider.startSymbol('{[').endSymbol(']}');
This changes the default expression syntax from {{ }}
to {[ ]}
, preventing unwanted execution.
4. Use Content Security Policy (CSP)
Configure CSP to block inline JavaScript execution:
Content-Security-Policy: default-src 'self'; script-src 'self';
5. Upgrade to a Modern Framework (Angular 2+ or React)
Since AngularJS is deprecated, migrating to a more secure framework eliminates these risks.