http://www.perlmonks.org?node_id=140664

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

Hi,

I understand that it's possble to save a html form from the website and alter the values in the form. Examples of values that can be modified are textfield values or hidden values. In doing, the person can modify the behaviour of the CGI script to his desires. How can a CGI script be written so that it can detect whether it is called directly from the server or via the person's computer (of course, the script would still be called from the server)? If this is not possible, what safeguards are there to prevent such a scenario?

Thanks in anticipation :)

kiat

Replies are listed 'Best First'.
Re: Modiying values in html form
by Biker (Priest) on Jan 22, 2002 at 19:32 UTC
    You must verify that all 'important' values are 'reasonable' when they come up to your .cgi application.
    For instance, the price for an article that the visitor is going to buy should not be stored on the client side. Or at least, your .cgi application should not use it. Because a smart(?) client could change it and buy your product for 1 cent. Or for -100 dollars. (Hup! Will you send the money with the product? :-)

    Some basic rules of thumb:
    - Almost anything provided by the visitor may be stored in the visitors browser.
    - Anything provided by your site cannot be trusted if it's been down to the client. You must verify and check it again. (Like using the price from your database, not from the client browser.)
    - If you want to give the visitor some sort of safety, like using a password or such, it will become even more complicated.

    Best regards
    Biker
Re: Modiying values in html form
by gav^ (Curate) on Jan 22, 2002 at 21:04 UTC
    You have several options:
    • You can use $ENV{HTTP_REFERER} (or more simpler $cgi->referer) to make sure that your script is being submitted from the right place.
    • You could do a MD5 checksum of all the hidden fields to makre sure they haven't changed
    • You could use something like CGI::EncryptForm to encrypt the data so it can't be changed
    • You could not store anything in hidden fields and use sessions instead (see Apache::Session)
    You definatly don't want to accept things like prices from form fields (I know of one major e-commerce system that does).

    Hope this helps.

    gav^

Re: Modiying values in html form
by drinkd (Pilgrim) on Jan 22, 2002 at 19:22 UTC
    Basically, a script to programatically read/write web pages is just a custom browser. The whole idea of the www client/server model is that any kind of browser can be used and the server doesn't know beans, except what the client tells it. As such, what you say is impossible.

    That being said, there is a number of loopholes that you can use. merlyn (of course), for example, has an article that shows how to make life hard for robot scripts proporting to be real-life browsing people by showing a picture of a random number or word and making the browser person type in what they see. There are other ways to make it hard but not impossible for scripts to pretend to be people browsing. LOL

    drinkd

Re: Modiying values in html form
by taint (Chaplain) on Nov 03, 2013 at 05:05 UTC
    Greetings, In my humble opinion. It is best to use only the POST method within such forms, and simply drop attempts submitted via GET. This greatly eliminates common methods to alter submissions via the URL/Location field(s) in their web client (browser). eg;

    http:/your.domain/location/to/your/script?product=expensive-product&price=free

    While hidden fields aren't really hidden, should anyone simply choose View->Source, from their browser. It is fairly trivial to encode those fields via base64, or even sha256. All modern browsers will render those fields correctly. But a View->Source will reveal only seeming gibberish. While a savvy seasoned programmer/user might recognize the fields as being "packed". Is it really worth the bother?

    Anyway. While it isn't ever really possible to completely secure online form(s)/form data. Things like this, that "raise the bar to entry" will usually thwart most attempts. If for no other reason being, that it simply doesn't seem worth the bother.

    HTH

    --Chris

      This question/comment is not much Perl related so probably won't get much comment here. A brief answer is: "Don't round trip prices. Use codes or maintain a session and use a shopping cart".

      There are many tools on CPAN that will help with session management etc.

      True laziness is hard work

      Although it does hinder casual variable modification, anyone who is knowledgeable enough to attempt such attacks is probably more than capable of sending a valid request if they want. There are many browser plugins that allow for easy editing of forms which makes it hardly any more effort to edit a POST compared to a GET. In my opinion the gains in the slight increase in workload for an attacker do not outweigh the time and effort to implement, maintain and debug the obfuscation.

      I believe it is far more important to whitelist and sanitise any inputs, this is where your efforts should be focused. If a hole exists someone can find it no matter how well you conceal the entrance, far better to close the holes.

      That said if you want the peace of mind and are willing to expend the time and effort, any increase in security can only be a positive thing.

        This was in response to:

        http://www.perlmonks.org/?node_id=140664

        #!/usr/bin/perl -Tw
        use perl::always;
        my $perl_version = "5.12.5";
        print $perl_version;
      You should store anything of value server-side (usually in a database or session), but the other way of protecting those is including a signature as a hidden field in the form. Something like sha1(concatenate($longsecrettoken, %importantformfields)) should be enough (but I'm not a cryptographer so don't quote me on that).