How to escape output in PHP

2019-01-26 22:07发布

问题:

I am a newbie, just to be clear. I hear a lot about escaping data to prevent XSS attacks. How do I actually do that?

This is what I am doing currently -

$s = mysqli_real_escape_string($connect,$_POST['name']));

Is this enough? Thanks

回答1:

If you output the data to html you should use htmlspecialchars() else, if you're storing the data in a database you should escape strings using mysqli_real_escape_string() and cast numbers (or use prepared statements for both) and protect identifiers/operators by whitelist-based filtering whem.

Both these methods are all you need if you use them the correct way.



回答2:

You should use htmlspecialchars for output rather than mysqli_real_escape_string.



回答3:

If you are just starting to fix your code against attacks (meaning SQL Injection attacks), you will be better of checking out parameterized queries. What you basically do with these is separate your content (input) from the commands (sql), so you can never have them confused by a possible mallicious user-entered piece of information like the name.

You can try starting with using the PDO class: You can start reading the PDO manual here: http://php.net/manual/en/book.pdo.php and this page has a nice example: http://php.net/manual/en/pdo.prepared-statements.php

<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);

// insert one row
$name = 'one';
$value = 1;
$stmt->execute();

// insert another row with different values
$name = 'two';
$value = 2;
$stmt->execute();
?>

However, you don't need to use PDO, you can use mysqli also, see http://php.net/manual/en/mysqli.prepare.php

<?php
/* Script A -- We are already connected to the database */

$stmt = mysqli_prepare($link, "INSERT INTO table VALUES (?, ?, 100)"); /* Query 1 */
mysqli_stmt_bind_param($stmt, "si", $string, $integer);
mysqli_stmt_execute($stmt);
mysqli_stmt_close($stmt); // CLOSE $stmt
?>

Because the name is a separate value, it can never be an SQL command, so you will be safe automatically.