Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Security using Encrypted cookies

by mkirank (Chaplain)
on Feb 16, 2003 at 11:45 UTC ( #235708=perlquestion: print w/replies, xml ) Need Help??
mkirank has asked for the wisdom of the Perl Monks concerning the following question:

Hi Fellow Monks, I am developing a script which is displayed after completion of payment process (the payment site calls my url with certain parameters),i verify that the payment got through and then i display a link for download of an exe file ,What i do is after verification i encrypt a cookie and then i display a html page with a link (which is another perl script).when that link is clicked i check for the cookie and then force download the exe ... is this safe ???or is there any better way of doing this ..and what is the best way of encrypting the cookie I use Crypt::CBC but it is a bit of problem installing These on windows machine also i have attached the module that is done by looking at an example in the mod_perl eagle book ..
package Auth; use CGI qw(:standard); use CGI::Cookie (); use MD5 (); use Crypt::CBC (); use constant COOKIE_NAME => 'Cname'; use constant SECRET => '0mn1um ex 0vum'; $CIPHER ||= Crypt::CBC->new(SECRET, 'IDEA'); sub set_cookie { my $usrname=shift; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time +); $year = $year + 1900; $mon++; my $time = "$year$mon$mday$hour$min$sec"; $state=initialize($state,$time,$usrname); print header(-cookie => save_state($state)); } sub initialize { my $state = shift; my $time=shift; my $usrname=shift; $state = {} unless $state; $state->{TIME} =$time ; $state->{USRNAME} = $usrname; return $state; } # Check or generate the MAC authentication information sub MAC { my($state, $action) = @_; return undef unless ref($state); my @fields = @{$state}{qw(TIME USRNAME)}; my ($newmac) = MD5->hexhash(SECRET . MD5->hexhash(join '', SECRET, @fields)); return $newmac eq $state->{MAC} if $action eq 'check'; return $state->{MAC} = $newmac if $action eq 'generate'; undef; } # Save the current state sub save_state { my $state = shift; MAC($state, 'generate'); # add MAC to the state # encrypt the cookie my $encrypted = $CIPHER->encrypt_hex(join ':', %{$state}); return CGI::Cookie->new(-name => COOKIE_NAME, -value => $encrypted, ); } # Retrieve an existing state sub get_state { my $cookie = CGI::cookie(COOKIE_NAME); return undef unless $cookie; # decrypt the cookie my %state = split ':', $CIPHER->decrypt_hex($cookie); authentication_error() unless MAC(\%state, 'check'); return \%state; } sub authentication_error { print"<h4> Authentication error </h4>"; } 1;

Replies are listed 'Best First'.
Re: Security using Encrypted cookies
by Cabrion (Friar) on Feb 16, 2003 at 14:01 UTC
    You shouldn't be sending encrypted cookies. You should use session variables instead. Then you can keep the "secret" data on the server side.

    merlyn has a good article on the subject of cookies. Chek out his home page.

Re: Security using Encrypted cookies
by fokat (Deacon) on Feb 16, 2003 at 14:08 UTC

    I take from your description, that you are somehow selling the software. All it takes to break your scheme, is getting the crypted cookie from another user.

    I believe this is slightly harder than your user simply giving the software away to another person directly, so I would say this is ok 99.5% of the time...

    If this worries too much, here's a simple way to cope with it, assuming that you have the source code of the .EXE you're selling. This is in addition to what you already done.

    • Place some sort of char * placeholder in your code along the lines of:

       char *replace_me = "____REPLACE_ME_WITH_THE_MAGIC_KEY___";
    • Compile this code and store the resulting .EXE in a file, say, unsigned.exe

    • When generating the download page, grab unsigned.exe with a Perl script and write it to some semi-random name, replacing the string ____REPLACE_ME_WITH_THE_MAGIC_KEY___ with a string with exactly the same length (or shorter but padded with \0s), containing the customer-id or some other number that allows you to track the user.

    It then becomes a matter of checking this number in the .EXE to know who leaked his/her copy. You can also have more elaborate schemes, placing an encrypted number in there and having the code decrypt and print such number at runtime.

    Of course, all this can be easily defeated if the attacker can disassemble your code...

    Best regards

    -lem, but some call me fokat

Re: Security using Encrypted cookies
by dws (Chancellor) on Feb 16, 2003 at 17:35 UTC
    As fokat notes, anyone who gets their hands on the cookie, encrypted or not, can defeat your scheme.

    You can mitigate the risk by timing out the cookie. You're already embedding a timestamp, though the timestamp would be easier to check if you embedded a raw time() value, rather than splitting it via localtime().

    For real security, though, you should be doing this over https:

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://235708]
Approved by BazB
and God said, "Let Newton be!"...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (6)
As of 2017-04-29 12:56 GMT
Find Nodes?
    Voting Booth?
    I'm a fool:

    Results (531 votes). Check out past polls.