Sam
Sam

Reputation: 21

Create a Secure PHP Petition

I launched a website with an online pledge component and it keeps getting hacked/exploited by people using html/javascript to cause crazy stuff to happen on the signatures page. I can't figure out how to script the non-alphas from the fields to prevent this.

Below is the code I'm using to record the form data in the database. Any suggestions on how to implement the preg_replace function (if that's the best one)? Also, is this the best place to prevent the exploit, or is there somewhere else that would be more ideal?

if ((isset($_POST["MM_insert"])) && ($_POST["MM_insert"] == "form1")) {
    $insertSQL = sprintf("INSERT INTO signature (FirstName, LastName, Email, State, Country, `TSDate`, IP) VALUES (%s, %s, %s, %s, %s, %s, %s)",
                   GetSQLValueString(($_POST['FirstName']), "text"),
                   GetSQLValueString(($_POST['LastName']), "text"),
                   GetSQLValueString(($_POST['Email']), "text"),
                   GetSQLValueString(($_POST['State']), "text"),
                   GetSQLValueString($_POST['Country'], "text"),
                   GetSQLValueString($_POST['Date'], "date"),
                   GetSQLValueString($_POST['IP'], "text"));
mysql_select_db($database_petitionscript, $petitionscript);
$Result1 = mysql_query($insertSQL, $petitionscript) or die(mysql_error());
}

Upvotes: 2

Views: 1158

Answers (3)

Dean Rather
Dean Rather

Reputation: 32384

You could use form tokens. It might take a little to implement, but simply:

When PHP Serves up the form, generate a random string and save it into the db as a "token". have a hidden field on the form with that token.

When you receive submitted form data from the user, only process it if the provided token exists in the database. (Then delete the token).

This will help prevent people from automating the process of submitting the form, as they will need to re-load the form and submit the token each time (which most script-kiddies would not bother with.)

You can take this much, much further, by doing things like binding the tokens to user sessions, and only allowing each session one token, etc. etc. but it's possibly a good place to begin.

Actually, it looks like this could be done just using the session w/o touching the db, might be a bit easier.

Upvotes: 1

Ozzy
Ozzy

Reputation: 8312

You should wrap all of your $_POST vars with htmlspecialchars

http://php.net/manual/en/function.htmlspecialchars.php

Also, if you're on PHP5 you should use a PDO object instead, for connecting to the database, and you shouldn't put vars directly into MySQL queries (that allows SQL parser to be injected with SQL code from the user). You need to use parametrized queries. How can I prevent SQL injection in PHP?

(Actually I just realised you are using parameterized queries)

Upvotes: 2

uzyn
uzyn

Reputation: 6683

Sanitize all your outputs with htmlentities().

Eg., instead of doing

<?php echo $FirstName; ?>

Do:

<?php echo htmlentities($FirstName); ?>

This will stop XSS attack with crazy HTML/JavaScript that you described.

Additionally, do prevent from SQL injection, you should also sanitize your inputs ($_POST data) before saving them.

Upvotes: 1

Related Questions