Skip to main content

Insecure functionality - Masking

Need

Secure data masking

Context

  • Usage of Dart 2.0 for building high-performance, cross-platform applications
  • Usage of Shelf for managing and organizing data in Node.js applications

Description

Non compliant code

import 'package:shelf/shelf.dart' as shelf;

shelf.Response handleRequest(shelf.Request request) {
var user = request.headers['user'];
var password = request.headers['password'];

// Do something with user and password

return shelf.Response.ok('Request handled.');
}

void main() {
var handler = const shelf.Pipeline().addMiddleware(shelf.logRequests()).addHandler(handleRequest);

shelf.serve(handler, 'localhost', 8080).then((server) {
print('Serving at http://${server.address.host}:${server.port}');
});
}

In the above code, the handleRequest function is handling the incoming request. It retrieves the 'user' and 'password' from the request headers and then processes them. This is a security vulnerability because the sensitive information like 'user' and 'password' are being transferred in plain text format within the headers of the request.

This is an insecure functionality as the sensitive data is not being masked or encrypted in any way. Anyone who is able to intercept this request would be able to see this information. This could potentially lead to unauthorized access to the system if the intercepted credentials are valid.

Moreover, the server logs all the requests including their headers using shelf.logRequests() middleware. This means that the sensitive data (user and password) are being stored in the server logs in plain text format. Again, this is a security vulnerability as anyone with access to these logs would be able to retrieve this sensitive information.

To fix this vulnerability, the sensitive data should be masked or encrypted before being sent in the request and/or response. The server should also be configured to not log sensitive information.

Steps

  • Avoid passing sensitive information like username and password in the request headers. Use secure methods like POST for sending such data.
  • Implement SSL/TLS to encrypt the data during transmission. This will ensure that even if someone intercepts the data, they won't be able to understand it.
  • Use a secure method for storing passwords. Never store passwords in plain text. Use hashing algorithms like bcrypt to store passwords.
  • Implement proper access controls to ensure that only authorized users can access sensitive data.
  • Use a secure session management system. This will ensure that even if a user's session is hijacked, the attacker won't be able to access sensitive data.
  • Implement proper error handling. Never reveal sensitive information in error messages.
  • Regularly update and patch your systems to protect against known vulnerabilities.

Compliant code

import 'dart:convert';
import 'package:shelf/shelf.dart' as shelf;
import 'package:crypto/crypto.dart';

shelf.Response handleRequest(shelf.Request request) async {
if (request.method != 'POST') {
return shelf.Response.forbidden('Forbidden');
}

var body = await request.readAsString();
var data = jsonDecode(body);
var user = data['user'];
var password = data['password'];

// Hash the password
var bytes = utf8.encode(password);
var digest = sha256.convert(bytes);

// Do something with user and hashed password

return shelf.Response.ok('Request handled.');
}

void main() {
var handler = const shelf.Pipeline().addMiddleware(shelf.logRequests()).addHandler(handleRequest);

shelf.serve(handler, 'localhost', 8080).then((server) {
print('Serving at http://${server.address.host}:${server.port}');
});
}

The updated code now uses the POST method to receive sensitive data such as username and password. This is a more secure method than passing such data in the request headers. The data is read from the request body and then parsed as JSON.

The password is then hashed using the SHA-256 algorithm from the crypto package. This ensures that the password is not stored or handled in plain text, which is a major security vulnerability. Instead, a hashed version of the password is used, which can't be reversed to get the original password.

The code also checks if the request method is POST, and if it's not, it returns a 403 Forbidden response. This is a simple form of access control, ensuring that only requests with the correct method can proceed.

Please note that this code does not include SSL/TLS implementation, session management, error handling, and system patching. These are important security measures that should be implemented in a real-world application, but they are beyond the scope of this code snippet.

References