replaced rand() with cryptographically secure alternative
This commit is contained in:
parent
17b3c309fe
commit
a5cf07a181
|
@ -1,14 +1,14 @@
|
|||
from alpine:latest
|
||||
|
||||
run apk add wget gnupg sqlite build-base perl perl-dev perl-app-cpanminus
|
||||
run cpanm --notest IPC::Run DBD::SQLite Net::DNS::Resolver Crypt::Eksblowfish::Bcrypt JSON URI::Escape HTML::Entities String::ShellQuote Net::Server HTTP::Server::Simple
|
||||
run apk add wget gnupg sqlite unzip build-base perl perl-dev perl-app-cpanminus
|
||||
run cpanm --notest IPC::Run DBD::SQLite Net::DNS::Resolver Crypt::Eksblowfish::Bcrypt JSON URI::Escape HTML::Entities String::ShellQuote Net::Server HTTP::Server::Simple Crypt::Random
|
||||
|
||||
run mkdir -p /opt/data/plans
|
||||
copy schema.sql /opt/data
|
||||
run cat /opt/data/schema.sql | sqlite3 /opt/data/users.db
|
||||
run rm /opt/data/schema.sql
|
||||
|
||||
run apk del build-base perl-dev perl-app-cpanminus wget sqlite
|
||||
run apk del build-base perl-dev perl-app-cpanminus wget sqlite unzip
|
||||
|
||||
copy server.pl /opt
|
||||
workdir /opt
|
||||
|
|
32
server.pl
32
server.pl
|
@ -55,6 +55,7 @@ if (defined $ENV{'LOCAL_DOMAINS'}) {
|
|||
use File::Temp qw(tempfile);
|
||||
use Fcntl qw(:flock);
|
||||
use Net::DNS::Resolver;
|
||||
use Crypt::Random qw(makerandom_itv);
|
||||
use Crypt::Eksblowfish::Bcrypt qw(bcrypt_hash en_base64);
|
||||
use MIME::Base64 qw(decode_base64);
|
||||
use POSIX qw(strftime);
|
||||
|
@ -92,7 +93,7 @@ if (defined $ENV{'LOCAL_DOMAINS'}) {
|
|||
sub handle_request {
|
||||
my ($self, $cgi) = @_;
|
||||
# assign a random request id for anonymous logging
|
||||
my $req_id = util_req_id();
|
||||
my $req_id = util_token(12);
|
||||
$cgi->param('request_id', $req_id);
|
||||
my $path = $cgi->path_info();
|
||||
my $method = $cgi->request_method();
|
||||
|
@ -206,7 +207,7 @@ EOF
|
|||
: "INSERT INTO users (password, pw_token, pw_token_expires, email) values (?, ?, datetime('now', '+$pw_token_expiration_minutes minutes'), ?)";
|
||||
my $crypted = util_bcrypt($password);
|
||||
my $sth = util_get_dbh()->prepare($query);
|
||||
$sth->execute($crypted, util_token(), $email);
|
||||
$sth->execute($crypted, util_token(24), $email);
|
||||
die $sth->errstr if $sth->err;
|
||||
# TODO: send email
|
||||
print_json_response($cgi, 200, {email => $email});
|
||||
|
@ -244,10 +245,10 @@ EOF
|
|||
print_response($cgi, 401, $not_authorized);
|
||||
} else {
|
||||
my $sth = util_get_dbh()->prepare("UPDATE users SET token=?, token_expires=datetime('now', ?) WHERE email=?");
|
||||
my $token = util_token();
|
||||
my $token = util_token(24);
|
||||
my $expires = $cgi->param('expires');
|
||||
my $minutes = $auth_token_default_expiration_minutes;
|
||||
if ($expires =~ /^\d+$/) {
|
||||
if (defined $expires && $expires =~ /^\d+$/) {
|
||||
$minutes = int($expires);
|
||||
if ($minutes <= 0) {
|
||||
$minutes = $auth_token_default_expiration_minutes;
|
||||
|
@ -282,7 +283,7 @@ EOF
|
|||
} elsif (defined $user->{'pw_token_expires'} && $user->{'pw_token_expires'} >= time) {
|
||||
print_json_response($cgi, 429, {error => "Wait $pw_token_expiration_minutes between this type of request."});
|
||||
} else {
|
||||
my $token = util_token();
|
||||
my $token = util_token(24);
|
||||
my $sth = util_get_dbh()->prepare("UPDATE users SET pw_token=?, pw_token_expires=datetime('now', '+10 minutes') WHERE email=?");
|
||||
$sth->execute($token, $email);
|
||||
die $sth->errstr if $sth->err;
|
||||
|
@ -426,7 +427,7 @@ EOF
|
|||
my $msg = shift;
|
||||
my $timestamp = strftime("%Y-%m-%d %H:%M:%S", localtime(time()));
|
||||
if (!defined $_log) {
|
||||
open($_log, '>>', $log_file);
|
||||
open($_log, '>>', $log_file) or die $!;
|
||||
binmode($_log, ':unix');
|
||||
}
|
||||
print $_log "$timestamp $msg\n";
|
||||
|
@ -470,7 +471,7 @@ EOF
|
|||
sub util_salt {
|
||||
my $itoa64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
my $salt = '';
|
||||
$salt .= substr($itoa64,int(rand(64)),1) while length($salt) < 16;
|
||||
$salt .= substr($itoa64,int(makerandom_itv(Strength => 0, Upper => 64)),1) while length($salt) < 16;
|
||||
return $salt;
|
||||
}
|
||||
|
||||
|
@ -504,20 +505,13 @@ EOF
|
|||
|
||||
# generate an authorization token
|
||||
sub util_token {
|
||||
my $itoa62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
my $length = shift;
|
||||
my $chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
my $token = '';
|
||||
$token .= substr($itoa62,int(rand(62)),1) while length($token) < 24;
|
||||
$token .= substr($chars,int(makerandom_itv(Strength => 0, Upper => 62)),1) while length($token) < $length;
|
||||
return $token;
|
||||
}
|
||||
|
||||
# generate a random request id
|
||||
sub util_req_id {
|
||||
my $itoa36 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||
my $id = '';
|
||||
$id .= substr($itoa36,int(rand(36)),1) while length($id) < 8;
|
||||
return $id;
|
||||
}
|
||||
|
||||
# get a user from the database by email
|
||||
sub util_get_user {
|
||||
my $email = shift;
|
||||
|
@ -564,7 +558,7 @@ EOF
|
|||
|
||||
if (-f "$basename.plan") {
|
||||
my $details = {};
|
||||
open(my $plan_file, '<', "$basename.plan");
|
||||
open(my $plan_file, '<', "$basename.plan") or die $!;
|
||||
flock($plan_file, LOCK_SH);
|
||||
my $mtime = (stat($plan_file))[9];
|
||||
my $timestamp = strftime("%a, %d %b %Y %H:%M:%S %z", localtime($mtime));
|
||||
|
@ -574,7 +568,7 @@ EOF
|
|||
close($plan_file);
|
||||
|
||||
if (-f "$basename.asc") {
|
||||
open(my $sig_file, '<', "$basename.asc");
|
||||
open(my $sig_file, '<', "$basename.asc") or die $!;
|
||||
flock($sig_file, LOCK_SH);
|
||||
local $/;
|
||||
$details->{'signature'} = <$sig_file>;
|
||||
|
|
|
@ -108,7 +108,7 @@ if [ -z "$USE_DOCKER" ]; then
|
|||
DATABASE="$BASEDIR/data/test.db" \
|
||||
PLAN_DIR="$BASEDIR/data/plans" \
|
||||
SENDMAIL=/usr/bin/true \
|
||||
perl "$BASEDIR/../server.pl" -d >>/dev/null 2>>/dev/null
|
||||
perl "$BASEDIR/../server.pl" -d >>/dev/null
|
||||
else
|
||||
docker build -t dotplan-online-test "$BASEDIR/.."
|
||||
docker run --name dotplan_online_test -d --rm \
|
||||
|
|
Reference in New Issue