Secure generation and transmission of OTP tokens
import 'package:shelf/shelf.dart' as shelf;
import 'dart:math';
shelf.Response handleRequest(shelf.Request request) {
var params = request.url.queryParameters;
var phoneNumber = params['phoneNumber'];
var OTP = generateOTP();
// Send OTP to client
return shelf.Response.ok('OTP: $OTP');
}
String generateOTP() {
var rng = new Random();
return List.generate(6, (_) => rng.nextInt(9)).join();
}
In the above code, we have a function
handleRequest(shelf.Request request)
that handles incoming requests. Inside this function, we extract the phone number from the request query parameters and generate an OTP (One-Time Password).
The OTP is generated using the function
generateOTP()
, which creates a 6 digit random number. This OTP is then sent back to the client in the response.
The vulnerability lies in the fact that the OTP is generated on the server-side and sent to the client-side. This means that if an attacker intercepts the request, they can easily access the OTP and continue the application flow without needing access to the actual phone number used.
This is a serious security flaw as OTPs are meant to provide a second layer of security by requiring users to have access to a specific device (in this case, a phone). By allowing the OTP to be intercepted, this layer of security is effectively bypassed.
import 'package:shelf/shelf.dart' as shelf;
import 'dart:math';
import 'package:shelf_session/shelf_session.dart';
import 'package:sms_maintained/sms.dart';
// Create a session middleware
var sessionMiddleware = SessionMiddleware(
SessionConfig(
sessionKey: 'session',
),
);
// Create a session handler
var handler = const shelf.Pipeline()
.addMiddleware(sessionMiddleware)
.addHandler(_handleRequest);
shelf.Response _handleRequest(shelf.Request request) {
var session = Session.fromRequest(request);
var params = request.url.queryParameters;
var phoneNumber = params['phoneNumber'];
// Generate OTP
var OTP = _generateOTP();
// Store OTP in session
session['OTP'] = OTP;
// Send OTP to user's phone number
_sendOTP(phoneNumber, OTP);
// Do not send OTP in response
return shelf.Response.ok('OTP sent to your phone number');
}
String _generateOTP() {
var rng = new Random();
return List.generate(6, (_) => rng.nextInt(9)).join();
}
void _sendOTP(String phoneNumber, String OTP) {
SmsSender sender = new SmsSender();
SmsMessage message = new SmsMessage(phoneNumber, 'Your OTP is: $OTP');
sender.sendSms(message);
}
The code above fixes the vulnerability by moving the OTP generation to the server-side and sending it directly to the user's phone number using an SMS gateway service.
The OTP is generated using the
_generateOTP
function, which generates a random 6-digit number. This OTP is then stored in a server-side session using the
shelf_session
package. The session is associated with the user's request, allowing the OTP to be stored securely and associated with the user's session or phone number.
The OTP is then sent to the user's phone number using the
_sendOTP
function. This function uses the
sms_maintained
package to send an SMS to the user's phone number with the OTP.
The OTP is not included in the response sent back to the client, preventing it from being intercepted.
This code also sets up a session middleware and a session handler using the
shelf
and
shelf_session
packages. This allows the server to handle multiple sessions and store session data securely.
Please note that this code does not implement a time limit for the OTP, rate limiting, or HTTPS. These features should be implemented as well to further secure the OTP process.