1

I have a PHP page with a form. The form has method="POST" and the action is another PHP file which inserts the values into MySQL. This all works properly.

My problem is that the 2nd PHP page which sends the info to the database contains the username, password, databasename and tablename where the info should go. I am concerned that someone could create their own PHP or HTML form and POST to MY 2nd PHP file and submit any values to my database.

I want to put the username, password, databasename and tablename on the 1st PHP page (with the form) and pass these as variables to the 2nd PHP form, thus eliminating the threat of someone else creating their own form and posting whatever they want. (If this is possible and the correct way to do it, can you suggest how to pass the variables?)

Is this the proper way to secure input to the database?

Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
andrew anderson
  • 393
  • 5
  • 6
  • 16

4 Answers4

1

Look at your server as a black box. It accepts requests and responds to them. For websites that means any time a URL is accessed, a link is clicked or a form is submitted, that's a request. The server does something with those requests and responds with a new website, or a redirect, or a file to download or whatever else.

HTML forms are really just an interface to take data from a user and package it up into a request. What's important is not the HTML or the PHP that generated that HTML, it's the resulting request that is sent to the server, containing the data the user entered into the form. You can generate such requests trivially without even having an HTML form.

Use the Web Inspector in Chrome/Safari, Firebug in Firefox or IE Developer Tools and look at the network inspection tools there to see all request-responses and poke around their details.

If you need any sort of validation for requests, the server has to do it. You cannot depend on your HTML forms for validation. Anybody can send any data anytime to your server from anywhere.

deceze
  • 510,633
  • 85
  • 743
  • 889
0

I am concerned that someone could create their own PHP or HTML form and POST to MY 2nd PHP file and submit any values to my database.

They can, and they don't even need to go to the trouble of creating an HTML page to do it.

Is this the proper way to secure input to the database?

The correct way of doing this is to never allow inputs to specify table or column names (or any SQL identifier). Inputs should only specify column values or values used in comparisons in WHERE clauses.

Enumerate the queries you need, and come up with a way to let the form specify the particular query you want and make sure you properly authenticate for that particular query.

If you are trying to do ad-hoc reporting, explicitly design for that. Open Source & Free Adhoc / End User Reporting Tool addresses that for PHP.

"ad hoc" reporting systems allow the users themselves to create specific, customized queries.

Ad-hoc reporting is tough to do securely because many SQL-security best practices like prepared statements do not allow parameterizing queries with table names, and there are often corner cases to ad-hoc reporting that leak PII that are not otherwise available.

I want to put the username, password, ... on the 1st PHP page (with the form) and pass these as variables to the 2nd PHP form

It's not clear from your question that you're doing this, but just to be clear, you should never export the database username and password or allow form inputs to affect your database connection configuration. This makes it far easier for an attacker to

  1. covert the ability to run a low-power shell inside your firewall into a partial takeover of your database,
  2. brute force your database's administrative password given only web access and time and then turn any SQL injection flaw into a complete takeover of your database.
Community
  • 1
  • 1
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • Ok so to confirm , if a field in my database is called "house" i should never use the word "house" in my form? If this is correct does that mean its good practice to use database feild names which are random and not meaningful? I assume that my suggestion of having the username, password ect in the first file and passing them wouldnt help the security that much? – andrew anderson Apr 06 '12 at 00:33
  • @andrewanderson, Using the word house in your form is fine. Just don't plug it into a place where a column name is entered. Don't do `$query = "SELECT $colname FROM $tablename WHERE ..."`. Even if you've properly encoded `colname` and `tablename` ahead of time (to avoid SQL injection), you're probably violating assumptions made by the DB schema designer about access patterns when assigning permissions. – Mike Samuel Apr 06 '12 at 00:36
  • I am affraid your response is way above my knowledge and i am not able to follow your solution. My database holds no sensitive information i just want to be able to secure it to a resonable standard to stop people from being able to insert any data that they want. – andrew anderson Apr 06 '12 at 00:48
  • @andrew Then you need to **validate** data before your script accepts it to insert it into the database. Whether somebody "creates their own HTML" doesn't matter. What would stop somebody from just entering any data into your existing form? Where is the difference? – deceze Apr 06 '12 at 01:09
  • @andrewanderson, then it might be a good idea to connect to the database as a user that only has read permissions. – Mike Samuel Apr 06 '12 at 14:40
0

Don't put databasename and tablename in the form. Put some meaningful value there, and on ther serverside code, select the appropriate table name and database.

For instance, add a select field that can take the values "bluepill" or "redpill". On receiving the POST data, choose the table "good_users" for bluepill and "evil_users" for redpill.

If the form is a registration form, you can think of other methods of verifying users, such as email link, captcha, etc.

j13r
  • 2,576
  • 2
  • 21
  • 28
  • i am not sure that i am explaining this properly, either that or the replies are too complicated for me to understand. I have a file.. lets call it php1.php in this there is a form and its action is php2.php inside php2.php is an insert statement to send the data from the form to a database. all the log in info for the database is in the file php2.php so anyone could create there own php1.php with the action of my php2.php and it would submit to my database. – andrew anderson Apr 06 '12 at 00:46
  • Nobody should be able to write files on the server (i.e. create php files). Presumably you are the only one who can upload files. Your database is protected by a username & password that you write in your php file. Nobody else should be able to read your php file. All the webserver does is run it. – j13r Apr 06 '12 at 00:50
  • yeah i get all that, but whats to stop you doing the following: creating your own php file. with the action of http://mydomain.co.uk/php/php2.php Uploading this to your sever and using the form. This will post all the infor from your form to my php2.php file and because the username and password is already in this file then it will just insert the data from your form to my database..Atleast i think it will havent tried it. In theory it should work though – andrew anderson Apr 06 '12 at 00:54
  • 1
    you mean to say create my own html file. You are right, that is possible; but what's the difference between that and using your website? How would you distinguish between inputs you want and inputs you don't want if people used your website. One thing you can do is to create a session -- so people first have to open php1.php, where the session is initialized. in php2.php you check whether that person came with in initialized session. But it really boils down to what scenario you try to avoid. – j13r Apr 06 '12 at 01:02
  • So basically, a user must be logged in to get access to the form. If you created your own html form then you wouldnt need to be logged in. Can i use require login.php inside php2.php to make sure that the user is already logged in ? – andrew anderson Apr 06 '12 at 01:05
  • Yes, you can require that. However from your comment I'm not sure that you understand that login (more accurately, having a session, doesn't require an account/password) happens on the server side; I can't do that on my html form. – j13r Apr 06 '12 at 01:10
0

I would agree with deceze response. You can always use captcha or additionally you can do $_SERVER['HTTP_REFERER'] check (see here for HTTP_REFERER) for the request to your php2.php and bypass all requests which are not from your server.

dldnh
  • 8,923
  • 3
  • 40
  • 52
Suketu
  • 371
  • 1
  • 7