Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: Re: Re: Re: Re: Re: "Correct" program style questions

by BrowserUk (Pope)
on Oct 24, 2002 at 01:21 UTC ( #207596=note: print w/replies, xml ) Need Help??


in reply to Re: Re: Re: Re: Re: "Correct" program style questions
in thread "Correct" program style questions

One reason for processing parameters that "aren't there" is to check that someone isn't modifying a URI in an attempt to break the code?

This seems like an appropriate way to do that and bottle out early to an error page, before going on to validate correctly passed parameters. That way you get a single log entry for each mal-formed query string, noting all the information you need rather than (potentially) several dozen essentially similar warnings, one for each missing parameter.



Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: Re: Re: "Correct" program style questions
by sauoq (Abbot) on Oct 24, 2002 at 01:53 UTC
    One reason for processing parameters that "aren't there" is to check that someone isn't modifying a URI in an attempt to break the code?

    Yes. At least, that's one way you might legitimately find yourself checking for parameters that aren't there. In that case, however, you are still checking for parameters that you expect to be there. I think there are three good options in that exceptional case:

    1. If you are paranoid about it, then include code that explicitly checks whether the value returned by param() is defined.
    2. If you aren't paranoid about it, then don't write any specific handling for it and let perl spew out some warnings.
    3. If you don't care at all, turn off warnings.

    I don't think it is a good practice to write code that simply circumvents warnings which only arise under exceptional conditions. The use of the or-empty construct that started this discussion was just that.

    -sauoq
    "My two cents aren't worth a dime.";
    

      I hope I'll be forgiven for having one last try... :^)

      1. If you are paranoid about it, then include code that explicitly checks whether the value returned by param() is defined.
        1. I don't consider it paranoid to validate user input. This is no different that the whole purpose of taint checking.
        2. This goes back to what I said a couple of iterations back. Using the || operator (which is undeprecated as far as I know ) serves the purpose of simplifying and clarifying the code, and removing the need to used defined twice (or more) on each parameter.
        3. What's wrong with cleaner, simpler code?
      2. If you aren't paranoid about it, then don't write any specific handling for it and let perl spew out some warnings.

        Sounds like a possible DoS attack in the making.

        Whilst I've never heard of it being done in this particular way--and my attempts at seeing what would happen on my local Apache server where foiled by simply not being able to generate enough queries fast enough as the user agent and the webserver were always competing for cpu and were therefore self limiting--but it wouldn't be the first time that causing logs to fill/overflow or simply sapping the horsepower of the server by causing it to generate gobs of useless warnings has been used to bend or break a server.

      3. If you don't care at all, turn off warnings.

        That is probably what I would do, locally, for the duration of the untaining of the parameters and validation that I had them all.



      Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
        I hope I'll be forgiven for having one last try... :^)

        Just this one last one... :-)

        I don't consider it paranoid to validate user input.

        Either do I. We aren't really talking about validating user input though. We are talking about the literal presence of parameters in the query. The presence of the parameters themselves is ostensibly controlled by the programmer and should be considered reliable. Take these three URLs for example:

        1. http://example.com/some.cgi?name=foo
        2. http://example.com/some.cgi?name=
        3. http://example.com/some.cgi
        In the first example, a call to param('name') returns the value. In the second, it would return an empty string. In the last it would return undef. The or-empty construct eliminates the ability to differentiate between cases two and three.

        If the 'name' parameter is expected to be there but isn't, then someone is accessing the application in a way that it was not meant to be accessed. That's an exceptional condition. If you have determined that this situation is critical, then you should be checking the definedness of the value that param() returns and taking appropriate action unless it is defined. If you have determined that this situation is not critical, then you could choose to ignore it, with or without warnings.

        Using the or-empty construct amounts to nothing more than a non-standard way of turning an 'unitialized value' warning off for one variable. That can't be good. Especially not without documenting that behavior.

        Sounds like a possible DoS attack in the making.

        That's unlikely though perhaps not impossible. In order to exploit it someone would have to be familiar with the fact that your program is logging warnings. You log information with each connection anyway, so what is a little more going to hurt? If you actually log a lot more with warnings, that's an argument to turn them off. Better yet, it would be a very good reason to check for undef on the original param() call and handle the condition properly. For instance, you might choose to email your pager that a possible DoS or hack attempt is taking place and log the IP.

        Upon looking at the original code again, I'm convinced that the proper way to do it is to check for definedness first and to use a * rather than a + in the regex in order to ensure that the untainted value is never undef. Something similar to this:

        error_out() unless defined( my $name = param('name') ); ($name) = $name =~ /^([[:alpha:]]*)$/;

        -sauoq
        "My two cents aren't worth a dime.";
        

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://207596]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (4)
As of 2018-10-22 15:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    When I need money for a bigger acquisition, I usually ...














    Results (119 votes). Check out past polls.

    Notices?
    • (Sep 10, 2018 at 22:53 UTC) Welcome new users!