bachoA4o has asked for the wisdom of the Perl Monks concerning the following question:

Hello I'm making a a form that create a user with username and password and then crypts the data and store it in database ; password crypting is working fine i think but stores the name as CGI::Simple=HASH(0x55bb333591e0). Here is the code for creating the user:
#!/usr/bin/perl use strict; use warnings; use DBI; use CGI::Simple; use Crypt::Argon2 qw/argon2id_pass argon2id_verify/; sub user_crypt;sub createUser; sub user_crypt { my ($cryUser , $cryPass)=@_; my $salt = rand(16); my $encode = argon2id_pass($cryPass,$salt,3,'32M',1,16); createUser($cryUser,$encode); } sub createUser{ my ($user , $hashPass)=@_; my $statement="INSERT INTO LOGIN_DATA(USER_NAME,USER_HASH) VALUES(?,?) +"; my $driver="mysql"; my $database="USERS"; my $dsn="DBI:$driver:database=$database"; my $databaseUser="root"; my $databasePass=""; my $dbcon= DBI->connect($dsn,$databaseUser,$databasePass) or die $!; my $preState = $dbcon->prepare($statement) ; $preState->execute($user , $hashPass) or die $!; } my $username=CGI::Simple->new; my $pass=CGI::Simple->new; $username->param('textfield'); $pass->param('pass'); user_crypt($username,$pass); print "Content-type: text/html\n\n"; print "<html><body>\n"; print "<h1>Random heading</h1>\n"; print "$username , $pass"; print "</body></html>\n";
and this is how is stored in the database
CGI::Simple=HASH(0x55bb333591e0) | $argon2id$v=19$m=32768,t=3,p=1$MTMu +ODI1NjU0MDY4Mjc3OQ$V83Q4GNnwnY1187C/whS/Q
and after the program that verifies but of course it's not working because don`t know how to fetch the username .
#!/usr/bin/perl use strict; use warnings; use Crypt::Argon2 qw/argon2id_pass argon2id_verify/; use DBI; sub get_data; sub chec_pass; sub get_data{ my ($user , $hash_pass); my $statement = "SELECT * FROM LOGIN_DATA"; my $driver = "mysql"; my $database = "USERS"; my $dsn = "DBI:$driver:database=$database"; my $dataUsr = "root"; my $dataPass = ""; my $dbcon = DBI->connect($dsn,$dataUsr,$dataPass) or die $!; my $preState = $dbcon->prepare($statement); $preState->execute(); my @row; while (@row = $preState->fetchrow_array()) { } } sub chec_pass { my ($user, $password) = @_; my $encoded = fetch_encoded($user); return argon2id_verify($encoded , $password); }

Replies are listed 'Best First'.
Re: Login form
by Your Mother (Archbishop) on Sep 18, 2018 at 06:45 UTC

    The CGI::Simple object is not the parameter but you’re treating it like it is–

    perl -MCGI::Simple -E 'my $pass = CGI::Simple->new; $pass->param("pass +"); say $pass' CGI::Simple=HASH(0x7f8af5002ee8)

    You want something more like–

    my $cgi = CGI::Simple->new; my $pass = $cgi->param("pass"); say $pass;
Re: Login form
by Athanasius (Archbishop) on Sep 18, 2018 at 06:48 UTC

    Hello bachoA4o,

    my $username=CGI::Simple->new; my $pass=CGI::Simple->new; $username->param('textfield'); $pass->param('pass');

    This creates two uninitialised CGI::Simple objects and then reads the (non-existent) fields 'textfield' and 'pass' — it doesn’t write them. You need something like this:

    my $username = 'Fred'; my $password = 'Flintstone123'; my $cgi = CGI::Simple->new( { username => $username, pass => $pa +ssword } ); user_crypt($cgi);

    and then sub user_crypt would be implemented as:

    sub user_crypt { my ($cgi) = @_; my $cryUser = $cgi->param('username'); my $cryPass = $cgi->param('pass'); my $salt = rand(16); my $encode = argon2id_pass($cryPass, $salt, 3, '32M', 1, 16); createUser($cryUser, $encode); }

    BTW, there is no need to pre-declare your subroutines.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Login form
by hippo (Archbishop) on Sep 18, 2018 at 08:37 UTC

    Since you've already received wisdom from Your Mother and Athanasius on the problem at hand, here are 2 quick tips to stop your server getting compromised.

    1. Never do my $databaseUser="root"; in a CGI script or really any script run by an unprivileged user. Set up a dedicated db user for the task at hand and use that in your script instead - it only takes 10 seconds to do but could save you weeks of clean-up in the event of an attack. Set up a second dedicated user with read-only privs too for such scripts that require it such as your second one above.
    2. Always use taint mode with CGI. This is especially important when interacting with other back-end systems such as a database but is good practice anyway to prevent injection attacks against the shell, net protocols, databases, etc.

    These things may seem like a hassle now but if you don't use them and your system becomes compromised you will surely wish you had. Good luck.

Re: Login form
by poj (Abbot) on Sep 18, 2018 at 11:23 UTC
    my $salt = rand(16);

    This creates a floating point number occasional with a length less than 8 which caused this error
    Couldn't compute argon2id tag: Salt is too short.

    There are various ways to create a random string of fixed length ( see Random string generator ) . A simple one is

    my @chars = ("A".."Z", "a".."z",0..9); my $salt = join '', map{ $chars[rand @chars] } 0..15;
    poj