When building web applications, it is important to handle sensitive data with care to avoid exposing it to malicious attacks or unauthorized access. Storing sensitive information, such as authentication tokens, user data, or session details, in cookies is a common practice for maintaining state across requests. However, cookies are inherently insecure since they are stored in plain text and can be intercepted by malicious actors if not properly encrypted.
In this guide, we will explore how to encrypt sensitive data before storing it in cookies in AngularJS, and how to securely decrypt and retrieve that data when needed.
Why Encrypt Cookies?
Cookies are easily accessible by the client-side JavaScript, meaning if sensitive data is stored in a cookie, it can be read by anyone with access to the browser’s developer tools. To mitigate the risk of data exposure or tampering, it is crucial to encrypt any sensitive data before storing it in a cookie. Encrypting the data ensures that even if the cookie is intercepted or accessed by unauthorized parties, the sensitive information remains secure.
Here are the main reasons to encrypt data before storing it in cookies:
- Confidentiality: Encryption ensures that sensitive information like authentication tokens, user credentials, or session data is unreadable to anyone who intercepts the cookie.
- Data Integrity: Encryption can protect against tampering, ensuring that the data has not been altered.
- Security: It adds an additional layer of security, especially in environments with potentially unsafe networks (e.g., public Wi-Fi).
Step 1: Choose an Encryption Library
In AngularJS, the native JavaScript API does not provide encryption out-of-the-box. To encrypt and decrypt data, we need to use an encryption library such as CryptoJS.
CryptoJS is a popular JavaScript library for encryption and hashing. It supports various encryption algorithms, such as AES, DES, and Triple DES.
- Install CryptoJS: If you’re using npm, you can install it as follows: bashCopyEdit
npm install crypto-js
If you’re using a CDN, you can include CryptoJS directly in your HTML:<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1-crypto-js.js"></script>
- Include CryptoJS in Your AngularJS Application: After adding the library, include it in your AngularJS module as follows:
<script src="path-to-crypto-js/crypto-js.js"></script>
Step 2: Encrypt Data Before Storing in Cookies
Now that you have CryptoJS available, you can use it to encrypt the data before storing it in a cookie.
Example: Encrypting Sensitive Data
Let’s assume that you’re storing a JWT token in a cookie. You would first encrypt it and then store it in a cookie.
- Encryption Function:
angular.module('app')
.factory('cookieService', function($cookies) {
// Encryption key (must be kept secret)
const ENCRYPTION_KEY = 'my-secret-key';
return {
// Function to set an encrypted cookie
setEncryptedCookie: function(cookieName, data) {
// Encrypt the data using AES algorithm
const encryptedData = CryptoJS.AES.encrypt(JSON.stringify(data), ENCRYPTION_KEY).toString();
// Store the encrypted data in a cookie
$cookies.put(cookieName, encryptedData);
},
// Function to get the decrypted cookie
getDecryptedCookie: function(cookieName) {
const encryptedData = $cookies.get(cookieName);
if (encryptedData) {
// Decrypt the data using AES algorithm
const bytes = CryptoJS.AES.decrypt(encryptedData, ENCRYPTION_KEY);
const decryptedData = bytes.toString(CryptoJS.enc.Utf8);
try {
return JSON.parse(decryptedData);
} catch (e) {
console.error("Error parsing decrypted cookie", e);
return null;
}
}
return null;
},
// Function to remove a cookie
removeCookie: function(cookieName) {
$cookies.remove(cookieName);
}
};
});
In this example:
- The
setEncryptedCookie
function takes the data (e.g., JWT token) and encrypts it using the AES encryption algorithm from CryptoJS. It then stores the encrypted data in a cookie using$cookies.put()
. - The
getDecryptedCookie
function retrieves the encrypted cookie and decrypts it back to its original form. If the cookie doesn’t exist, it returnsnull
. - The
removeCookie
function is a utility to delete the cookie when it is no longer needed.
Step 3: Using the Encryption Service in Your Application
To use the encryption service, inject it into your AngularJS controller and store or retrieve the encrypted data as needed.
Example: Using the cookieService
to Store and Retrieve Data
angular.module('app')
.controller('AuthController', function($scope, cookieService) {
// Sample data to store in the cookie (e.g., JWT token)
const authToken = 'your-jwt-token-here';
// Encrypt and store the token in a cookie
cookieService.setEncryptedCookie('authToken', authToken);
// Retrieve and decrypt the token from the cookie
const decryptedToken = cookieService.getDecryptedCookie('authToken');
if (decryptedToken) {
console.log('Decrypted token:', decryptedToken);
} else {
console.log('No valid token found.');
}
});
Step 4: Implement Secure Cookie Handling (Optional)
When storing sensitive data in cookies, it’s essential to implement some best practices for cookie security:
- Secure Cookies: Ensure that cookies are sent over HTTPS by setting the
Secure
flag. This ensures that cookies are only transmitted over secure channels (i.e., HTTPS). - HTTPOnly Cookies: To prevent access to cookies via JavaScript, set the
HttpOnly
flag. This ensures that the cookies cannot be accessed through client-side scripts (e.g., by XSS attacks). - SameSite Cookies: Set the
SameSite
flag to prevent cross-site request forgery (CSRF) attacks. This restricts how cookies are sent with cross-site requests.
Example of setting these options in AngularJS:
angular.module('app')
.config(function($cookiesProvider) {
// Set cookie options for security
$cookiesProvider.defaults.secure = true;
$cookiesProvider.defaults.httpOnly = true;
$cookiesProvider.defaults.samesite = 'Strict'; // Or 'Lax' based on use case
});
Step 5: Test the Encryption and Decryption
Ensure that the encryption and decryption work properly:
- Store sensitive data in a cookie using the
cookieService
. - Verify that the cookie contains an encrypted value (you can inspect the cookie in your browser’s developer tools).
- Retrieve and decrypt the cookie to ensure that the data is correct.