Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

web cgi forms data security...

by noname00 (Novice)
on Dec 30, 2003 at 20:28 UTC ( [id://317769]=perlquestion: print w/replies, xml ) Need Help??

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

very good site.. nice job guys:)
i just came here so i hope to post on the right place :)

here is my problem...
i want to pass sensitive data through dynamic web pages.. that means that when the user logs in , some information including username and password must pass to the next web page created and so on..

i want the data passed to be encrypted and , if possible, encrypted in one string...
lets say , i have 2 variables $user,$pass
i want a function that will make this job :
$encrypted_string = some_encryption_method($key,$user,$pass);

then cgi "transmits" the data like this :
print "Location: next_page.cgi?code=$key";

then the data received from the next page must be decrypted and i want to have back my original data :
@mydata = some_decryption method($key,$code);

i want something like that..(if there is)
or if you have something else to propose you are more than welcome..
i just want the data given to be as secure as possible and to be encrypted when "traveling" around the site :)

thanx in advance ...

Replies are listed 'Best First'.
Re: web cgi forms data security...
by iburrell (Chaplain) on Dec 30, 2003 at 21:10 UTC
    There are three ways to do this: 1. Use SSL. Then just pass the sensitive parameters in the form and trust the encryption to keep them secure. Doesn't work with GET requests because the sensitive parameters show in the URL bar. If the initial posting of the values needs to be secure, then you need SSL anyway. This doesn't work if the sensitive parameters need to be concealed from the user because they could view source. 2. Use encryption to protect the parameters. Crypt::CBC is the generic interface. The server encrypts the data with its private key, passes the ciphertext as a cookie or form parameter, and then decodes it with the private key. 3. Store the values in the database or filesystem. Pass around the unique identifier to find the data in the database.
      thanx iburell :)

      i think i ll use your 3rd option since cookies aren't always enabled from users...
Re: web cgi forms data security...
by Art_XIV (Hermit) on Dec 30, 2003 at 21:31 UTC

    Suggestions that may or may not be applicable to your situation:

    1. Don't pass around data that you don't want users or baddies to see/access, or do it as little as possible. Not passing data is even more secure than 128-bit encryption.
    2. Sessions can be a nice place to park sensitive data. If you're unfamiliar with sessions, they're kind of like a hash that resides on the server(s) for a specific user. Several CPAN modules exist for managing sessions, or try a home-grown db-based one.
    3. POSTing your forms (instead of GETting them) will put nothing into the highly-visible querystrings.
    4. As b10m said, SSL is a very good way of foiling packet-sniffers, but it doesn't do squat if your problem is that you don't want users/baddies seeing indexes/keys in the querystrings in your source code. If this is the issue then you must resort to one of the encryption modules or some sort of lookup tables on the server. Even this can be less than foolproof, though. Imagine that I access the following (spuriously encrypted) url - "www.expensivepics.com/picserver.cgi?3RJHT=H5RTJ98" - and the next day I just paste the same url into my browser even though it's no longer supposed to be an option for me? Its 'So much for encryption' unless you've taken other measures.

    Update: Dang! iburrell said almost the same thing that I did mere minutes (twenty, but I'm a slow typer) before I finished with my comment. Sorry for the redundancy, all.

    Hanlon's Razor - "Never attribute to malice that which can be adequately explained by stupidity"
Re: web cgi forms data security...
by b10m (Vicar) on Dec 30, 2003 at 20:34 UTC

    To save you a lot of hassle, see if SSL is an option for you (most http daemons can handle it). This way, everything between the user and your server is encrypted, without you doing anything different :)

    --
    b10m

      SSL won't save you here. The user can still modify the parameters being passed on their end. With encrypted params, there's no way the user can know what chagnes they are making.

      Though it's probably better to do proper session management instead.

      ----
      I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
      -- Schemer

      : () { :|:& };:

      Note: All code is untested, unless otherwise stated

        noname00 "i just want the data given to be as secure as possible and to be encrypted when "traveling" around the site :)"
        b10m "see if SSL is an option for you"
        hardburn "SSL won't save you here.The user can still modify the parameters being passed on their end."

        Sorry, but I didn't get the part where the user shouldn't be allowed to change parameters. I figured the OP wanted a way to make sure the sensative data couldn't be snooped by others. Using SSL seems valid in this case, if you'd ask me. But please explain.

        And yes ... I should have suggested using the post method over the get method too.

        --
        b10m
Re: web cgi forms data security...
by hardburn (Abbot) on Dec 30, 2003 at 22:06 UTC

    Let CGI::EncryptForm do the work for you, or do proper session management with CGI::Session or a similar module.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

Re: web cgi forms data security...
by pg (Canon) on Dec 30, 2003 at 20:40 UTC
    use strict; use warnings; require Digest::MD5; my $user = "foo"; my $pass = "bar"; my $key = "something"; my $md5 = Digest::MD5->new(); $md5->add(join(":", $key, $user, $pass)); print $md5->hexdigest;
      I'm going to be interested in how you propose to retrieve the data from that digest... since it returns a 16 byte one-way hash of the data. :)

      Now, to give you credit, you could at least verify that the people hadn't switched up the data from form to form with this. That isn't an unimportant task and worthy of implementing even if the users decides to go with SSL only and just let HTTP and the browser resend the arguments over and over.

      --
      $you = new YOU;
      honk() if $you->love(perl)

        That's actually easy to do. Each time the page loads, you just create a massive distributed computing project to try all possible usernames and passwords.

        Might be a little slow, though.

      pg,
      after md5 encryption can i get back my original data?
      with which function?

      thanx

        No. The way a hash digest works is to allow you to REHASH the 2 params and the key (in the same order), and see if the hash is the same. It will be if the params have not been tampered with. You sound like you want real encryption. Here are a few handy functions:

        my $key = "this key must be kept secret!"; sub generate_MD5_hash { my ( $plain_text ) = @_; $plain_text = '' unless defined $plain_text; require Digest::MD5; return Digest::MD5->new->add( $plain_text . $key )->hexdigest; } sub validate_MD5_hash { my ( $hash, $plain_text ) = @_; return 0 unless $hash; return 0 unless defined $plain_text; return $hash eq generate_MD5_hash($plain_text) ? 1 : 0; } sub decrypt { return '' unless $_[0] and $_[0] =~ m!^[A-Fa-f0-9]+$!; require Crypt::Blowfish; require Crypt::CBC; my $cipher = new Crypt::CBC( $key, 'Blowfish' ) return $cipher->decrypt_hex($_[0]); } sub encrypt { return '' unless defined $_[0]; require Crypt::Blowfish; require Crypt::CBC; my $cipher = new Crypt::CBC( $key, 'Blowfish' ) return $cipher->encrypt_hex($_[0]); }

        cheers

        tachyon

Re: web cgi forms data security...
by extremely (Priest) on Dec 30, 2003 at 21:28 UTC
    If you have a backend DB and the webserver(s) all have access to it, consider doing something with sessions where you hand the user a completely opaque session key and store all the data locally, temporarily.

    Or at best, use one of the Crypt modules to stuff it into a cookie (temporary, don't make them store it) and deal with it using the cookie mechanism.

    --
    $you = new YOU;
    honk() if $you->love(perl)

Re: web cgi forms data security...
by Anonymous Monk on Dec 30, 2003 at 22:30 UTC
    Issue a session ID based on MD5 Digest. Pass the session ID as one of the parameters, unencrypted. Use the session ID to encrypt, pass around and decrypt the data. This way you get symmetrical encryption (not public-key encryption).

    I would review Chapter 5 of Secure Programming Cookbook (even though it's for C/C++, not directly Perl) and just copy-paste something from there, since the encryption-decryption routine will be server-side anyway.

Re: web cgi forms data security...
by fx (Pilgrim) on Dec 31, 2003 at 00:15 UTC

    In the past I have used the technique described by Mark Neilson in Issue 59 of the Linux Gazette. In (brief) summary, it uses Crypt::Blowfish to encrypt sensitive data in binary and then uses unpack to turn that binary format into ASCII (well, ok, a hex representation of the binary data) that can be placed into a URL. The receiving page then uses pack before Crypt::Blowfish decrypts it.

    IMHO, the only downfall of this method as described is that the key is in plaintext in the perl files. As perl is an interepted language, anyone with permission to read these files can also obtain the key.

    I agree that sensitive information should be placed into some store (such as a database) and retrieved using session.

    ==fx, Infinity is Colourless

Re: web cgi forms data security...
by noname00 (Novice) on Dec 31, 2003 at 00:03 UTC
    thank you all guys.. so many replies in less than an hour i think i ll be a (perl)monk(.com) too :) now i ll have to decide which method is best for my situation

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://317769]
Approved by Enlil
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-04-16 04:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found