2

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());
}
Ozzy
  • 8,244
  • 7
  • 55
  • 95
Sam
  • 21
  • 2

3 Answers3

2

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)

Community
  • 1
  • 1
Ozzy
  • 8,244
  • 7
  • 55
  • 95
  • @user1544815 was asking about how to prevent crazy HTML/JavaScript exploits (usually XSS), not quite on SQL injection prevention. – uzyn Jul 23 '12 at 03:17
  • @uzyn Supposedly the `GetSQLValueString` function is preventing SQL injection. – Andrew M Jul 23 '12 at 03:22
  • @AndrewM Yup, hence my comment that the original poster was asking about XSS prevention, not quite on SQL injection. – uzyn Jul 23 '12 at 03:23
1

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.

uzyn
  • 6,625
  • 5
  • 22
  • 41
  • Thanks, Uzyn! Think the functions provided here would be sufficient in sanitizing the $_POST data? http://css-tricks.com/snippets/php/sanitize-database-inputs/ – Sam Jul 23 '12 at 03:57
  • @Sam What you're looking at is not so much sanitizing inputs for database, but outputting safely (with `htmlentities()`) at display time. – uzyn Jul 23 '12 at 04:00
  • And I believe that `GetSQLValueString()` that you are using is already handling SQL sanitization for you. – uzyn Jul 23 '12 at 04:00
1

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.

Dean Rather
  • 31,756
  • 15
  • 66
  • 72
  • This doesn't help with preventing XSS, though. Anyone could go to his page and copy/paste HTML/JS and the problem still exists. – Andrew M Jul 23 '12 at 03:25
  • But the HTML they copy would have a hard-coded token in it, which would only work once. – Dean Rather Jul 23 '12 at 03:27
  • No, I mean if they type `` into the name input, the token does nothing to stop this. Plus any browser automation script (ie. an AutoIt script) would also make the token useless, since it would simply emulate a user entering values into the fields. – Andrew M Jul 23 '12 at 03:29
  • This prevents botting, not XSS. – uzyn Jul 23 '12 at 03:45