![]() |
|
|||
WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
SQLite никогда не должен переполнять буфер, допускать утечки памяти
или показывать любое другое вредное поведение, даже когда получает
злонамеренно уродливые входы SQL или файлы базы данных. SQLite должен всегда
обнаруживать ошибочные входы и поднимать ошибку, не падать или портить
память. Любой сбой, вызванный входом SQL или файлом базы данных, считают
серьезной ошибкой и быстро исправят. SQLite экстенсивно проверен, чтобы
помочь гарантировать, что он стоек к этим видам ошибок. Тем не менее, ошибки происходят. Если вы пишете применение, которое
посылает входы SQL, которым не доверяют, или файлы базы данных к SQLite, есть
дополнительные шаги, которые можно сделать, чтобы помочь уменьшить
поверхность атаки и предотвратить деяния нулевого дня,
вызванные необнаруженными ошибками. Приложения, которые принимают входы SQL, которым не доверяют, должны
принять следующие меры предосторожности: Установить флаг
SQLITE_DBCONFIG_DEFENSIVE. Это предотвращает обычные SQL-операторы от
преднамеренного развращения файла базы данных. SQLite должен быть
доказательством против нападений, которые включают злонамеренные входы SQL
и злонамеренно испорченный файл базы данных в то же время.
Тем не менее, отрицание доступа нападавшего только для сценария, чтобы
испортить входы базы данных обеспечивает дополнительный слой защиты. Уменьшите лимиты,
которые SQLite накладывает на входы. Это может помочь предотвратить атаки
denial of service и другие виды вреда, который может произойти в результате
необычно больших входов. Можно сделать это во время компиляции, используя
опции -DSQLITE_MAX_... или во время выполнения, используя
sqlite3_limit().
Большинство запросов может уменьшить пределы существенно, не влияя на
функциональность. Приведенная ниже таблица обеспечивает некоторые
предложения, хотя точные значения изменяются в зависимости от применения: Рассмотрите использование
sqlite3_set_authorizer(), чтобы ограничить объем SQL, который будет
обработан. Например, применение, которое не должно изменять схему базы
данных, могло бы добавить sqlite3_set_authorizer(),
который заставляет любой CREATE или DROP терпеть неудачу. Язык SQL очень силен, и таким образом, для злонамеренных входов SQL
(или ошибочных входов SQL, вызванных прикладной ошибкой) всегда возможно
представить SQL, который работает
в течение очень долгого времени. Чтобы препятствовать тому, чтобы это стало
атакой denial-of-service, рассмотрите использование
sqlite3_progress_handler(),
чтобы периодически вызывать отзыв, когда каждый SQL-оператор работает
и получить возвращение отзыва, отличное от нуля, чтобы прервать запрос, если
он работает слишком долго. Альтернативно, установите таймер в отдельном
потоке и вызовите
sqlite3_interrupt(), когда таймер кончится, чтобы препятствовать тому,
чтобы SQL-оператор работал вечно. Ограничьте максимальный объем памяти, что SQLite ассигнует,
использованием
sqlite3_hard_heap_limit64(). Это помогает предотвратить атаки
denial-of-service. Чтобы узнать, в каком количестве пространство
"кучи" на самом деле нужно, выполните это для типичных входов и
затем измерьте максимальное мгновенное использование памяти с
sqlite3_memory_highwater().
Установите жесткий предел кучи к максимальному наблюдаемому мгновенному
использованию памяти плюс некоторый запас. Рассмотрите урегулирование выбора времени компиляции
SQLITE_MAX_ALLOCATION_SIZE
к чему-то меньшему, чем его значение по умолчанию 2147483391 (0x7ffffeff).
Значение 100000000 (100 миллионов) или еще меньше не было бы неблагоразумно,
в зависимости от применения. Для встроенных систем расмотрите компилирование SQLite с опцией
-DSQLITE_ENABLE_MEMSYS5
и затем предоставлением SQLite с фиксированным куском памяти, чтобы
использовать в качестве кучи через
sqlite3_config(
SQLITE_CONFIG_HEAP). Это будет препятствовать тому, чтобы злонамеренный
SQL выполнил атаку denial-of-service при помощи чрезмерного объема памяти.
Если (говорят), что 5 МБ памяти предусмотрены SQLite, чтобы использовать,
как только так много потреблялось, SQLite начнет возвращать ошибки
SQLITE_NOMEM вместо того, чтобы впитать память, необходимую другим частям
применения. Это также распределит память песочниц SQLite
так, чтобы write-free ошибка в некоторой другой части приложения не вызывала
проблемы для SQLite или наоборот.
Для контроля использования памяти в
To control memory usage in the
SQL-функции printf() скомпилируйте с
"
-DSQLITE_PRINTF_PRECISION_LIMIT=100000"
или некоторой столь же подходящей
стоимостью. Этот #define ограничивает ширину и точность для
%-подстановок в функции printf() и таким образом препятствует тому, чтобы
враждебный SQL-оператор потреблял большие суммы RAM через такие конструкции,
как "printf('%1000000000s','hi')". Обратите внимание на то, что SQLite использует свой встроенный printf()
внутренне, чтобы помочь ему отформатировать sql-колонку в
таблице sqlite_schema.
По этой причине никакие таблица, триггер, индекс или представление
не могут быть намного больше, чем предел точности. Можно установить предел
точности меньше чем 100000, но быть осторожными, так как независимо от того,
какой предел точности вы используете, он должен быть по крайней мере как
самый длинный запрос CREATE в вашей схеме. Запросы, которые читают или пишут файлы базы данных SQLite неопределенного
происхождения, должны принять меры предосторожности перечисленные ниже. Даже если применение сознательно не принимает файлы базы данных из
источников, которым не доверяют, надо остерегаться нападений, в которых
изменен файл локальной базы данных. Для лучшей безопасности любой файл базы
данных, который, возможно, когда-либо был перезаписываем агентом в другом
домене защиты, нужно рассматривать как подозреваемый. Если применение включает какие-либо
свои функции SQL или
виртуальные таблицы,
у которых есть побочные эффекты, или это могло бы пропустить секретную
информацию, то применение должно использовать один или больше методов ниже,
чтобы предотвратить злонамеренно созданную схему базы данных от тайного
управления теми функциями SQL и/или виртуальными таблицами в низких целях: Если применение не использует триггеры или обзоры, рассмотрите
отключение неиспользованных возможностей с: Для чтения файлов базы данных, которые необычно рискованны, таковы как
файлы базы данных, которые получены от отдаленных машин, и возможно от
анонимных участников, могли бы быть оправданы следующие дополнительные меры
предосторожности. Эта добавленная обороноспособность идет с затратами на
производительность, однако, и может быть
несоответствующей в каждой ситуации:
Выполните
PRAGMA integrity_check или
PRAGMA quick_check
на базе данных как первый SQL-оператор после открытия файлов базы данных и до
управления любыми другими SQL-операторами. Отклоните и откажитесь
обрабатывать любой файл базы данных, содержащий ошибки. Включите
PRAGMA cell_size_check=ON. Не позволяйте I/O с отображенной памятью.
Другими словами, удостоверьтесь, что
PRAGMA mmap_size=0. Меры предосторожности выше не требуются, чтобы использовать SQLite
безопасно с потенциально враждебными входами. Однако, они действительно
обеспечивают дополнительный слой защиты против деяний нулевого дня и
поощряются для запросов, которые передают данные из источников, которым
не доверяют, в SQLite.
Choose any three.
1.
SQLite всегда утверждает свои входы
1.1.
Входы SQL, которым не доверяют
Значение лимита По умолчанию Более безопасный вариант
LIMIT_LENGTH 1,000,000,000
1,000,000
LIMIT_SQL_LENGTH 1,000,000,000
100,000
LIMIT_COLUMN 2,000
100
LIMIT_EXPR_DEPTH 1,000
10
LIMIT_COMPOUND_SELECT 500
3
LIMIT_VDBE_OP 250,000,000
25,000
LIMIT_FUNCTION_ARG 127
8
LIMIT_ATTACH 10
0
LIMIT_LIKE_PATTERN_LENGTH 50,000
50
LIMIT_VARIABLE_NUMBER 999
10
LIMIT_TRIGGER_DEPTH 1,000
10
1.2. Файлы базы данных SQLite, которым не доверяют
sqlite3_db_config(db,
SQLITE_DBCONFIG_ENABLE_TRIGGER,0,0);
sqlite3_db_config(db,
SQLITE_DBCONFIG_ENABLE_VIEW,0,0);
2. Итог