Hashing Log Fields in Nginx with njs: A Practical Guide
Security is paramount, and often involves obfuscating sensitive data. This article explores how to use Nginx's JavaScript engine (njs) to hash log fields, particularly the http_authorization
header, for enhanced security.
The Problem: Nginx's js_set
directive requires synchronous code, while njs's crypto.subtle.digest
for SHA-512 hashing is asynchronous. This creates a conflict, making it challenging to replace a log field with its hash.
Solution: While directly using js_set
with asynchronous functions isn't feasible, we can leverage the power of asynchronous programming to achieve the desired result.
Here's a breakdown of the solution, based on insights from Stack Overflow:
-
Embrace Asynchronous Nature: We can wrap the asynchronous hashing operation within a Promise, ensuring the code flow continues while the hashing process completes in the background.
-
Nginx Configuration: Modify your
nginx.conf
to utilize the asynchronous function. The following snippet demonstrates this:js_import obfuscate.js; log_format main escape=json '{' '"http_authorization":"$obfuscated_token",' '}'; location / { js_set $obfuscated_token obfuscate.get_obfuscated_token($http_authorization); access_log /var/log/nginx/access.log main; }
-
JavaScript Code: Implement the SHA-512 hashing in your
obfuscate.js
file. The provided code below handles the hashing and returns the hexadecimal representation of the hash:async function get_obfuscated_token(token) { const encoder = new TextEncoder(); const msgUint8 = encoder.encode(token); const digest = await crypto.subtle.digest("SHA-512", msgUint8); const hashArray = Array.from(new Uint8Array(digest)); const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join(''); return hashHex; }
Explanation:
- The
get_obfuscated_token
function accepts thehttp_authorization
header as input. - It converts the header string to a Uint8Array using
TextEncoder
. - The
crypto.subtle.digest
function performs the SHA-512 hashing asynchronously, returning a Promise. - The Promise resolves with the hash digest, which is then converted to a hexadecimal representation.
- The hexadecimal hash is returned, replacing the original
http_authorization
value.
Additional Considerations:
- Performance: While the asynchronous approach is elegant, it may impact performance slightly. Consider profiling your application to assess any potential bottlenecks.
- Error Handling: Implement robust error handling within your
get_obfuscated_token
function to catch potential failures during hashing.
Conclusion: By harnessing the power of asynchronous programming and njs, you can effectively hash sensitive log fields like http_authorization
in your Nginx configurations. This solution improves security while maintaining the desired functionality, demonstrating the flexibility and power of njs for customizing your web server.
Attribution:
- This article draws inspiration from the Stack Overflow answer provided by "David Maze" (https://stackoverflow.com/a/75009510/15766285).