Уникання введення SQL без параметрів


109

У нас тут ще одна дискусія на роботі щодо використання параметризованих запитів sql у нашому коді. У дискусії у нас є дві сторони: я та деякі інші, які кажуть, що ми завжди повинні використовувати параметри для захисту від sql ін'єкцій та інших хлопців, які не вважають це за потрібне. Натомість вони хочуть замінити одиничні апострофи двома апострофами у всіх рядках, щоб уникнути sql ін'єкцій. Наші бази даних працюють на Sql Server 2005 або 2008, а наша база коду працює на .NET Framework 2.0.

Дозвольте навести простий приклад на C #:

Я хочу, щоб ми використовували це:

string sql = "SELECT * FROM Users WHERE Name=@name";
SqlCommand getUser = new SqlCommand(sql, connection);
getUser.Parameters.AddWithValue("@name", userName);
//... blabla - do something here, this is safe

Хоча інші хлопці хочуть це зробити:

string sql = "SELECT * FROM Users WHERE Name=" + SafeDBString(name);
SqlCommand getUser = new SqlCommand(sql, connection);
//... blabla - are we safe now?

Де функція SafeDBString визначена наступним чином:

string SafeDBString(string inputValue) 
{
    return "'" + inputValue.Replace("'", "''") + "'";
}

Тепер, поки ми використовуємо SafeDBString для всіх значень рядків у наших запитах, ми повинні бути в безпеці. Правильно?

Для використання функції SafeDBString є дві причини. По-перше, це так, як це робилося з віків каменю, а по-друге, простіше налагоджувати оператори sql, оскільки ви бачите запит розкопок, який виконується в базі даних.

Так то. Моє запитання - чи дійсно достатньо використовувати функцію SafeDBString, щоб уникнути атак нападів на sql. Я намагався знайти приклади коду, який порушує цей захід безпеки, але не можу знайти жодного прикладу цього.

Хтось там може зламати це? Як би ти це зробив?

EDIT: Для підведення підсумків відповідей поки що:

  • Ще ніхто не знайшов способу обійти SafeDBString на Sql Server 2005 або 2008. Це добре, я думаю?
  • У кількох відповідях зазначено, що ви отримуєте підвищення продуктивності, використовуючи параметризовані запити. Причина полягає в тому, що плани запитів можна використовувати повторно.
  • Ми також погоджуємось, що за допомогою параметризованих запитів надається більш читабельний код, який легше підтримувати
  • Крім того, простіше завжди використовувати параметри, ніж використовувати різні версії SafeDBString, перетворення рядка в число та рядки на дату.
  • Використовуючи параметри, ви отримуєте автоматичне перетворення типів, що особливо корисно, коли ми працюємо з датами чи десятковими числами.
  • І нарешті: не намагайтеся захистити себе так, як писав JulianR. Постачальники баз даних витрачають багато часу та грошей на безпеку. Немає способів зробити це краще, і немає причин намагатися виконувати їхню роботу.

Тому, хоча ніхто не зміг зламати просту безпеку функції SafeDBString, у мене з’явилося багато інших хороших аргументів. Дякую!


16
Ваші колеги - це шлях, шлях, база. Киньте виклик, щоб вони знайшли частину літератури на підтвердження своєї позиції. Аргумент ex neolithos є смішним, все змінюється, лише людина, що застрягла в кам'яному віці, не змогла б адаптуватися.
annakata

1
Ну, принаймні, ваші колеги захищають від ONE з різних форм злому ... Чи впевнені вони, що всі параметризовані запити роблять? (Я не ...)
Арджан Ейнбу

1
Будь-яка вразливість не переконає їх. Якщо ви виявите кілька вразливих ситуацій (про що ви запитуєте) та інші проблеми та вкажете по черзі, що параметри вирішать цю проблему, і що ваша команда повинна буде написати гори коду, щоб забезпечити частину функціоналу, ви можете перемогти їх. Удачі.
Роберт Гоуленд

3
Навіть без одиничних лапок, ви все одно можете зламати свій код логікою. Спробуйте скористатись ім'ям користувача "тест АБО 1 = 1" - ви отримаєте всі рядки повернені, а не лише те, з тестом імені користувача!
Міст

1
Зітхнути. Я дійсно не розумію, як нам як галузі вдається продовжувати терпіти подібну непрофесійну поведінку.
jeroenh

Відповіді:


83

Я думаю, що правильна відповідь:

Не намагайтеся робити безпеку самостійно . Використовуйте будь-яку надійну, галузеву стандартну бібліотеку, доступну для того, що ви намагаєтеся зробити, а не намагатися зробити це самостійно. Які б припущення щодо безпеки ви не мали, вони можуть бути помилковими. Настільки безпечним, як може виглядати ваш власний підхід (а він у кращому випадку виглядає хитким), є ризик, що ви щось не помічаєте, і чи дійсно хочете ризикнути, коли справа стосується безпеки?

Використовуйте параметри.


Повторно "Використовуйте будь-яку надійну, галузеву стандартну бібліотеку" - ви можете порекомендувати її для .NET? Може бути більше, ніж залежно від БД: SQLServer, MySQL, PostgreSQL? Я шукав SQL-дезінфікуючий засіб, але без особливого шансу, тому hsve був змушений реалізувати своє, як найкраще можу (що, без сумніву, далеко не дурний).
ПСУ

72

І тоді хтось іде і використовує "замість". Параметри - ІМО - єдиний безпечний шлях.

Це також дозволяє уникнути безлічі проблем, пов'язаних з датами / номерами i18n; яка дата 01.02.03? Скільки коштує 123 456? Чи згодні ваші сервери (додаток-сервер і db-сервер)?

Якщо фактор ризику для них не переконливий, як щодо ефективності? RDBMS може повторно використовувати план запитів, якщо ви використовуєте параметри, що сприяють продуктивності. Це не може зробити лише за допомогою рядка.


Я спробував аргументи форматування та продуктивності, але вони все ще не впевнені.
Руна Грімстад

5
Насправді сервер sql може повторно використовувати план запитів, використовуєте ви параметри чи ні. Я погоджуюся з іншими аргументами, але для більшості випадків аргумент продуктивності для параметризованого sql більше не летить.
tnyfst

1
@tnyfst: він може повторно використовувати план виконання, коли рядок запиту змінюється для кожної комбінації значень параметрів? Я не вважав, що це можливо.
Джон Сондерс

4
План запиту буде повторно використаний, якщо текст запиту є ІДЕНТИЧНИМ для попереднього тексту запиту. Тож якщо ви надішліть ЗАЯВКУ РОЗПОВІЛЬНОГО ТОЖОГО ж, він буде повторно використаний. Однак якщо ви зміните навіть просто пробіл, кому чи щось таке, потрібно буде визначити новий план запитів.
marc_s

1
@Marc: Я не впевнений, що ти абсолютно правильний. Гуеристика кешування керованих серверів трохи дивна. Аналізатор здатний ідентифікувати константи в тексті і може перетворити рядок SQL в параметри використання штучно. Потім він може вставити в кеш текст цього нового параметризованого запиту. Наступний аналогічний SQL може знайти свою параметризовану версію, узгоджену в кеші. Однак параметризовані версії не завжди використовуються з кешованими оригінальними версіями SQL, я підозрюю, що SQL має мільйон причин, пов'язаних з продуктивністю, щоб вибрати між двома підходами.
AnthonyWJones

27

Аргумент - безрезультатний. Якщо вам все-таки вдасться знайти вразливість, ваші співробітники просто змінять функцію SafeDBString для її обліку, а потім попросять підтвердити, що це знову небезпечно.

Зважаючи на те, що параметризовані запити - це безперечна найкраща практика програмування, тягар доказування повинен бути на них, щоб вони пояснили, чому вони не використовують метод, який є і безпечнішим, і ефективнішим.

Якщо проблема переписує весь застарілий код, простим компромісом було б використовувати параметризовані запити у всьому новому коді та рефакторний старий код, щоб використовувати їх під час роботи над цим кодом.

Я гадаю, що справжнє питання - це гордість і впертість, і ви не можете з цим зробити багато іншого.


19

Перш за все, ваш зразок для версії "Замінити" неправильний. Потрібно поставити апострофи навколо тексту:

string sql = "SELECT * FROM Users WHERE Name='" + SafeDBString(name) & "'";
SqlCommand getUser = new SqlCommand(sql, connection);

Тож це ще одна параметрія, яка робиться для вас: вам не потрібно турбуватися про те, чи потрібно значення включати в лапки. Звичайно, ви можете вбудувати це у функцію, але тоді вам потрібно додати багато складності функції: як знати різницю між "NULL" як null та "NULL" як просто рядок, або між числом і рядок, який просто так містить багато цифр. Це просто ще одне джерело для помилок.

Інша справа: ефективність: параметризовані плани запитів часто кешуються краще, ніж об'єднані плани, таким чином, можливо, збереження сервера кроком під час запуску запиту.

Крім того, уникнути одинарних цитат недостатньо. Багато продуктів DB дозволяють альтернативні методи втечі символів, якими може скористатися зловмисник. Наприклад, у MySQL ви можете уникнути однієї цитати за допомогою зворотної косої риски. Отже, наступне значення "ім'я" підірве MySQL лише SafeDBString()функцією, тому що при подвоєнні одинарної цитати перша з них все ще залишається зворотною косою рисою, залишаючи другу "активною":

x \ 'АБО 1 = 1; -


Також JulianR пропонує гарний момент нижче: НІКОЛИ не намагайтеся самостійно працювати над охороною. Так легко помилитися з програмуванням безпеки невловимими способами, які, здається, працюють, навіть при ретельному тестуванні. Потім проходить час, і через рік ви дізнаєтесь, що ваша система зламалася півроку тому, і ви ніколи навіть цього не знали.

Завжди якомога більше покладайтеся на бібліотеки безпеки, надані для вашої платформи. Вони будуть написані людьми, які роблять код безпеки на життя, набагато краще перевірений, ніж те, чим ви можете керувати, та обслуговує постачальник, якщо виявиться вразливість.


5
Функція заміни додає апострофи
Руна Грімстад,

5
Тоді це лише ще одне джерело помилок. Як дізнатися різницю між NULL як нульовим значенням та NULL як текстовим рядком? Або між введенням числа і рядком, який, як раз, містить цифри?
Джоель Куехорн

Гарна думка. Ви повинні використовувати функцію лише для рядків і, можливо, дат, тому вам слід бути обережними. Це ще одна причина використання параметрів! Так!
Руна Грімстад,

10

Тому я б сказав:

1) Чому ви намагаєтесь знову реалізувати щось, що вбудовано? він там доступний, простий у користуванні та вже налагоджений у глобальному масштабі. Якщо в ньому знайдуться майбутні помилки, вони будуть виправлені та доступні для всіх дуже швидко, без цього вам нічого робити.

2) Які процеси існують, щоб гарантувати, що ви ніколи не пропустите виклик SafeDBString? Відсутність його лише в одному місці може відкрити цілу низку питань. Скільки ви збираєтеся заглянути на ці речі, і подумайте, скільки витрачено даремно зусиль, коли прийняту правильну відповідь так легко дістати.

3) Наскільки ви впевнені, що ви прикривали кожен вектор атаки, про який Microsoft (автор БД та бібліотеку доступу) знає у вашій реалізації SafeDBString ...

4) Наскільки легко читати структуру sql? У прикладі використовується + конкатенація, параметри дуже схожі на string.Format, який є більш читабельним.

Крім того, є два способи опрацювати те, що було насправді запущено - прокрутити власну функцію LogCommand, просту функцію, яка не стосується безпеки , або навіть подивитися на sql слід, щоб розібратися з тим, що думає, що база даних насправді відбувається.

Наша функція LogCommand проста:

    string LogCommand(SqlCommand cmd)
    {
        StringBuilder sb = new StringBuilder();
        sb.AppendLine(cmd.CommandText);
        foreach (SqlParameter param in cmd.Parameters)
        {
            sb.Append(param.ToString());
            sb.Append(" = \"");
            sb.Append(param.Value.ToString());
            sb.AppendLine("\"");
        }
        return sb.ToString();
    }

Правильно чи неправильно, він дає нам необхідну інформацію без проблем безпеки.


1
Йому, мабуть, доводиться мати справу з купою старих програмістів VBSCRIPT, які звикли робити все, в тому числі XML та SQL, шляхом об'єднання рядків. Це будуть люди, які лякаються використання API. З ними нічого не можна зробити, принаймні нічого гуманного.
Джон Сондерс

1
+1 для елемента №2, за винятком того, що реальні параметри також не застосовуються.
Joel Coehoorn

7

Завдяки параметризованим запитам ви отримуєте більше, ніж захист від введення sql. Ви також отримаєте кращий потенціал кешування плану виконання. Якщо ви використовуєте профайлер запитів на сервер sql, ви все ще можете побачити "точний sql, який запускається в базі даних", тож ви насправді нічого не втрачаєте з точки зору налагодження ваших заяв sql.


MySQL також реєструє параметризовані запити з інтерпольованими в них параметрами парам.
Білл Карвін

5

Я використовував обидва підходи, щоб уникнути атак ін'єкцій SQL і, безумовно, віддаю перевагу параметризованим запитам. Коли я використовую об'єднані запити, я використовував функцію бібліотеки, щоб уникнути змінних (наприклад, mysql_real_escape_string) і не був би впевнений, що я охопив все у власній реалізації (як здається, ви теж є).


2
+1, тому що mysql_real_escape_string () уникає \ x00, \ x1a, \ n \ r 'і ". Він також обробляє проблеми з набором символів. Наївна функція співробітників ОП нічого з цього не робить!"
Білл Карвін

4

Ви не можете легко здійснити будь-яку перевірку типу вводу користувача без використання параметрів.

Якщо ви використовуєте класи SQLCommand і SQLParameter для здійснення дзвінків у БД, ви все ще можете бачити SQL-запит, який виконується. Подивіться на властивість SQLCommand's CommandText.

Я завжди підозрюваний у власному підході до запобігання ін'єкції SQL, коли параметризовані запити настільки прості у використанні. По-друге, тільки те, що "це робилося завжди так" не означає, що це правильний спосіб зробити це.


3

Це безпечно лише в тому випадку, якщо ви гарантовано передаєте рядок.

Що робити, якщо в якийсь момент ви не проходите рядок? Що робити, якщо ви пройдете лише номер?

http://www.mywebsite.com/profile/?id=7;DROP DATABASE DB

Зрештою, став би:

SELECT * FROM DB WHERE Id = 7;DROP DATABASE DB

Це або рядок, або число. Рядок уникнути за допомогою SafeDbString. Число - це Int32, і воно не може скидати бази даних.
Андомар

Цифри легше обробляти. Ви просто конвертуєте параметр у int / float / будь-що перед тим, як використовувати його у запиті. Проблема полягає в тому, коли ви повинні прийняти рядкові дані.
Руна Грімстад

Andomar - якщо ви просто створюєте оператор SQL вручну, тоді він призначений для "типу" не має значення, ви можете вводити SQL з числом дуже і дуже легко. Руна - Я думаю, що це занадто багато покладається на окремого розробника, щоб пам’ятати всі нюанси ручного вирішення інжекції SQL. Якщо ви просто скажете "використовувати параметри", це дуже просто, і вони не можуть помилитися.
joshcomley

@Andomar: А що з NULL? Або рядки, схожі на числа?
Joel Coehoorn

2

Я б використовував збережені процедури або функції для всього, тому питання не виникало б.

Там, де мені потрібно вводити SQL в код, я використовую параметри, це єдине, що має сенс. Нагадуйте іншим особам, що хакери розумніші, ніж вони, і з більшим стимулом порушувати код, який намагається їх перехитрити. Використовуючи параметри, це просто неможливо, і це не так, як важко.


Добре, як зробити інжекцію SQL за допомогою параметрів?
Джон Сондерс

@Saunders: Крок 1 - знайти помилку переповнення буфера у функціональності обробки параметрів вашої БД.
Брайан

2
Знайшли ще одного? У комерційній БД, яку щодня забивають сотні тисяч хакерів? Один, зроблений програмною компанією, яка, як відомо, має дуже глибокі кишені? Ви могли б процитувати позов по імені, якби це було можливо.
Джон Сондерс

1
Звичайно, якщо SPROC використовує конкатенацію та EXEC (замість sp_ExecuteSQL), ти знову опинився в біді ... (Я бачив, що це робив неправильно занадто багато разів, щоб знизити його ...)
Марк Гравелл

2

Дуже погоджуйтеся з питань безпеки.
Ще одна причина використання параметрів - це ефективність.

Бази даних завжди будуть збирати ваш запит і кешувати його, а потім повторно використовувати кешований запит (що, очевидно, швидше для наступних запитів). Якщо ви використовуєте параметри, то навіть якщо ви використовуєте різні параметри, база даних повторно використовуватиме ваш кешований запит, оскільки він відповідає на основі рядка SQL перед прив'язкою параметрів.

Якщо ви не прив'язуєте параметри, то рядок SQL змінюється в кожному запиті (який має різні параметри), і він ніколи не буде відповідати тому, що є у вашому кеші.


2

З наведених причин параметри є дуже хорошою ідеєю. Але ми ненавидимо їх використовувати, оскільки створення парамуму та присвоєння його імені змінній для подальшого використання в запиті - це потрійна аварія голови.

Наступний клас обгортає програму stringbuilder, яку ви зазвичай використовуєте для створення запитів SQL. Це дозволяє писати параматеризовані запити без необхідності створювати параметр , щоб ви могли сконцентруватися на SQL. Ваш код буде виглядати приблизно так ...

var bldr = new SqlBuilder( myCommand );
bldr.Append("SELECT * FROM CUSTOMERS WHERE ID = ").Value(myId, SqlDbType.Int);
//or
bldr.Append("SELECT * FROM CUSTOMERS WHERE NAME LIKE ").FuzzyValue(myName, SqlDbType.NVarChar);
myCommand.CommandText = bldr.ToString();

Читання коду, я сподіваюся, ви погоджуєтесь, значно покращується, і вихід є належним параметризованим запитом.

Клас виглядає приблизно так ...

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;

namespace myNamespace
{
    /// <summary>
    /// Pour le confort et le bonheur, cette classe remplace StringBuilder pour la construction
    /// des requêtes SQL, avec l'avantage qu'elle gère la création des paramètres via la méthode
    /// Value().
    /// </summary>
    public class SqlBuilder
    {
        private StringBuilder _rq;
        private SqlCommand _cmd;
        private int _seq;
        public SqlBuilder(SqlCommand cmd)
        {
            _rq = new StringBuilder();
            _cmd = cmd;
            _seq = 0;
        }
        //Les autres surcharges de StringBuilder peuvent être implémenté ici de la même façon, au besoin.
        public SqlBuilder Append(String str)
        {
            _rq.Append(str);
            return this;
        }
        /// <summary>
        /// Ajoute une valeur runtime à la requête, via un paramètre.
        /// </summary>
        /// <param name="value">La valeur à renseigner dans la requête</param>
        /// <param name="type">Le DBType à utiliser pour la création du paramètre. Se référer au type de la colonne cible.</param>
        public SqlBuilder Value(Object value, SqlDbType type)
        {
            //get param name
            string paramName = "@SqlBuilderParam" + _seq++;
            //append condition to query
            _rq.Append(paramName);
            _cmd.Parameters.Add(paramName, type).Value = value;
            return this;
        }
        public SqlBuilder FuzzyValue(Object value, SqlDbType type)
        {
            //get param name
            string paramName = "@SqlBuilderParam" + _seq++;
            //append condition to query
            _rq.Append("'%' + " + paramName + " + '%'");
            _cmd.Parameters.Add(paramName, type).Value = value;
            return this; 
        }

        public override string ToString()
        {
            return _rq.ToString();
        }
    }
}

1

З дуже короткого часу, коли мені довелося досліджувати проблеми з ін'єкцією SQL, я можу бачити, що зробити значення "безпечним" також означає, що ви закриваєте двері у ситуаціях, коли ви можете насправді захотіти апостроф у своїх даних - а що з чиїмсь іменем , наприклад, O'Reilly.

Це залишає параметри та збережені процедури.

І так, ви завжди повинні намагатися реалізовувати код найкращим чином, який ви знаєте зараз - не тільки як це робилося завжди.


Подвійні апострофи будуть переведені сервером sql в єдиний апостроф, тому O'Reilly буде переведено на Name = 'O''Reilly'
Руна Грімстад,

Так чи є відповідна функція для видалення апострофів, коли користувач хоче побачити їх дані?
quamrana

Нема потреби. Послідовність виходу дозволяє аналізатору бачити одну цитату, а не кінець рядка. Під час синтаксичного розбору він сприймається ''як буквальний ', тому ваша рядок буде розглядатися внутрішньо як послідовність символів O'Reilly. Ось що БД буде зберігати, витягувати, порівнювати тощо. Якщо ви хочете показати користувачеві їхні дані після того, як ви його уникнули, збережіть копію нерозміщеного додатку рядка.
cHao

1

Ось кілька статей, які можуть вам стати корисними для переконання своїх колег.

http://www.sommarskog.se/dynamic_sql.html

http://unixwiz.net/techtips/sql-injection.html

Особисто я вважаю за краще ніколи не дозволяти жодному динамічному коду торкатися моєї бази даних, вимагаючи, щоб весь контакт був через sps (а не той, який використовує динамічний SQl). Це означає, що нічого, крім того, що я дав дозвіл користувачам, не можна зробити, і що внутрішні користувачі (за винятком тих, хто має доступ до виробництва для цілей адміністратора) не можуть безпосередньо отримати доступ до моїх таблиць і створювати хаос, красти дані або вчиняти шахрайство. Якщо у вас є фінансова заявка, це найбезпечніший шлях.


1

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

Один, який вже виховувався, - це помилка переповнення / усічення, яку можна використовувати.

Іншим майбутнім засобом буде пошук помилок, подібних до інших баз даних - наприклад, стек MySQL / PHP зазнав проблему, оскільки певні послідовності UTF8 можуть використовуватися для маніпулювання функцією заміни - функція заміни буде вводити введення введення символів ін'єкції.

Зрештою, механізм захисту заміни покладається на очікуване, але не призначене функціонал. Оскільки функціональність не була цільовим призначенням коду, існує велика ймовірність того, що якась виявлена ​​химерність порушить вашу очікувану функціональність.

Якщо у вас є багато застарілого коду, метод заміни може бути використаний як зупинка, щоб уникнути тривалого переписування та тестування. Якщо ви пишете новий код, виправдання немає.


1

Завжди використовуйте параметризовані запити, де це можливо. Іноді навіть просте введення даних без використання будь-яких дивних символів вже може створити SQL-ін'єкцію, якщо її не визначено як вхід для поля в базі даних.

Тому просто нехай база даних робить свою роботу з визначення самого введення, не кажучи вже про це, також економить багато клопоту, коли вам потрібно фактично вставити дивні символи, які в іншому випадку не вдалося б уникнути або змінити. Це навіть може зберегти якийсь цінний час виконання в кінці кінців за те, що не потрібно обчислювати вхідні дані.


1

Я не бачив, щоб інші відповідачі зверталися до цієї сторони "чому це робити самостійно - це погано", але врахуйте атаку скорочення SQL .

Існує також QUOTENAMEфункція T-SQL, яка може бути корисною, якщо ви не можете переконати їх у використанні парам. Це наздоганяє багато (все?) Проблем, які врятувались qoute.


1

2 роки пізніше я повторно відновив ... Кожен, хто знаходить параметри болі, може спробувати моє розширення VS, QueryFirst . Ви редагуєте свій запит у реальному .sql-файлі (Validation, Intellisense). Щоб додати параметр, просто введіть його безпосередньо у свій SQL, починаючи з "@". Коли ви зберігаєте файл, QueryFirst буде генерувати класи обгортки, щоб ви могли запустити запит і отримати доступ до результатів. Він буде шукати тип БД вашого параметра і відображатиме його до типу .net, який ви знайдете як вхід до створеного методу Execute ().Не може бути простішим. Зробити це правильним способом радикально швидше і простіше, ніж зробити це будь-яким іншим способом, а створити вразливість sql для ін'єкцій стає неможливим або, принаймні, збочно важким. Є й інші переваги вбивці, такі як можливість видалення стовпців у БД та негайно побачити помилки компіляції у вашій програмі.

юридична відмова: Я написав QueryFirst


0

Ось кілька причин використовувати параметризовані запити:

  1. Безпека - Шар доступу до бази даних знає, як видалити або видалити елементи, заборонені в даних.
  2. Розділення проблем - Мій код не несе відповідальності за перетворення даних у формат, який подобається БД.
  3. Ніяких надмірностей - мені не потрібно включати збірку чи клас у кожен проект, який виконує форматування / видалення цієї бази даних; він вбудований у бібліотеку класів.

0

Уразливості (не можу пригадати, для якої бази даних це було) було мало, що пов'язано з переповненням буфера оператора SQL.

Я хочу сказати, що SQL-Injection - це більше, ніж просто "уникнути цитати", і ви не маєте уявлення, що буде далі.


0

Ще одне важливе питання - це відстеження втечених та нерозроблених даних. Існує багато і багато додатків, Web та інше, які, здається, не належним чином відслідковують, коли дані є необробленими - Unicode, & -кодировані, відформатовані HTML та ін. Очевидно, що буде важко відслідковувати, які рядки - ''кодовані, а які - ні.

Це також проблема, коли ви в кінцевому підсумку змінюєте тип якоїсь змінної - можливо, вона раніше була цілим числом, але тепер це рядок. Тепер у вас є проблема.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.