Безопасность PHP, intval и htmlspecialchars - PullRequest
3 голосов
/ 01 августа 2009
<?php

$id = intval($_GET['id']);

 $sql = mysql_query("SELECT username FROM users WHERE id = $id");
 $row = mysql_fetch_assoc($sql);

$user = htmlspecialchars($row['username']);

?>

<h1>User:<?php echo $user ?></h1>

Видите ли вы какие-либо угрозы в приведенном выше коде? Нужно ли использовать htmlspecialchars для всего, что я вывожу? И я должен использовать is_numeric или intval, чтобы проверить, чтобы получить числовой?

Я просто строю минимальный сайт. Мне просто интересно, если приведенный выше код уязвим для инъекций SQL, XSS?

Ответы [ 3 ]

8 голосов
/ 01 августа 2009

Вообще говоря, mysql_real_escape_string() предпочтительнее, но, поскольку это число, intval() в порядке. Так что да, это выглядит нормально с точки зрения безопасности.

Хотя на многих платформах целые числа ограничены 32 битами, поэтому, если вы хотите иметь дело с числами, превышающими ~ 2,1 миллиарда, это не сработает. Ну, в любом случае, это не сработает так, как вы ожидаете.

Такие меры предосторожности применяются к любой форме ввода данных пользователем, включая файлы cookie (то, что многие забывают).

5 голосов
/ 01 августа 2009

Я настоятельно рекомендую использовать PDO и подготовленные заявления. Хотя приведенное выше утверждение выглядит безопасным, у вас возникнут проблемы, как только вы выполните более сложные запросы.

Вместо того чтобы ломать голову над тем, является ли конкретный запрос безопасным, узнайте о готовых утверждениях, и вам не придется беспокоиться Вот ваш пример, переписанный с помощью PDO:

# Make a database connection
$db = new PDO('mysql:dbname=your_db;host=your_db_server', 'username',
    'password');

# The placeholder (:id) will be replaced with the actual value
$sql = 'SELECT username FROM users WHERE id=:id';

# Prepare the statement
$stmt = $db->prepare($sql);

# Now replace the placeholder (:id) with the actual value. This
# is called "binding" the value. Note that you don't have to
# convert it or escape it when you do it this way.
$stmt->bindValue(':id', $id);

# Run the query
$stmt->execute();

# Get the results
$row = $stmt->fetch();

# Clean up
$stmt->closeCursor();

# Do your stuff
$user = htmlspecialchars($row['username']);

Я добавил много комментариев; это не так много кода, как это выглядит. Когда вы используете bindValue, вам никогда не придется беспокоиться о внедрении SQL.

0 голосов
/ 01 августа 2009

Ну

Вы приводите полученный идентификатор к int; так что нет возможности SQL-инъекции здесь.
А остальная часть запроса к БД «жестко запрограммирована», так что никаких проблем там тоже нет.

Если бы id был строкой в ​​БД, вам пришлось бы использовать mysql_real_escape_string, но для целого числа intval - правильный инструмент : -)


По поводу вывода вы тоже экранируете данные (и, поскольку вы выводите HTML, htmlspecialchars в порядке) ; поэтому нет HTML / JS-инъекций.


Итак, эта короткая часть кода выглядит нормально для меня: -)


Как примечание, если вы начинаете разработку нового веб-сайта, это момент или никогда не взглянуть на mysqli (вместо mysql) и / или PDO; -)

Это позволит вам использовать функциональные возможности, предоставляемые последними версиями MySQL, такие как, например, подготовленные операторы - которые являются хорошим способом защитить себя от внедрения SQL!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...