Как предотвратить SQL инъекции кода в мой код PHP?


я Разработал простую страницу на PHP для внутреннего использования в компании, что работа, и только очень немногие люди используют его. С помощью этой страницы можно сделать некоторые запросы, вставки, изменения и удаления данных из таблицы в базе данных MySQL, однако я считаю, что мой код в PHP не защищен от SQL инъекции кода, например:

//----CONSULTA SQL----//
$busca = mysql_query ('insert into Produtos (coluna) values(' . $valor . ')');

, Логотип, предположим, что пользователю использовать приговор: 1); DROP TABLE Produtos; для поля valor команда будет выглядеть:

insert into Produtos (coluna) values(1); DROP TABLE Produtos;

Он будет вставлять новую запись, чье поле coluna 1, а затем он будет удалять таблицы "Товары".

Как я могу улучшить мой код, чтобы предотвратить эту ситуацию?

Author: UzumakiArtanis, 2014-02-03

9 answers

1 - НЕ используйте функции mysql_*, поскольку они считаются устаревшими (deprecated), и скоро будут удалены. несколько причин, чтобы не использовать их.

Используйте prepared statements, это позволит уменьшить уязвимость sql-инъекция, потому что запрос состоит из двух частей, команд sql и маркировка(? и :nome), которые будут поменять значениями, первый работает уже второй же содержащий инструкции корректный sql будет рассматриваться как текст.

Маркировка не могут заменены имена databases, таблицы/views, столбцы и значения в clásulas ORDER BY, GROUP BY.

Есть два драйвера, которые поддерживают это, o PDO и mysqli.

, Например, prepared staments, PDO:

$db = new PDO('mysql:host=localhost dbname=teste', 'usuario', 'senha');

$sql = 'INSERT INTO tabela(campo1, campo2, campo3) VALUES(?, ?, ?)';

$stmt = $db->prepare($sql);

$stmt->bindValue(1, 'valor1');
$stmt->bindValue(2, 'valor2');
$stmt->bindValue(3, 'valor3');

$stmt->execute(); // executa o insert ou outra sql

, Например, prepared staments mysqli:

$db = new mysqli('localhost', 'usuario', 'senha', 'teste');

$sql = 'INSERT INTO tabela(campo1, campo2, campo3) VALUES(?, ?, ?)';

$stmt = $db->prepare($sql);
if(!$stmt){
    echo 'erro na consulta: '. $db->errno .' - '. $db->error;
}

$var1 = 1;
$var2 = 'foo';
$var3 = 1.99;
$stmt->bind_param('isd', $var1, $var2, $var3);
$stmt->execute();

String isd соответствует типам данных прошлые являются integer, string, double b blob поля в соответствии с ручного.

 195
Author: rray, 2017-04-13 12:59:32

Существуют несколько способов предотвратить SQLInjection. Два примера:

Я Рекомендую вам прочитать на второй вариант и примите PDO для обработки базы данных.

Читайте также: mysql_real_escape_string() по сравнению с Prepared Statements

 50
Author: William, 2014-02-03 12:43:38

Не рекомендуется использовать библиотеку mysql будет прекращено в ближайшие версии.

Для задачи существует несколько решений:

Http://br2.php.net/mysqli

Http://www.php.net/manual/pt_BR/class.pdo.php

Http://medoo.in/ это, что я использую. Уже много sql общий готова! Стоит проверить.

ПРИМЕЧАНИЕ: в библиотеке более быстрой mysqli, потому что под обе используют mysqli.

 38
Author: Iago Leão, 2014-02-03 21:00:04

Просто не используйте string concatenation, используйте параметры SQL всегда, или библиотека, что-то сделать для себя.

И В вашем примере с параметра user вставить '1); DROP TABLE Продукты;' в столбце, если это позволяет, в противном случае получит сногсшибательному звуку.

И В моем framework я пытаюсь использовать NotORM для слоя данных, и предотвращает многие проблемы, связанные с SQL-инъекции, а также использует интерфейс PDO ;) http://pedrosimoes79.github.io/silverbullet/

И В случае NotORM используют PDO::quote

Http://www.php.net/manual/en/pdo.quote.php https://groups.google.com/forum/#!topic/notorm/3kR2o9iI5xQ

, Используя этот код в Model:

function getHelloworldMySQL()
{
    $this->db->hello2->test->insert([
        'text' => "'Hello with a drop'); DROP TABLE Produtos;"
    ]);

    foreach ($this->db->hello2->test as $id => $hello) {
        return $hello['text'];
    }
}

И Получаем ;)

inserir a descrição da imagem aqui

 34
Author: Pedro Simões, 2014-04-26 16:55:35

Я Нашел странным, никто не процитировать

Stored Procedure.

Кроме того, чтобы избежать SQL-Инъекции, вы получаете высокую производительность, поскольку они компилируются.

Create PROCEDURE stp_ExemploInsert
@nome varchar(200),
@idade smallint

as

BEGIN
Set nocount on; --não traz nenhum retorno de linha extra;

Insert tabela_exemplo (nome,idade) values (@nome, @idade)

END

Dai в PHP, и не помню, хорошо, но это было

    $stmt = mssql_init('Nome_Procedure');

    mssql_bind($stmt, '@nome','Felipe Pena',  SQLVARCHAR,false,false,0);
    mssql_bind($stmt, '@idade ',25,SQLINT2);

 mssql_execute($stmt);
    mssql_free_statement($stmt);

Http://php.net/manual/en/function.mssql-execute.php

ПРИМЕЧАНИЕ: Хранимые Процедуры является неуязвимым, если вы не делаете что-то!

CREATE PROCEDURE getDescription
   @vname VARCHAR(50)
AS
   EXEC('SELECT description FROM products WHERE name = '''+@vname+ '''')
RETURN

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

 29
Author: Dorathoto, 2016-01-21 13:20:01

- хороший способ предотвратить инъекции SQL также уже с помощью готовых решений для этого.

Возможно, использование Frameworks Full Stacks - что, уже есть несколько готовых решений для программиста от проверок до безопасности - чтобы помочь в защите вашего приложения.

Случае не будет необходимости использования Framework Full Stack, я хотел бы выбрать для использования framework для абстракции базы данных (средств orm способом сопоставления), как Doctrine 2.

Я Говорю это, потому что Рамок как правило, предназначены также для этого типа относятся: безопасность.

 21
Author: Wallace Maxters, 2015-08-14 20:15:07

Кроме того, прекратить использование библиотеки запрещены, как уже было сказано, в качестве ответа, вы должны проверить свои запросы, чтобы иметь возможность проверить, если какой-либо из них проходит что-то чувствительное, без шифрования, если какой-либо форме его переживает, методы, GET etc.

Есть несколько методов, чтобы можно было предотвратить только от вас зависит, найти, какой из них будет лучше в вашем случае и использовании.

 10
Author: Vinicius Mesel, 2016-01-03 04:01:24

Вы Можете использовать вместе с prepared statements функция filter_var(). Но тихо, filter_var имеет несколько назначений, например:

filter_var('[email protected]', FILTER_VALIDATE_EMAIL);//retorna boolean true
filter_var('[email protected]\\', FILTER_SANITIZE_EMAIL);//retorna string "[email protected]"

Вы можете взглянуть на документации подход, о SQL-инъекции, которые вы не найдете стороны, только от взгляда на константы, которые могут быть использованы.

 9
Author: Alex, 2018-02-07 19:16:49

Я использую framework, Doctrine ORM для уровня данных. Каркасы во избежание SQL-инъекции.

На обзор Doctrine: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/getting-started.html, охватывающих установки с помощью composer и пример основы объектно-Реляционного Отображения.

На ваш вопрос, с помощью вставки продукции, документации есть пример того, на тот же случай. Это просто, и вы находится под защитой.

<?php
use Doctrine\ORM\Annotation as ORM;
/**
 * @ORM\Entity @ORM\Table(name="products")
**/
class Product
{
/** @ORM\Id @ORM\Column(type="integer") @ORM\GeneratedValue **/
protected $id;

/** @ORM\Column(type="string") **/
protected $name;

// .. (other code)
}

Вставка:

<?php
// create_product.php <name>
require_once "bootstrap.php";

$newProductName = $argv[1];

$product = new Product();
$product->setName($newProductName);

$entityManager->persist($product);
$entityManager->flush();
 5
Author: monovox, 2018-02-27 15:22:06