Что такое код pg_escape_bytea


Содержание

PHP разные результаты pg_escape_bytea() при подключении к postgresql — php

Я не хочу менять результат. Как я могу это сделать? Пожалуйста помоги!

    3 1
  • 9 сен 2020 2020-09-09 13:07:05
  • Khoa Tran

1 ответ

Когда вы выбираете тип bytea, PostgreSQL возвращает восьмеричные байтовые значения с префиксом (например,032). Пользователи должны преобразовать обратно в двоичный формат вручную.

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

Фиксирование ошибки типа в Python Pg

Благодарим вас за помощь в решении первых ошибок!

Как вы можете использовать pg.escape_bytea или pg.escape_string в следующем?

# 1 И с pg.escape_string и pg.escape_bytea

Я получаю сообщение об ошибке

Я тоже успешно проверил обе escape-последовательности в обратном порядке.

# 2 Без pg.escape_string()

Я получаю следующую ошибку

# 3 Только с pg.escape_string

python types postgresql

1 ответ

4 Решение bobince [2009-11-20 18:30:00]

INSERT INTO файлы (‘binf’, ‘file_name’) VALUES (файл, имя_файла)

У вас есть разделы (. ) неправильным образом, вы пытаетесь вставить столбцы (file, filename) в строковые литералы (‘binf’, ‘file_name’) . Вы также не вставляете содержимое переменных binf и file_name в запрос.

Вызов pg module query не поддерживает параметризацию. Вы должны сами сделать строку:

Предполагается, что f является файловым объектом; Я не уверен, где file исходит из кода выше или что означает .read(binf) . Если вы используете столбец bytea для хранения данных файла, вы должны использовать escape_bytea вместо escape_string .

Лучше, чем создавать свои собственные запросы, позволяет pg сделать это для вас с помощью insert:

В качестве альтернативы рассмотрите возможность использования интерфейса pgdb или одного из других интерфейсов, совместимых с DB-API, которые не являются специфичными для PostgreSQL, если вы когда-нибудь захотите запустить приложение в другой базе данных. DB-API дает вам параметризацию в методе execute :

pg_escape_bytea

(PHP 4 >= 4.2.0, PHP 5, PHP 7)

pg_escape_bytea — Escape a string for insertion into a bytea field

Description

pg_escape_bytea() escapes string for bytea datatype. It returns escaped string.

When you SELECT a bytea type, PostgreSQL returns octal byte values prefixed with ‘\’ (e.g. \032). Users are supposed to convert back to binary format manually.

This function requires PostgreSQL 7.2 or later. With PostgreSQL 7.2.0 and 7.2.1, bytea values must be cast when you enable multi-byte support. i.e. INSERT INTO test_table (image) VALUES (‘$image_escaped’::bytea); PostgreSQL 7.2.2 or later does not need a cast. The exception is when the client and backend character encoding does not match, and there may be multi-byte stream error. User must then cast to bytea to avoid this error.

Parameters

PostgreSQL database connection resource. When connection is not present, the default connection is used. The default connection is the last connection made by pg_connect() or pg_pconnect() .

A string containing text or binary data to be inserted into a bytea column.


Как восстановить gz сжатую строку, хранящуюся в PostgreSQL ByteA, используя PHP PDO Object?

У меня возникла проблема в понимании того, как PHP обрабатывает ByteA с привязкой postgreSQL.

Для ведения журнала и архивирования я храню gzencode() файлы столбцов, которые я обслуживаю с помощью моего PHP / Apache Server. Для хранения я сжимаю данные, pg_escape_bytea() а затем я убираю строку перед сохранением, используя : // Compress: if ( $compress ) < $data = gzencode ( $data , 9 ); >// PostgreSQL ByteA Escaping: $data = pg_escape_bytea ( $data );

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

Я должен использовать объект PDO, все примеры, которые я нашел (даже на веб-сайте PHP), основаны на специализированном API СУБД. Во-вторых, ByteA столбцы возвращаются в качестве ресурсов, а затем я должен использовать их stream_getcontents() для получения строки. Когда я храню несжатые файлы, я могу легко избавиться от него, что бы я ни использовал или не выполнял SET bytea_output = ‘escape’; запрос и / или pg_unescape_bytea() функцию. Все комбинации позволяют мне получить файл.

Когда я использую сжатые данные, pg_unescape_bytea() резко поглощает почти все мои байты. Во всяком случае, во всех комбинациях gzdecode() не работает. Кажется, у меня есть недостающие или неправильные символы в моей двоичной строке, которая не блокируется в режиме обычного текста. Во всяком случае, дело не хорошо документировано в Интернете, и я застрял без всякой подсказки.

Как мне восстановить gz сжатую строку, хранящуюся в PostgreSQL ByteA, используя PHP PDO Object?

Ответов: 1

Решение проблемы поиска только при условии, что работы по вставке

Как только двоичное содержимое вступит в $data следующий код:

они уже находятся в необработанном двоичном формате по мере необходимости, поэтому вы не должны расшифровывать его снова с помощью этого:

Просто удалите это ложное unescaping. Причина, по которой вы не заметили проблему, когда $data имеют только символы ASCII, pg_unescape_bytea преобразует эти символы в себя (данный bytea_output задан для выхода).

Но когда бинарный поток действительно содержит весь диапазон из 256 возможных байтов, например, в gzipped-контенте, то гарантируется, что pg_unescape_bytea в этом контексте будет получен поврежденный результат.

pg_unescape_bytea должен использоваться только для строк, которые поступают непосредственно из базы данных как bytea-encoded-as-text.

Как это обычно делается с PDO

На самом деле с PDO мы не должны использовать pg_[un]escape_bytea функции или даже любую из функций, которые начинаются с того, pg_* что PDO является независимым от базы данных, и его целью является обеспечение кода, который работает в разных базах данных.

Вставка должна выполняться, как описано в http://php.net/manual/en/pdo.lobs.php , с квалификацией двоичных параметров PDO::PARAM_LOB . При этом PDO сам будет кодировать данные для двоичной передачи, используя соответствующий метод для типа базы данных, к которой он подключен.

При явном экранировании pg_escape_bytea() он создает строку, которую PDO может рассматривать как текстовое содержимое и передавать как таковой. Это способ передачи двоичных данных «за спиной PDO», но в этом не так много смысла.

Что определенно не работает, так это смешивание: экранирование (которое создает текст) и указание PDO, что он двоичный.

How to convert PostgreSQL escape bytea to hex bytea?

I got the answer to check for one certain BOM in a PostgreSQL text column. What I really like to do would be to have something more general, i.e. something like

The result of a UTF8 BOM is:

Which is octal bytea and can be converted by switching the output of bytea in pgadmin:

What I would like to have is this result as one query, e.g.

But that doesn’t work. The result is empty, probably because the decode cannot handle hex output.

2 Answers 2

If the final purpose is to get the hexadecimal representation of all the bytes that constitute the strings in textColumn , this can be done with:

It does not depend on bytea_output . BTW, this setting plays a role only at the final stage of a query, when a result column is of type bytea and has to be returned in text format to the client (which is the most common case, and what pgAdmin does). It’s a matter of representation, the actual values represented (the series of bytes) are identical.

In the query above, the result is of type text , so this is irrelevant anyway.

I think that your query with decode(. ‘escape’) can’t work because the argument is supposed to be encoded in escape format and it’s not, per comments it’s normal xml strings.

Как восстановить gz сжатую строку, хранящуюся в PostgreSQL ByteA, используя PHP PDO Object?

У меня возникла проблема в понимании того, как PHP обрабатывает ByteA с привязкой postgreSQL.

Для ведения журнала и архивирования я храню в файлах столбцов ByteA , которые я обслуживаю с помощью моего PHP/Apache Server. Для хранения, сжать данные, используя gzencode() , а затем я убегаю строку перед хранением с использованием pg_escape_bytea() :

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

Я должен использовать объект PDO, все примеры, которые я нашел (даже на веб-сайте PHP) основаны на выделенном СУБД API. Во-вторых, столбец ByteA возвращаются как ресурсы, тогда мне нужно было использовать stream_getcontents() , чтобы получить строку. Когда я храню несжатые файлы, я могу легко избавиться от него, что когда-либо использовал или нет. SET bytea_output = ‘escape’; запрос и/или pg_unescape_bytea() функция. Все комбинации позволяют мне получить файл.

Когда я использую сжатые данные, pg_unescape_bytea() резко поглощает почти все мои байты. Во всяком случае, во всех комбинациях gzdecode() не работает. Кажется, у меня есть недостающие или неправильные символы в моей двоичной строке, которая не блокируется в режиме обычного текста. Во всяком случае, дело не хорошо документировано в Интернете, и я застрял без всякой подсказки.

Как восстановить gz сжатую строку, хранящуюся в PostgreSQL ByteA, используя PHP PDO Object?


Создан 13 окт. 16 2020-10-13 11:38:55 jlandercy

1 ответ

Решение только проблемы извлечения, предполагая, что вставка работает

После того, как двоичные содержимое попадают в $data со следующим кодом:

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

Просто удалите это ложное отключение. Причина, по которой вы не заметили проблему, когда $data имеет только символы ASCII, заключается в том, что pg_unescape_bytea преобразует эти символы в себя (задано значение bytea_output ).

Но когда бинарный поток действительно содержит весь диапазон из 256 возможных байтов, например, в gzipped-контенте, то гарантируется, что pg_unescape_bytea приведет к поврежденному результату в этом контексте.

pg_unescape_bytea следует использовать только для строк, которые поступают непосредственно из базы данных как bytea-encoded-as-text.

Как это обычно делается с PDO

На самом деле с PDO, мы не должны использовать pg_[un]escape_bytea функции, или даже какой-либо из функций, которые начинаются с pg_* , потому что ПДО базы данных независим, и его цель заключается в том, чтобы использовать код, который работает в разных базах данных.

Илон Маск рекомендует:  Что такое код getkeystate

Вставка должна выполняться в соответствии с описанием в http://php.net/manual/en/pdo.lobs.php, определяя двоичные параметры с помощью PDO::PARAM_LOB . При этом PDO сам будет кодировать данные для двоичной передачи, используя соответствующий метод для типа базы данных, к которой он подключен.

При выполнении явного экранирования с помощью pg_escape_bytea() он создает строку, которую PDO может рассматривать как текстовое содержимое и передавать как таковой. Это способ передачи двоичных данных «за спиной PDO», но в этом не так много смысла.

Что определенно не работает, так это смешивание обоих: экранирование (которое создает текст) и говорит PDO, что он двоичный.

Создан 13 окт. 16 2020-10-13 18:29:57 Daniel Vérité

Я действительно смущен об этом. Я вижу, что он связан с кодировкой. Но я не могу заставить его работать. Я не могу хранить gz сжатые данные в ByteA, не используя pg_escpae_bytea, и это может быть проблемой. Что мне не хватает? – jlandercy 14 окт. 16 2020-10-14 09:20:10

Вставка gzcompressed без pg_escape_bytea дает мне ERROR: неверная последовательность байтов для кодирования «UTF8»: 0x8b. Когда я использую fucntion, возвращаемые данные возвращают что-то другое, что я вставил. – jlandercy 14 окт. 16 2020-10-14 09:25:13

Эта страница http://sickel.net/blogg/?p=1365 предоставляет решение, но она работает контрпродуктивно и точно соответствует тому, как я хочу работать. Я хочу хранить двоичные данные (и я не могу это сделать без изменения формата gzip) вместо шестнадцатеричного строкового представления двоичных данных. – jlandercy 14 окт. 16 2020-10-14 09:44:32

Я наконец нашел решение, я редактирую ваш вопрос, тогда я могу принять его как ответ. Спасибо. – jlandercy 14 окт. 16 2020-10-14 09:58:39

@jlandercy: Я уточнил, надеюсь, в редактировании. В вашем 1-м комментарии оказалось, что вы изменили код вставки, но мой ответ касался только изменения поиска, а не вставки. Если вы избавитесь от pg_escape_bytea во вставке, вместо этого вы должны использовать PDO :: PARAM_LOB, но я думаю, что именно это вы и сделали в конце концов. – Daniel Vérité 14 окт. 16 2020-10-14 15:49:36

Спасибо, что вы поняли, и теперь его полностью работающий – jlandercy 14 окт. 16 2020-10-14 15:59:25

Книга «Безопасность в PHP» (часть 2). Атаки с внедрением кода

В списке десяти наиболее распространённых видов атак по версии OWASP первые два места занимают атаки с внедрением кода и XSS (межсайтовый скриптинг). Они идут рука об руку, потому что XSS, как и ряд других видов нападений, зависит от успешности атак с внедрением. Под этим названием скрывается целый класс атак, в ходе которых в веб-приложение внедряются данные, чтобы заставить его выполнить или интерпретировать вредоносный код так, как это нужно злоумышленнику. К таким атакам относятся, например, XSS, внедрение SQL, внедрение заголовка, внедрение кода и полное раскрытие путей (Full Path Disclosure). И это лишь малая часть.

Атаки с внедрением — страшилка для всех программистов. Они наиболее распространены и успешны за счёт разнообразия, масштабности и (иногда) сложности защиты от них. Всем приложениям нужно брать откуда-то данные. XSS и UI Redress встречаются особенно часто, поэтому я посвятил им отдельные главы и выделил их из общего класса.

OWASP предлагает следующее определение атак с внедрением:

Возможности внедрения — вроде SQL, OS и LDAP — возникают тогда, когда интерпретатор получает ненадёжные данные в виде части командного запроса. Зловредные данные могут обмануть интерпретатор и заставить его выполнить определённые команды или обратиться к неавторизованным данным.

Внедрение SQL

Внедрение SQL — самая распространённая и чрезвычайно опасная форма атак с внедрением. Трудно переоценить серьёзность этой угрозы, поэтому крайне важно понимать, что влияет на успешность атак и как от них защититься.

Итак, данные внедряются в веб-приложение, а затем используются в SQL-запросах. Обычно они попадают из ненадёжных источников ввода, например из веб-форм. Однако внедрение может выполняться и из других мест, скажем, из самой базы данных. Программисты часто верят в полную безопасность своей базы, не осознавая, что если она была безопасна в одном случае, то это совершенно не значит, что она будет безопасна и впредь. Данные из базы должны считаться ненадёжными до тех пор, пока не доказано обратное, т. е. пока они не прошли проверку.

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

Посмотрите на этот запрос:

Здесь целый ряд косяков. Во-первых, мы не проверяли содержимое POST-данных на предмет корректности user_id . Во-вторых, мы позволяем ненадёжному источнику сообщать нам, какой user_id использовать: атакующий может подсунуть любой корректный user_id . Возможно, он содержался в скрытом поле формы, которую мы считали безопасной, потому что её нельзя редактировать (при этом забыв, что атакующие могут вводить любые данные). В-третьих, мы не заэкранировали user_id и не передали его в запрос в виде параметра (bound parameter), что тоже позволяет атакующему внедрять произвольные строки, которые будут манипулировать SQL-запросом, учитывая, что мы не смогли проверить его в первую очередь.

Это три упущения очень часто встречаются в веб-приложениях.

Что касается доверия к базе данных, то представьте, что мы искали транзакции с помощью поля user_name . Имена имеют широкий охват и могут содержать кавычки. Допустим, атакующий сохранил внедрённое строковое значение в одном из пользовательских имён. Когда мы снова используем это значение в одном из следующих запросов, то оно будет манипулировать строкой запроса, раз мы посчитали базу надёжным источником, не изолировали и не ограничили скомпрометированный запрос.

Также уделяйте внимание другому фактору внедрения SQL: постоянное хранилище не всегда нужно держать на сервере. HTML 5 поддерживает использование БД на стороне клиента, куда можно отправлять запросы с помощью SQL и JavaScript. Для этого есть два API: WebSQL и IndexedDB. В 2010 году W3C не рекомендовал выбирать WebSQL; он поддерживается WebKit-браузерами, использующими SQLite в качестве бэкенда. Скорее всего, поддержка сохранится ради обратной совместимости, даже несмотря на рекомендацию W3C. Как следует из его названия, этот API принимает SQL-запросы, а значит, может быть мишенью атак с внедрением. IndexedDB — это более новая альтернатива, база данных NoSQL (не требует использования SQL-запросов).

Примеры внедрения SQL

Манипулирование SQL-запросами может преследовать такие цели:

  1. Утечки данных.
  2. Раскрытие хранимой информации.
  3. Манипулирование хранимой информацией.
  4. Обход авторизации.
  5. Внедрение SQL на стороне клиента.


Защита от внедрения SQL

Защита от внедрения SQL базируется на принципе эшелонирования. Перед использованием данных в запросе надо проверять, что их форма корректна. Также необходимо изолировать данные до включения в запрос либо включать в виде параметра перехода.

Проверка

Я не устаю повторять: все данные, которые не были явным образом созданы в исходном PHP-коде текущего запроса, ненадёжны. Строго проверяйте их и отклоняйте всё, что не прошло проверок. Не пытайтесь «исправить» данные, можно внести лишь лёгкие, косметические изменения в формат.

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

Экранирование

С помощью расширения mysqli вы можете изолировать все данные, включённые в SQL-запрос. Это делает функция mysqli_real_escape_string() . Расширение pgsql для PostgresSQL предлагает функции pg_escape_bytea() , pg_escape_identifier() , pg_escape_literal() и pg_escape_string() . В расширении mssql (Microsoft SQL Server) нет изолирующих функций, а подход с применением addslashes() неэффективен — вам понадобится кастомная функция.

Чтобы ещё больше усложнить вам жизнь, скажу, что вы не имеете права на ошибку при изолировании вводимых в запрос данных. Один промах — и вы уязвимы для атаки.

Подведём итог. Экранирование — не лучший вариант защиты. К нему стоит прибегать в крайнем случае. Оно может понадобиться, если используемая вами для абстракции библиотека БД допускает настройку голых SQL-запросов или частей запроса без принудительной привязки параметров. В остальных случаях лучше вообще избегать изолирования. Этот подход сложен, провоцирует ошибки и различается в зависимости от расширения базы данных.

Параметризованные запросы (заранее подготовленные выражения)

Параметризация, или привязка параметров, — это рекомендованный способ создания SQL-запросов. Все хорошие библиотеки БД применяют его по умолчанию. Вот пример использования расширения PDO для PHP:

Метод bindParam() , доступный для выражений PDO, позволяет привязывать параметры к «местам для вставки» (placeholders), представленным в заранее подготовленном выражении. Этот метод принимает параметры основных типов данных, например, PDO::PARAM_INT , PDO::PARAM_BOOL , PDO::PARAM_LOB и PDO::PARAM_STR . Для PDO::PARAM_STR это делается по умолчанию, если не задано другое, так что запомните и для других значений!

В отличие от ручного изолирования, привязка параметров (или иной другой метод, используемый вашей библиотекой БД) позволит корректно изолировать автоматически привязываемые данные, так что вам не придётся вспоминать, какую функцию применять. Также согласованная привязка параметров гораздо надёжнее, чем попытка не забыть, что нужно изолировать всё вручную.

Реализация принципа наименьших привилегий

Прервать успешное внедрение SQL не менее важно, чем его полностью предотвратить. Когда атакующий получает возможность выполнять SQL-запросы, то он будет это делать как конкретный пользователь БД. Благодаря принципу наименьших привилегий можно удостовериться, что все пользователи имеют лишь те привилегии, которые абсолютно необходимы для выполнения их задач.

Если у пользователя широкие привилегии, то атакующий может удалять таблицы и менять привилегии других пользователей, выполняя от их имени новые внедрения SQL. Чтобы этого не произошло, никогда не обращайтесь к БД из веб-приложения от лица root’а, администратора или иного пользователя с высокими привилегиями.

Другое применение принципа — разделение ролей чтения и записи данных в базу. Выберите одного пользователя с правами только на запись, а другого — с правами только на чтение. Если атака будет направлена на «читающего» пользователя, то у злоумышленника не получится манипулировать данными в таблице или записывать их. Можно ограничивать доступ в ещё более узких рамках, тем самым уменьшая последствия успешных атак с внедрением SQL.

Многие веб-приложения, особенно с открытым кодом, разработаны так, что в них используется только один пользователь БД, уровень привилегий которого почти наверняка никогда не проверяется. Так что не забывайте об этом моменте и не пытайтесь запускать приложения под администраторским аккаунтом.

Внедрение кода (известно как удалённое включение файла, Remote File Inclusion)

Внедрение кода — это любые способы, которые позволяют атакующему добавлять в веб-приложение исходный код с возможностью его интерпретировать и исполнять. При этом речь не идёт о внедрении кода в клиентскую часть, например в JavaScript, здесь применяются уже XSS-атаки.

Можно внедрить исходный код напрямую из ненадёжного источника входных данных либо заставить веб-приложение загрузить его из локальной файловой системы или внешнего ресурса вроде URL. Когда код внедряется в результате включения внешнего источника, то это обычно называют удалённым включением файла (RFI), хотя само по себе RFI всегда предназначено для внедрения кода.

Основные причины внедрения кода:

  • обход проверки входных данных,
  • внедрение ненадёжных входных данных в любой контекст, где они будут расценены как PHP-код,
  • взлом безопасности репозиториев исходного кода,
  • отключение предупреждений о загрузке сторонних библиотек,
  • переконфигурация сервера, чтобы он передавал в PHP-интерпретатор файлы, не относящиеся к PHP.

Последнему пункту уделяйте особое внимание: в этом случае ненадёжные пользователи могут загрузить на сервер любые файлы.

Примеры внедрения кода

В PHP множество целей для внедрения кода, так что этот тип атак возглавляет список наблюдения у любого программиста.

Включение файла

Самые очевидные цели для внедрения кода — функции include() , include_once() , require() и require_once() . Если ненадёжные входные данные позволят определить передаваемый в эти функции параметр path , то можно будет удалённо управлять выбором файла для включения. Нужно отметить, что включённый файл не обязан быть настоящим PHP-файлом, допускается использование файла любого формата, способного хранить текстовые данные (т. е. почти без ограничений).

Илон Маск рекомендует:  На что обратить внимание при выборе виртуального сервера (VPS)

Параметр path также может быть уязвим для атак обхода каталога (Directory Traversal) или удалённого включения файла. Использование в path комбинаций символов ../ или… позволяет атакующему переходить почти к любому файлу, к которому имеет доступ PHP-процесс. Заодно в конфигурации PHP по умолчанию вышеприведённые функции принимают URL, если не отключён allow_url_include.

Проверка

Функция PHP eval() принимает к исполнению строку PHP-кода.

Внедрение регулярных выражений

Функция PCRE (регулярное выражение, совместимое с Perl) preg_replace() в PHP допускает использование модификатора e (PREG_REPLACE_EVAL). Это означает замещающую строку, которая после подстановки будет считаться PHP-кодом. И если в этой строке имеются ненадёжные входные данные, то они смогут внедрить исполняемый PHP-код.

Дефектная логика включения файла

Веб-приложения по определению включают в себя файлы, необходимые для обслуживания любых запросов. Если воспользоваться дефектами логики маршрутизации, управления зависимостями, автозагрузки и других процессов, то манипуляция с путём прохождения запроса или его параметрами заставит сервер включить конкретные локальные файлы. Поскольку веб-приложение не рассчитано на обработку таких манипуляций, последствия могут быть непредсказуемыми. Например, приложение невольно засветит маршруты, предназначенные только для использования в командной строке. Или раскроет другие классы, конструкторы которых выполняют задачи (лучше классы так не проектировать, но это всё же встречается). Любой из этих сценариев может помешать операциям бэкенда приложения, что позволит манипулировать данными или провести DOS-атаку на ресурсоёмкие операции, которые не подразумевают прямого доступа.

Задачи внедрения кода


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

Defenses against Code Injection

Command Injection

Examples of Command Injection

Defenses against Command Injection

Внедрение лога (известно как внедрение лог-файла, Log File Injection)

Многие приложения собирают логи, а авторизованные пользователи часто просматривают их через HTML-интерфейс. Поэтому логи — одна из главных целей злоумышленников, желающих замаскировать другие атаки, обмануть тех, кто просматривает логи, и даже провести затем атаку на пользователей мониторингового приложения, с помощью которого читаются и анализируются логи.

Уязвимость логов зависит от механизмов контроля над записью логов, а также от обращения с данными логов как с ненадёжным источником при просмотре и анализе записей.

Простая система журналирования может записывать в файл текстовые строки с помощью file_put_contents() . Например, программист регистрирует ошибочные попытки авторизации в виде строк следующего формата:

А что, если атакующий использует в форме имя «AdminnSuccessful login by Adminn»?

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

Здесь вся суть в том, что атакующий способен добавлять в лог всевозможные записи. Также можно внедрить XSS-вектор и даже символы, затрудняющие чтение в консоли записей лога.

Задачи внедрения лога

Одна из целей внедрения — интерпретаторы формата логов. Если инструмент анализа использует регулярные выражения для парсинга записей в логе, чтобы делить их на части и раскидывать по разным полям, то можно создать и внедрить такую строку, которая заставит регулярные выражения выбирать внедрённые поля вместо правильных. Например, эта запись может стать источником нескольких проблем:

Более изощрённые атаки с внедрением логов базируются на атаках с обходом каталога, чтобы отобразить лог в браузере. При подходящих условиях внедрение PHP-кода в сообщение лога и открытие в браузере файла с записями приведёт к успешному внедрению кода, аккуратно форматированного и выполняемого по желанию злоумышленника. А если дойдёт до исполнения на сервере зловредного PHP, то остаётся надеяться лишь на эффективность эшелонирования защиты, которое может уменьшить ущерб.

Защита от внедрения лога

Проще всего фильтровать все внешние сообщения логов с помощью белого списка. Допустим, ограничить набор символов только цифрами, буквами и пробелами. Сообщения, содержащие неразрешённые символы, считаются повреждёнными. Тогда в журнале появляется запись о потенциальной попытке внедрения лог-файла. Это простой способ защиты для простых текстовых логов, когда нельзя избежать включения в сообщения ненадёжных входных данных.

Второй метод защиты — преобразование порций ненадёжных входных данных с помощью системы наподобие base64, которая поддерживает ограниченный набор символов, при этом позволяя хранить в текстовом виде разнообразную информацию.

Обход пути (известен как обход каталога, Directory Traversal)

Атаки с обходом пути — это попытки повлиять на операции чтения или записи файлов в бэкенде веб-приложения. Делается это с помощью внедрения параметров, которые позволяют манипулировать путями файлов, вовлечённых в операции бэкенда. Так что атаки этого типа облегчают раскрытие информации (Information Disclosure) и локальное/удалённое внедрение файлов.

Такие атаки мы рассмотрим отдельно, но в основе их успешности лежит именно обход пути. Поскольку описанные ниже функции характерны именно для манипулирования путями файлов, имеет смысл упомянуть, что многие PHP-функции не принимают пути к файлам в привычном смысле слова. Вместо этого функции наподобие include() или file() принимают URI.

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

Дело в том, что относительный путь обрабатывается на стороне (настройка include_path в php.ini и доступных автозагрузчиках). В таких случаях PHP-функции особенно уязвимы для многих форм манипуляций с параметрами, включая подмену схемы URI файла (File URI Scheme Substitution), когда атакующий может внедрить HTTP или FTP URI, если в начало пути файла внедрены ненадёжные данные. Подробнее об этом мы поговорим в разделе, посвящённом атакам с удалённым включением файлов, а пока сосредоточимся на обходах путей файловых систем.

Эта уязвимость подразумевает изменение пути для обращения к другому файлу. Обычно это достигается с помощью внедрения серии последовательностей ../ в аргумент, который затем присоединяется к функциям или целиком вставляется в функции наподобие include() , require() , file_get_contents() и даже менее подозрительные (для кого-то) функции вроде DOMDocument::load() .

С помощью последовательности ../ атакующий заставляет систему вернуться в родительский каталог. Так что путь /var/www/public/../vendor на самом деле ведёт в /var/www/vendor . Последовательность ../ после / public возвращает нас в родительский каталог, т. е. в / var/www . Таким образом злоумышленник получает доступ к файлам, расположенным вне каталога / public , доступного с веб-сервера.

Конечно, обход пути не ограничивается одним лишь возвратом. Можно внедрить новые элементы пути, чтобы получить доступ к дочерним каталогам, которые недоступны из браузера в связи с настройками ограничений в .htaccess. Операции PHP с файловой системой не волнует конфигурация контроля доступа к непубличным файлам и каталогам на веб-сервере.

Examples of Path Traversal

Defenses against Path Traversal

Внедрение XML

Несмотря на внедрение JSON в качестве облегчённого средства передачи данных между сервером и клиентом, XML остаётся популярной альтернативой, API веб-сервисов зачастую поддерживает её параллельно с JSON. Также XML применяется для обмена данными, использующими XML-схемы: RSS, Atom, SOAP и RDF и т. д.

XML вездесущ: его можно найти в серверах веб-приложений, в браузерах (в качестве предпочтительного формата для запросов и откликов XMLHttpRequest) и браузерных расширениях. Учитывая его распространённость и обработку по умолчанию таким популярным парсером, как libxml2, используемым PHP в DOM и в расширениях SimpleXML и XMLReader, XML стал целью для атак с внедрением. Когда браузер активно участвует в XML-обмене, необходимо учитывать, что посредством XSS авторизованные пользователи могут передавать XML-запросы, созданные на самом деле злоумышленниками.

Внедрение внешней XML-сущности (XXE)

Такие атаки существуют из-за того, что библиотеки парсинга XML часто поддерживают использование ссылок на кастомные сущности. Вы познакомитесь со стандартным XML-дополнением сущностей, его применяют для представления специальных символов разметки наподобие > , &lt ; и &apos ;. XML позволяет расширять набор стандартных сущностей, определяя посредством самого XML-документа кастомные сущности. Их можно определять, напрямую включая в опциональный DOCTYPE. Представляемое ими расширенное значение может ссылаться на внешний ресурс, который должен быть включён. XXE-атаки стали популярны именно благодаря возможности ординарного XML хранить кастомные ссылки, которые могут увеличиваться за счёт содержимого внешних ресурсов. При обычных условиях ненадёжные входные данные никогда не должны непредвиденным образом взаимодействовать с нашей системой. А большинство программистов XXE почти однозначно не предвидят XXE-атаки, что вызывает особую озабоченность.

Давайте, к примеру, определим новую кастомную сущность harmless:

XML-документ с этим определением теперь может ссылаться на сущность &harmless; везде, где вообще разрешены сущности:

Когда XML-парсер вроде PHP DOM будет интерпретировать этот XML, он обработает эту кастомную сущность сразу же, как загрузится документ. Поэтому при запросе соответствующего текста вернёт следующее:

This result is completely harmless


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

В зависимости от содержимого запрошенного локального файла данные могут использоваться при расширении сущности &harmless; . А потом расширенный контент может быть извлечён из XML-парсера и включён в исходящие данные веб-приложения для анализа атакующим. Например, для раскрытия информации. Извлечённый файл будет интерпретирован как XML, хотя специальных символов, инициирующих такое интерпретирование, нет. Это ограничивает масштаб раскрытия содержимого локального файла. Если файл интерпретирован как XML, но не содержит корректного XML, то наверняка мы получим ошибку, что предотвратит раскрытие содержимого. Однако в PHP доступен аккуратный трюк, позволяющий обойти ограничение масштаба, поэтому удалённые HTTP-запросы влияют на веб-приложение, даже если возвращённый ответ нельзя передать обратно атакующему.

В PHP часто встречаются три метода парсинга и использования XML: PHP DOM, SimpleXML и XMLReader. Все они применяют расширение libxml2, поддержка внешних сущностей включена по умолчанию. Как следствие, в PHP по умолчанию есть уязвимость к XXE-атакам, которую очень легко пропустить при рассмотрении безопасности веб-приложения или библиотеки, использующей XML.

Не забывайте также, что XHTML и HTML 5 могут быть сериализованы как корректный XML. А значит, некоторые XHTML-страницы или XML-сериализованный HTML 5 могут парситься как XML, с использованием DOMDocument::loadXML() вместо DOMDocument::loadHTML() . Такое применение XML-парсера тоже уязвимо к внедрению внешних XML-сущностей. Помните, что libxml2 пока даже не распознаёт HTML 5 DOCTYPE, поэтому не может проверить его как XHTML DOCTYPES.

Примеры внедрения внешних XML-сущностей

Содержимое файла и раскрытие информации

Выше мы рассмотрели пример раскрытия информации, отметив, что кастомная XML-сущность может ссылаться на внешний файл.

В данном случае кастомная сущность &harmless; будет расширена содержимым файлов. Поскольку все подобные запросы выполняются локально, это позволяет раскрыть содержимое всех файлов, которые может считать приложение. То есть когда расширенная сущность будет включена в исходящие данные приложения, атакующий сможет изучить файлы, находящиеся в закрытом доступе. Правда, в данном случае есть серьёзное ограничение: файлы должны быть либо XML-формата, либо формата, который не приведёт к возникновению ошибки XML-парсера. Но дело в том, что это ограничение можно полностью проигнорировать в PHP:

PHP даёт доступ к обёртке в виде URI, одного из протоколов, принимаемого стандартными функциями по работе с файловой системой: file_get_contents() , require() , require_once() , file() , copy() и многими другими. Обёртка PHP поддерживает ряд фильтров, которые можно применять к конкретному ресурсу, чтобы результаты возвращались вызовом функции. В приведённом выше примере мы применяем к целевому файлу, который хотим прочесть, фильтр convert.base-64-encode .

Это означает, что атакующий может прочитать любой доступный для PHP файл, независимо от текстового формата. Достаточно просто декодировать исходящие из приложения данные, а потом безнаказанно их препарировать. Хотя это не наносит прямого вреда конечным пользователям или бэкенду приложения, зато позволяет атакующим хорошо изучить структуру приложения в попытке найти иные уязвимости. Причём риск, что атакующих обнаружат, минимален.

Илон Маск рекомендует:  Что такое код asp frontpageweb

Обход контроля доступа

Доступ контролируется разными способами. Поскольку XXE-атаки проводятся на бэкенде веб-приложения, использовать сессию текущего пользователя не получится. Но атакующий всё ещё может обойти контроль доступа к бэкенду с помощью запросов от локального сервера. Рассмотрим такой примитивный контроль доступа:

Этот кусок PHP, как и несметное количество ему подобных, ограничивает доступ к определённым PHP-файлам на локальном сервере, т. е. localhost. Однако XXE-атака на фронтенде приложения даёт атакующему точные учётные данные, необходимые для обхода этого контроля доступа, потому что все HTTP-запросы XML-парсера будут делаться из localhost.

Даже если бы просмотр логов был ограничен локальными запросами, атакующий всё равно смог бы получить логи. То же самое касается интерфейсов сопровождения или администрирования, доступ к которым ограничен подобным образом.

DOS-атаки

Для DOS-атак можно использовать почти всё, что диктует потребление серверных ресурсов. С помощью внедрения внешней XML-сущности атакующий получает возможность делать произвольные HTTP-запросы, которые при подходящих условиях истощают серверные ресурсы.

Позднее мы поговорим о других потенциальных DOS-применениях XXE-атак с точки зрения расширения XML-сущностей.

Защита от внедрения внешних XML-сущностей

Такие атаки очень популярны, так что вас удивит, как просто от них защититься. Поскольку DOM, SimpleXML и XMLReader опираются на libxml2, можно всего лишь применить функцию libxml_disable_entity_loader() , отключающую использование внешних сущностей. Правда, это не отключит кастомные сущности, заранее определённые в DOCTYPE, потому что они не используют внешние ресурсы, требующие выполнения HTTP-запроса или операции в файловой системе.

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

Там, где приложению никогда не требуются внешние сущности, а также для большинства его запросов можно вообще отключить загрузку внешних ресурсов на более глобальном уровне. В большинстве случаев это куда предпочтительнее для определения всех «точек» загрузки XML, учитывая, что многие библиотеки имеют врождённые уязвимости к XXE-атакам:

Только не забывайте возвращать значение TRUE после каждого временного включения загрузки внешних ресурсов. Она может понадобиться для таких безобидных задач, как преобразование Docbook XML в HTML, когда применение XSL-стилей зависит от внешних сущностей.

Однако отключающая libxml2 функция — не панацея. Проанализируйте другие расширения и PHP-библиотеки, которые парсят или как-то ещё обрабатывают XML, чтобы найти их «выключатели» применения внешних сущностей.

Если это сделать невозможно, то дополнительно проверьте, объявляет ли XML-документ DOCTYPE. Если да и если при этом внешние сущности отключены, то просто выкиньте XML-документ, запретив ненадёжный XML-доступ к потенциально уязвимому парсеру и журналируя его как вероятную атаку. Это необходимый шаг, потому что других признаков не будет — ни ошибок, ни исключений. Встройте эту проверку в свою обычную валидацию входных данных. Но этот метод далеко не идеален, так что крайне рекомендуется в корне решить проблему внешних сущностей.

Также предпочтительно сразу удалять подозрительные данные, которые могут быть результатом атаки. Зачем продолжать работать с чем-то, что выглядит опасным? Так что комбинация из двух вышеописанных мер позволяет заранее игнорировать очевидно вредоносные данные, одновременно защищая себя на случай, если удалить данные не получится (например, если это сторонние библиотеки). Удалять данные приходится и потому, что libxml_disable_entity_loader() отключает не все кастомные сущности, а только те, что ссылаются на внешние ресурсы. Что оставляет возможность атаки с расширением XML-сущности (XML Entity Expansion).

Расширение XML-сущности

Эта атака во многом аналогична атаке с внедрением XML-сущности. Но в данном случае делается акцент на DOS-атаку с попыткой истощить ресурсы серверного окружения целевого приложения. В DOCTYPE XML создаётся определение кастомной сущности, которая, к примеру, может генерировать в памяти XML-структуры гораздо более крупного размера по сравнению с исходной. Это приводит к заполнению памяти и снижению эффективности работы сервера. Такая атака применяется и к XML-сериализации HTML 5 в том случае, если последний не распознан расширением libxml2 как HTML.

Примеры расширения XML-сущности

Есть несколько способов расширить кастомные XML-сущности ради желаемого истощения серверных ресурсов.

Общее расширение сущности

Другое название — «атака квадратичного увеличения». Кастомная сущность определяется в виде очень длинной строки. Если многократно использовать её в документе, то она каждый раз увеличивается, в результате XML-структура потребляет гораздо больше оперативной памяти по сравнению с исходным XML.

Если найти баланс между размером строки кастомной сущности и количеством использования в теле документа, то можно создать такой XML-файл или строку, при расширении которых получится прогнозировать потребление серверной памяти. Если заполнить её такими повторяющимися вопросами, то выйдет настоящая DOS-атака. Недостаток подхода: изначальный XML тоже должен быть довольно большим, потому что потребление памяти зависит от простого эффекта умножения.

Рекурсивное расширение сущности

В то время как общее расширение требует использования изначально большого XML, рекурсивное обеспечивает гораздо более высокий коэффициент увеличения. Этот метод основан на экспоненциальном разложении (resolve) наборов маленьких сущностей таким образом, чтобы они существенно увеличивались в размерах. Вполне логично, что этот метод часто называют XML-бомбой и атакой миллиарда смешков (Billion Laughs Attack).

XML-бомба не требует большого XML, размер которого иногда может быть ограничен приложением. Атака приводит к тому, что память забивается текстом, чей размер в 2^100 раза превышает размер исходного значения сущности — &x0; . Настоящая БОМБА!

Удалённое расширение сущности

Обе вышеописанные атаки используют локально определённые сущности в XML DTD. Но атакующий способен определить сущность и удалённо, если XML-парсер может делать внешние HTTP-запросы. Как мы видели в описании XXE (внедрения внешней XML-сущности), эту возможность нужно заблокировать в качестве базовой меры защиты. Таким образом, защищаясь от XXE, мы защищаемся и от этого вида атаки.


В любом случае: для этой атаки XML-парсер должен делать внешние HTTP-запросы для извлечения расширенного значения соответствующих сущностей. В свою очередь, они самостоятельно определят новые внешние сущности, к которым парсеру придётся сделать дополнительные HTTP-запросы. Таким образом, парочка безобидно выглядящих запросов быстро выйдет из-под контроля, увеличивая нагрузку на доступные серверные ресурсы, что в результате может привести к рекурсивному расширению сущностей и усугубить ситуацию.

Вышеприведённый код также позволяет провести DOS-атаку более хитрым способом: внешние запросы должны быть адаптированы для локального приложения или любого другого приложения, совместно использующего серверные ресурсы. В результате система будет атаковать сама себя: попытки разложить (resolve) внешние сущности с помощью XML-парсера спровоцируют отправку множества запросов к локальным приложениям и потребление массы серверных ресурсов. Эта атака может использоваться для усиления эффекта XXE-атаки, ради дальнейшего выполнения DOS-атаки.

Защита от расширения XML-сущностей

Методы защиты те же, что и в случае с одиночными XXE-атаками. Нужно отключить разложение (resolution) кастомных XML-сущностей в локальные файлы, а также функции; отключить внешние HTTP-запросы с помощью следующей функции, которая глобально применяется ко всем XML-расширениям PHP, основанным на использовании libxml2.

Однако в PHP не реализовано очевидное средство полного отключения определения кастомных сущностей с помощью XML DTD посредством DOCTYPE. PHP определяет константу LIBXML_NOENT , также есть публичное свойство DOMDocument::$substituteEntities , но они не улучшают ситуацию. Похоже, придётся использовать собственные наборы обходных средств защиты.

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

Таким образом, первичная новая угроза — это грубые подходы с XML-бомбой или общим расширением сущности. Для этих атак не требуются локальные или удалённые системные вызовы, не нужна рекурсия сущностей. По сути, единственное средство защиты — удаление или очистка XML, если он содержит DOCTYPE. Удалять безопаснее, если нам не нужно использовать DOCTYPE и если мы не получили его из надёжного доверенного источника, т. е. через проверенное HTTPS-соединение. В противном случае требуется создавать самопальную логику, потому что PHP не даёт нам работающей опции для отключения DTD. Если предположить, что вы можете вызвать libxml_disable_entity_loader(TRUE) , то следующий код будет безопасен, потому что сущность не расширится, пока нет доступа к заражённому расширением значению узла (node value). А в ходе этой проверки такого не случится.

Конечно, нужно ещё подстраховаться и присвоить libxml_disable_entity_loader значение TRUE, чтобы ссылки на внешние сущности не были разложены (resolve) при первичной загрузке XML. Это может быть единственно возможной защитой там, где XML-парсер не зависит от libxml2, если только этот парсер не имеет исчерпывающего набора опций управления разложением сущностей.

Если вы намерены использовать SimpleXML, то имейте в виду, что с помощью функции simplexml_import_dom() вы можете импортировать проверенный объект DOMDocument.

Что такое код pg_escape_bytea

pg_escape_bytea — мнемонизирует/еscape двоичные данные для типа bytea.

Описание

string pg_escape_bytea (string data)

pg_escape_bytea() мнемонизирует строку для типа данных byteaВозвращает мнемонизированную строку.

Примечание: если вы выполняете SELECT тип bytea, PostgreSQL возвращает восьмеричное байтовое значение с префиксом \ (например, \032). Предполагается, что вы сами конвертируете обратно в двоичный формат.

Эта функция требует наличия PostgreSQL 7.2 или новее. В PostgreSQL 7.2.0 и 7.2.1 тип bytea обязан приводиться, если вы включаете многобайтную поддержку. Т.е. INSERT INTO test_table (image) VALUES (‘$image_escaped’::bytea); PostgreSQL 7.2.2 или новее не требует приведение типа. Исключение — когда клиентская и backend-кодировки символов не совпадают, может появиться ошибка многобайтного потока. Пользователь обязан выполнять приведение к типу bytea, чтобы исключить эту ошибку.

Более новый PostgreSQL будет поддерживать unescape Support для встроенной unescape-функции.

pg_escape_bytea

Escape a string for insertion into a bytea field ( PHP 4 >= 4.2.0, PHP 5 )

pg_escape_bytea() escapes string for bytea datatype. It returns escaped string.

When you SELECT a bytea type, PostgreSQL returns octal byte values prefixed with ‘\’ (e.g. \032). Users are supposed to convert back to binary format manually.

This function requires PostgreSQL 7.2 or later. With PostgreSQL 7.2.0 and 7.2.1, bytea values must be cast when you enable multi-byte support. i.e. INSERT INTO test_table (image) VALUES (‘$image_escaped’::bytea); PostgreSQL 7.2.2 or later does not need a cast. The exception is when the client and backend character encoding does not match, and there may be multi-byte stream error. User must then cast to bytea to avoid this error.

Parameters

PostgreSQL database connection resource. When connection is not present, the default connection is used. The default connection is the last connection made by pg_connect() or pg_pconnect().

A string containing text or binary data to be inserted into a bytea column.

pg_escape_bytea

Руководство по PHP
Пред. След.

pg_escape_bytea

(PHP 4 >= 4.2.0, PHP 5)

pg_escape_bytea — Escape a string for insertion into a bytea field

Описание

pg_escape_bytea() escapes string for bytea datatype. It returns escaped string.

Замечание: When you SELECT a bytea type, PostgreSQL returns octal byte values prefixed with ‘\’ (e.g. \032). Users are supposed to convert back to binary format manually.

This function requires PostgreSQL 7.2 or later. With PostgreSQL 7.2.0 and 7.2.1, bytea values must be cast when you enable multi-byte support. i.e. INSERT INTO test_table (image) VALUES (‘$image_escaped’::bytea); PostgreSQL 7.2.2 or later does not need a cast. The exception is when the client and backend character encoding does not match, and there may be multi-byte stream error. User must then cast to bytea to avoid this error.

Список параметров

A string containing text or binary data to be inserted into a bytea column.

Возвращаемые значения

A string containing the escaped data.

Примеры

Пример 1. pg_escape_bytea() example

// Read in a binary file
$data = file_get_contents ( ‘image1.jpg’ );

// Escape the binary data
$escaped = pg_escape_bytea ( $data );

Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL