Reputation: 21
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
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
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
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