Как работает SQL-инъекция из & ldquo; таблиц Бобби & rdquo; XKCD комическая работа?

Инструменты непрерывной интеграции, такие как Jenkins, позволяют сохранить историю охвата тестированием и показать график, который включает тренд покрытия по сравнению с предыдущими сборками. Пример: Плагин Cobertura Jenkins

1056
задан Floern 21 March 2017 в 21:26
поделиться

9 ответов

Это отбрасывает таблицу студентов.

исходный код в программе школы, вероятно, смотрит что-то как [1 119]

q = "INSERT INTO Students VALUES ('" + FNMName.Text + "', '" + LName.Text + "')";

, Это - наивный способ добавить ввод текста в запрос и очень плохо , как Вы будете видеть.

После значений от имени, текстовое поле второго имени FNMName. Текст (который является Robert'); DROP TABLE STUDENTS; --), и текстовое поле фамилии LName. Текст (позволяют нам назвать его Derper) связывается с остальной частью запроса, результат теперь на самом деле два запроса разделен разделитель оператора (точка с запятой). Второй запрос был , ввел в первое. Когда код выполнит этот запрос против базы данных, это будет похоже на это

INSERT INTO Students VALUES ('Robert'); DROP TABLE Students; --', 'Derper')

, который, без обиняков, примерно переводит в два запроса:

Добавляют, что новая запись на таблицу Students со значением Имени 'Robert'

и

Удаляет таблицу

Students, Все мимо второго запроса отмечено как комментарий : --', 'Derper')

' на имя студента не комментарий, это - закрытие строковый разделитель . Так как имя студента является строкой, необходимо синтаксически завершить гипотетический запрос. Инжекция набрасывается только на работу , когда SQL-запрос они вводят результаты в допустимом SQL.

<глоток> <глоток>, Отредактированный снова согласно dan04 проницательный комментарий

1077
ответ дан 20 revs, 9 users 72% 21 March 2017 в 21:26
поделиться

Нет, ' не комментарий в SQL, а разделитель.

мама предположила, что программист баз данных выполнил сходство с запроса:

INSERT INTO 'students' ('first_name', 'last_name') VALUES ('$firstName', '$lastName');

(например), для добавления нового студента, где $xxx переменное содержание был взят непосредственно из HTML-формы, не проверяя формат, ни выйдя из специальных символов.

Поэтому, если $firstName содержит Robert'); DROP TABLE students; --, программа базы данных выполнит следующий запрос непосредственно на DB:

INSERT INTO 'students' ('first_name', 'last_name') VALUES ('Robert'); DROP TABLE students; --', 'XKCD');

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

Mmm, я являюсь слишком медленным, я уже вижу 8 ответов перед моим в оранжевой ленте...:-), популярная тема, это кажется.

70
ответ дан MikeMitchell 21 March 2017 в 21:26
поделиться

Одинарная кавычка является запуском и концом строки. Точка с запятой является концом оператора. Таким образом, если они делали выбор как это:

Select *
From Students
Where (Name = '<NameGetsInsertedHere>')

SQL стал бы:

Select *
From Students
Where (Name = 'Robert'); DROP TABLE STUDENTS; --')
--             ^-------------------------------^

В некоторых системах, эти select добрался бы, работал сначала сопровождаемый drop оператор! Сообщение: не ВСТРАИВАЙТЕ ЗНАЧЕНИЯ В СВОЙ SQL. Вместо этого используйте параметры!

25
ответ дан Robert Koritnik 21 March 2017 в 21:26
поделиться

Скажем, имя использовалось в переменной, $Name. Вы тогда выполняете этот запрос:

INSERT INTO Students VALUES ( '$Name' )

код по ошибке помещает что-либо пользователь, предоставленный как переменная. Вы хотели, чтобы SQL был:

ЗНАЧЕНИЯ Студентов INSERT INTO (' Robert Tables ')

, Но умный пользователь могут предоставить то, что они хотят:

ЗНАЧЕНИЯ Студентов INSERT INTO (' Robert'); Студенты DROP TABLE; - ')

то, Что Вы получаете:

INSERT INTO Students VALUES ( 'Robert' );  DROP TABLE STUDENTS; --' )

-- только комментарии остаток от строки.

586
ответ дан Ian Boyd 21 March 2017 в 21:26
поделиться

Скажите наивную запись студенческого метода создания как это:

void createStudent(String name) {
    database.execute("INSERT INTO students (name) VALUES ('" + name + "')");
}

И кто-то вводит имя Robert'); DROP TABLE STUDENTS; --

, на Чем работают, база данных является этим запросом:

INSERT INTO students (name) VALUES ('Robert'); DROP TABLE STUDENTS --')

точка с запятой заканчивает команду вставки и запускает другого; - комментирует остальную часть строки. Команда DROP TABLE выполняется...

Поэтому связывают параметры, хорошая вещь.

28
ответ дан Dan Vinton 21 March 2017 в 21:26
поделиться

Писатель базы данных, вероятно, сделал

sql = "SELECT * FROM STUDENTS WHERE (STUDENT_NAME = '" + student_name + "') AND other stuff";
execute(sql);

, Если student_name является одним данным, который делает выбор с именем "Robert" и затем отбрасывает таблицу. "-" часть изменяет остальную часть данного запроса в комментарий.

16
ответ дан Paul Tomblin 21 March 2017 в 21:26
поделиться

'); концы запрос, это не запускает комментарий. Тогда это отбрасывает таблицу студентов и комментирует остальную часть запроса, который, как предполагалось, выполнялся.

17
ответ дан Peter Mortensen 21 March 2017 в 21:26
поделиться

' символ в SQL используется для строковых констант. В этом случае это используется для окончания строковой константы а не для комментария.

15
ответ дан Peter Mortensen 21 March 2017 в 21:26
поделиться

В этом случае, 'не символ комментария. Это используется для разграничивания строковых литералов. Комический художник полагается на идею, что рассматриваемая школа имеет динамический sql где-нибудь, который выглядит примерно так:

$sql = "INSERT INTO `Students` (FirstName, LastName) VALUES ('" . $fname . "', '" . $lname . "')";

Поэтому теперь' символ заканчивает строковый литерал, прежде чем программист ожидал его. Объединенный с; символ для окончания оператора взломщик может теперь добавить любой sql, который они хотят. - комментируют в конце, должен удостовериться, что любой остающийся sql в исходном операторе не препятствует тому, чтобы запрос компилировал на сервере.

FWIW, я также думаю, что у рассматриваемого комика есть важная деталь неправильно: если Вы думаете [приблизительно 111] очистка Ваши исходные данные базы данных, как комик предполагает, Вы все еще делаете ее неправильно. Вместо этого необходимо думать с точки зрения изоляция исходные данные базы данных и корректный способ сделать, это через параметризированные запросы.

16
ответ дан Joel Coehoorn 21 March 2017 в 21:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: