AngularJS applications are vulnerable to injection attacks like Cross-Site Scripting (XSS), SQL Injection, and Dependency Injection attacks. These vulnerabilities can allow attackers to manipulate data, execute arbitrary code, or gain unauthorized access to sensitive information.
This guide will cover:
- Understanding Injection Attacks in AngularJS
- Preventing Cross-Site Scripting (XSS)
- Securing Against SQL Injection
- Mitigating Dependency Injection Attacks
- Preventing Server-Side Injection Attacks
- Implementing Content Security Policy (CSP)
- Using Security Best Practices in AngularJS
- Testing and Debugging Security Issues
1. Understanding Injection Attacks in AngularJS
Injection attacks occur when an attacker inserts malicious code into an application, often through user input fields, HTTP requests, or external dependencies. The most common types include:
- XSS (Cross-Site Scripting): Injects JavaScript into the web page to execute unauthorized actions.
- SQL Injection: Injects SQL queries into database interactions to extract or manipulate data.
- Dependency Injection Attacks: Manipulates AngularJS services to override application behavior.
- Server-Side Injection Attacks: Targets backend services via API calls.
Example of an Injection Attack
A hacker may enter the following in an input field:
<script>alert('Hacked!');</script>
If improperly handled, this script could execute when displayed, leading to XSS attacks.
2. Preventing Cross-Site Scripting (XSS)
Use $sanitize
to Remove Malicious HTML
AngularJS provides the $sanitize
service in the ngSanitize
module to clean user input.
app.controller('MainController', function($scope, $sanitize) {
$scope.userInput = "<script>alert('XSS!');</script><b>Safe Bold Text</b>";
$scope.sanitizedInput = $sanitize($scope.userInput);
});
<p ng-bind-html="sanitizedInput"></p>
Removes dangerous scripts while keeping safe HTML elements.
Use $sce.trustAsHtml()
with Caution
AngularJS enforces strict contextual escaping (SCE), which blocks potentially dangerous content.
If you must allow raw HTML, ensure the data source is trusted.
app.controller('MainController', function($scope, $sce) {
$scope.safeHTML = $sce.trustAsHtml('<b>Safe</b>'); // Use only on trusted data
});
<p ng-bind-html="safeHTML"></p>
Avoid using $sce.trustAsHtml()
for user input to prevent XSS attacks.
3. Securing Against SQL Injection
SQL Injection occurs when an attacker manipulates database queries.
Vulnerable API Call:
$http.get('/getUser?username=' + userInput);
If userInput
contains:
' OR '1'='1
The backend may return all user records, causing a data breach.
Best Practice: Always use parameterized queries:
$http.get('/getUser', { params: { username: userInput } });
On the backend, use prepared statements:
SELECT * FROM users WHERE username = ?;
Prevents attackers from injecting SQL commands.
4. Mitigating Dependency Injection Attacks
AngularJS uses dependency injection (DI) to manage services.
If an attacker overrides built-in services like $http
, it can lead to code execution vulnerabilities.
Vulnerable Code:
app.controller('MainController', function($scope, $injector) {
var evil = $injector.get('evilService'); // If 'evilService' is injected, attacker gains control
});
Preventing DI Attacks:
- Use minification-safe dependency injection:
app.controller('MainController', ['$scope', function($scope) {
// Secure Dependency Injection
}]);
- Restrict service overrides using
$provide.decorator
:
app.config(function($provide) {
$provide.decorator('$http', function($delegate) {
return $delegate; // Prevent overriding $http
});
});
Ensures only trusted dependencies are injected.
5. Preventing Server-Side Injection Attacks
Backend APIs should enforce proper validation to reject malicious requests.
Best Practices
Validate all incoming data on the server
if (!isValidInput(req.body.username)) {
return res.status(400).send("Invalid input");
}
Use CORS with strict policies
app.use(cors({ origin: 'https://trusted-site.com' }));
Escape special characters in user input
var escapedInput = input.replace(/</g, "<").replace(/>/g, ">");
Restrict API access using authentication (JWT, OAuth)
6. Implementing Content Security Policy (CSP)
A Content Security Policy (CSP) restricts inline scripts and external resource loading.
Example CSP Header in Server Configuration
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline';
Blocks malicious scripts injected by attackers.
Prevents execution of unauthorized inline scripts.
7. Using Security Best Practices in AngularJS
1️⃣ Avoid Using eval()
eval()
can execute arbitrary JavaScript, making it highly dangerous. ❌ Never do this:
$scope.result = eval($scope.userInput);
Use JSON parsing instead:
$scope.result = JSON.parse($scope.userInput);
2️⃣ Enable Strict Dependency Injection
app.controller('MainController', ['$scope', function($scope) { }]);
Prevents attackers from injecting malicious dependencies.
3️⃣ Use $http.defaults
for Secure API Calls
app.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
}]);
Prevents Cross-Site Request Forgery (CSRF) attacks.
8. Testing and Debugging Security Issues
1️⃣ Scan for XSS with Chrome DevTools
- Open Developer Console (
F12
). - Go to Console → Enter:
angular.element(document.body).scope().userInput = '<script>alert("XSS");</script>';
- If XSS executes, the input field is vulnerable.
2️⃣ Run Security Audits with OWASP ZAP
- OWASP ZAP automatically detects vulnerabilities in AngularJS applications.
3️⃣ Use $exceptionHandler
for Error Logging
app.factory('$exceptionHandler', function() {
return function(exception, cause) {
console.error('Error:', exception, 'Cause:', cause);
};
});
Logs unexpected errors, helping identify security issues.