3

I had trouble getting the form API to work though I am considering re doing all my forms with it. I have some custom html/php forms however I directly insert into the DB using pg_query. I am looking into replacing that with pg_query_params to escape. I was wondering whether the php filter module, if I set it up, would prevent users from doing harm via sql injection? Iwould guess not but thought I would check.

Just looking for suggestions.

  • 1
    If possible please accept Letharion or Clive's answers. Mine was intended as supplemental information, not a direct answer to the question. – Craig Ringer Jul 30 '13 at 11:44
11

No, it very much will not!

SQL injection prevention is something that needs to happen in the PHP code itself; the PHP filter won't alter your PHP, so it can't add protection to your code.

I'd be very surprised if there's anything out there that can auto-magically take an arbitrary PHP script and save it from SQL injection. In fact, if you ever see anything that claims to do that I'd go so far as to say "avoid it" it's lying.

Shows what I know :)

As per the comments, ModSecurity is an option if you want to control this at the web server level.

  • 3
    You beat me too it ;) – Letharion Jul 29 '13 at 15:54
  • @Letharion I think you nipped me by about 15 secs actually ;) – Clive Jul 29 '13 at 15:55
  • 1
    I'll take pleasure and surprise you: ModSecurity works pretty good. Sometimes it's over-protective and prevents you from some things you would want to allow, but hey, it's better that way than the opposite one. Of course it does not change PHP scripts, it just filters input. – Mołot Aug 1 '13 at 11:28
  • My pleasure. It kicked in only 2 or 3 times on things my app might not prevent on it's own (and about as much false positives), but on the other hand there was not an one successful attack when I worked there. But it was not a Drupal back then. – Mołot Aug 1 '13 at 11:35
12

It will not, in any way shape or form protect you from injection. Quite the contrary, using the PHP filter is generally a horrible security problem, because it enables arbitrary code to be executed.

Do not use the PHP module, at all.

Greggles mentions the Paranoia module in his answer, which is awesome, consider using it. However, if you have enough control over your server, you could take it one step further, by disabling the eval function all together.

In your php.ini: disable_functions = eval

  • Ahh ok, I thought my only allowing the admin user to use the php filter it would prevent other users inputting it. That's ok, I am looking at using pg_query_params to escape – Tom Jul 30 '13 at 8:08
  • You are of course free to solve the issue any way you want, but I want to point out that I don't think it's ok. Quite the opposite, I recommend people to run their webservers with disable_functions=eval. However, what you say is true, the permissions system will limit use of the filter, but that doesn't necessarily protect you from the opened pandoras box that the php filter is. – Letharion Jul 31 '13 at 8:23
2

The only reliable way to prevent SQL injection is to carefully use only parameterized queries ("prepared statements") and avoid string interpolation in queries. In PHP that means pg_query_params or appropriate PDO module use.

Even then, a multi-layered defense is certainly nice. I try to prevent obvious SQL injection attacks from appearing in identifiers where there's no reason for them to be permitted. If you try to set your username to something including '); I'll just reject the request. Sure, I can safely insert that string and if the check wasn't there the attack would still do nothing, but it means I don't have potential attack code in my DB where it could be read out and interpolated into another SQL command elsewhere, perhaps by code that thinks that "this value came from the database so it must be safe".

This might save you if someone wrote a buggy PL/PgSQL function that doesn't properly use format(...) or quote_ident / quote_literal. The data passes straight through your app fine, then successfully executes the attack via the buggy PL/PgSQL function. Similar issues can arise from a badly written automation script, reporting tool, or all sorts of things.

So: even with data from your own DB, treat it as if it could be user-modifiable if it was ever user modifiable at any stage in its life-cycle. In fact, treat everything as user-modifiable and untrustworthy unless you have an extremely good reason not to.

So, IMO, much like you'll tend to reject obvious XSS attempts even though you know your code will safely handle them if not rejected, you should reject obvious SQL injection attempts even if your code will survive them fine.

Also, note that pg_query_params isn't magic SQL injection protection. If you write:

pg_query_params("SELECT blah FROM $tablename WHERE somecol = \$1", array($uservalue))

and $tablename can be defined by the user, you're still just as stuffed.

  • Can't decide if I want to +1 because of great information, or -1 because it doesn't even attempt to answer the question. – Letharion Jul 30 '13 at 11:33
  • 1
    @Letharion I'm sorry, I usually remember to prepend ones like this with "Please accept other-user's answer, this is just supplimental information". – Craig Ringer Jul 30 '13 at 11:43
  • As a general answer this is ok, but on a Drupal specific question this feels a bit off-course since it doesn't mention the Drupal specific database APIs. – greggles Jul 31 '13 at 13:51
  • 1
    @greggles OK, thanks. I'll keep that in mind. I was just bought here by the PostgreSQL tag and was horrified to see another person walking straight into SQL injection protection woo. Though at least they questioned it. – Craig Ringer Jul 31 '13 at 16:44
2

The title of the question is about using "PHP Filter" as a way to make queries safe. As others have mentioned:

  • No, it doesn't magically make queries safe.
  • Even worse, it will make your site less safe. I suggest the Paranoia module to really prevent the PHP Filter from doing anything.

But the body of the question gets into two more questions. Using pg_query functions directly and how to avoid SQL injection. You also should not be using pg_query directly but instead use the Drupal database API.

  • Maybe you really love PG right now, but at some point the site has to move to a new database. Using the database API will make that easier.
  • Drupal's database API, when used properly, has placeholder handling that will escape any SQL injection attacks

You can find more about this topic at Drupal Database API and the Writing Secure Code for more tips about how and why to use the Drupal database API for portability, security and scalability.

There are other modules and services that behave as an Intrusion Detection System or provide other means to avoid malicious attacks.

  • The TinyIDS and PHPIDS modules attempt to detect attacks in every incoming request.
  • There are Web Application Firewalls - webserver-level solutions like Apache's mod_security - which can be configured to block requests with malicious patterns.
  • There are commercial services like CloudFlare
  • Just ben doing param escaping today, Good to know – Tom Jul 31 '13 at 13:58
  • Haven't come across Paranoia before, that one instantly goes into the "must have" column for new sites. Thanks for the heads up – Clive Aug 11 '13 at 13:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.