Input secure by PHP

2019-09-08 16:23发布

问题:

I'm not sure , how I can really make a safe inputs with strings.

For example I got:

$id = intval($_POST['id']);
$name = $_POST['name'];
$sql->query("UPDATE customers SET name = " . $sql->escape_string($name) . " WHERE id = {$id}");

I'm sure that $name isn't secured enough. How can I secure it, to prevent from XSS vulnerability?

Kind Regards, cyclone.

回答1:

XSS protection should be done on the output side, not your storage medium (the database). The database does not know where the data is displayed at. If the data to be stored is text (as in this case with $name), you should store it as text and not HTML.

If you really want to get rid of possible HTML tags, use $name = strip_tags($_POST['name']), but the correct way to prevent XSS vulns is escaping it on the output side with htmlspecialchars (or htmlentities).

If you want to use the PHP filter functions, here is an example that removes HTML tags:

$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);

PHP Docs:

  • filter_input function
  • Sanitize filters


回答2:

XSS has nothing to do with your database, well mostly.

Cross-site scripting (XSS) is a type of computer security vulnerability typically found in Web applications that enables attackers to inject client-side script into Web pages viewed by other users.

Maybe your referring to SQL injection? You've escaped input already, you can further sanitize it by casting variables to appropriate types.



回答3:

When it comes to security, I always think it makes sense to be as strict as possible, but no stricter. If you can determine that a name is invalid before inserting it into the database, why not reject it then?

Does anyone have a name with an HTML tag in it? Probably not. But how about an apostrophe or hyphen? Definitely.

With that in mind, let's see what a valid name would look like:

  • Letters
  • Spaces
  • Apostrophes
  • Hyphens
  • Periods (for initials)

Now that you've determined what a valid name looks like, reject all names that do not meet this criteria:

/* If the input contains any character that is not a capital letter, 
   a lowercase letter, whitespace, a hyphen, a period, or an apostrophe, 
   then preg_match with return true. */
if (preg_match('/[^A-Za-z\s\-\.\']/', $_POST['Name']))
{
    // Invalid name
}
else
{
    // Valid name
}


回答4:

The code you've provided is aimed at protecting again SQL Injection attacks, not XSS attacks, which are a completely different thing.

SQL Injection is where the attacker uses SQL code to get data in or out of your database in a way that you did not intend. Properly escaping the SQL string as you're doing will mitigate against this. (that said, I don't know from your code what class the $sql object is, and thus I can't tell you whether $sql->escape_string() is a sufficient protection; I assume it is, but would need to know more about the object to be sure)

XSS ("Cross-site scripting") attacks are where an attacker managed to get his HTML, CSS or Javascript code into your page, resulting in subsequent page loads being displayed with unwanted content.

This can be achieved by the attacker in a variety of ways, but typically you should ensure that any data input by users which will be displayed on your site should be filtered to prevent it containing HTML, CSS or JS code. If it does, you should either strip the code out entirely or use HTML escaping (PHP's htmlentities() function and similar) to ensure that it is displayed in a safe manner.

You are currently not doing anything to prevent this at all in the code you've shown us, but equally from the code you've shown us, we can't tell whether this data needs to be protected against XSS attacks. This would depending on when and how it is used.



回答5:

For cleaning entries before putting them in sql, I always do this:

trim($string) // Cuts off spacing and newlines in the beginning or end

And

mysql_real_escape_string($string) // prevents SQL injections

Note: Any part of the sql query string can be mysql_real_escape_string'd. The entire string does not have to be; as long as some part of escaped, the query will be safe from injection.