[thelist] Form Security

Frank Marion lists at frankmarion.com
Mon Jul 19 15:12:15 CDT 2010

On 2010-07-19, at 2:32 PM, Bill Moseley wrote:
> Sure, it's ok to change user data.  For example, if you accept  
> credit cards
> it's ok to strip out non-digits if you need only digits (I find it a  
> bit
> silly when I enter 1234-2345-3456-4567 and have the site return  
> "Please only
> enter only digits".  Just filter out all the non-digits *then*  
> validate that
> the number is valid for the credit card type.

+ 1

> But, my comment is if you are stripping things like "DROP TABLE" or  
> "rm -rf"
> from user input then you have bigger problems.  If you are worried  
> about "rm
> -rf" in user data that means you are not 100% sure that user- 
> supplied data
> is NEVER used in a way that might be dangerous.  That is, you are  
> allowing
> user data to pass though the shell or have a SQL injection problem.

Can we ever be sure of it? My default position is that the microsecond  
my form is out there, evil CIA hackers are immediately going to pounce  
on it just to ruin my day.

> There's room for debate.  I tend to lightly "validate" email  
> addresses  --
> but if your goal is to accept only valid email addresses then  
> honestly the
> only way to validate them is to actually send mail to the address  
> and get a
> confirmation that the user received the mail.  So, for things like  
> that I
> would use javascript to say "Hey, this doesn't look like an email  
> address.
> Continue anyway?" to allow the user to fix typos.

+ 1

I never considered the "continue anyway?" bit. Something to think about.

> Sure, every extra bit of security is probably good, but my argument  
> is that
> filtering to remove things like "DROP TABLE", rm -rf, "<strong>",  
> etc. is
> misguided and, in my experience, is an indicator that the programmer  
> doesn't
> understand the real security issues.

So what are some options that you do to protect against injection that  
don't involve reserved word filtering or neutralizing?

> Also, forget about the client side.  That is, forget about how the  
> form is
> rendered on the browser -- doesn't matter if you use a drop-down  
> list vs. a
> text field.  Hackers need browsers to attack your site.

... Hacker's *don't...


> Your job on the server is to process requests.  That means 1)  
> authenticate
> the user, 2) check access to make sure the authenticated user can do  
> the
> thing they are asking to do, and 3) validate that the request  
> contains the
> data required for the request and is validated.

I like to think of all computer transactions as two strangers  
discussing to get a job done.

1) Who are you? Prove it. (authentication: username and password)
2) What do I trust you to do? (Permissions)
3) Let me check up on what you've just done (validation)

The one item that I missed in Davoud's original post was that he is  
assigning user roles. That's an excellent idea that I forgot to  
mention, and was only round-about when I mentioned session validation  
to run the SQL query.

> Unfortunately, I also do not use PHP.   And I think what you are  
> after is
> examples of good way to handle user input and render output, which I  
> don't
> know for PHP.  What I suspect is that there are quite a few PHP  
> frameworks
> that handle a lot of this including:
>   - convert all http requests into valid utf8 (based on the charset  
> of the
>   request)
>   - manage sessions, authenticate and access control lists
>   - a central way to manage input data -- i.e. form validation.  You  
> should
>   say "for a POST to this URL a 'name' field is required and it must  
> be of
>   type 'text'.  I would think that using $_POST[$field_name] should  
> be handled
>   in one place for the entire application not explicitly for every  
>    (Data might not always come in via a $_POST.)
>   - Use some kind of database abstraction (ORM, maybe) where you can  
> do
>   something like sql( "update users set name = ? where id = ?",  
> $user_id,
>   $name )  and not have to worry if $name includes ";drop table  
> users;".
>   - Have a way to render output (a View) -- typically this is some  
> kind of
>   template engine that provides a way to escape user data.  A  
> request might
>   come from a browser or might come from a phone or maybe some day  
> from an API
>   request that expects json output so you may want to render the  
> same response
>   in different formats.

I had never thought of explicitly converting to to UTF-8. Good idea.

Frank Marion
lists [_at_] frankmarion.com

More information about the thelist mailing list