В Clojure, как я могу защитить функцию «разрешения» для пользовательского ввода? - PullRequest
0 голосов
/ 01 октября 2019

Моя проблема

В настоящее время я пишу REST-API, который должен принимать запросы JSON и работать с используемой нами библиотекой-интерном. Основное использование будет состоять в том, чтобы либо запустить сервер с веб-интерфейсом, либо использовать другой язык для работы с API, поскольку Clojure не распространен в других местах.

Чтобы достичь этого, запрос JSON содержит данные и имя функции, которые запускаются с разрешением, поскольку я должен сделать это так, чтобы нам не приходилось каждый раз менять функциюдобавлен / удален

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

Итак, что я уже пробовал?

Так вот, я до сих пор говорил только половину правды: я не использую разрешение, я использую ns-разрешение. Моя первая интуиция состояла в том, чтобы создать отдельный файл, который будет загружаться во все пространства имен из библиотеки, с этим вы ничего не поделаете. Проблема в том, что мне нужны только эти функции, и я не знаю ни одного способа удаления функций clojure.core. Я мог бы сделать черный список для тех, но белый список был бы намного легче. Не говоря уже о том, что я никогда не смогу найти все основные функции, которые на самом деле должны быть в черном списке.

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

Еще одна проблема, которую я слышал, заключается в том, что некоторые функции могут запускать ввод в качестве аргумента задолго до того, как предполагалось. Сервер работает с кольцом и его расширением JSON. JSON должен давать только строки, числа, логические значения и nil как атомарные типы данных. Я пришел к выводу, что каждый возможный злонамеренный ввод должен быть строкой на моем конце - помимо решения, есть ли какая-либо функция, которая может иметь побочный эффект от запуска такого ввода? Поскольку они строковые: есть ли какая-то проблема с данными вообще?

Ответы [ 2 ]

1 голос
/ 01 октября 2019

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

Вы могли бы добавить флаг метаданных к предоставляемым функциям, которые вы проверяете в местах их разрешения.

Все остальное должно быть просто данными;не оценивайте это.

0 голосов
/ 01 октября 2019

Вероятно, вы хотите рассмотреть следующее:

  • Как определить публичные функции из заданного пространства имен. Это даст вам список допустимых имен функций, которые ваш API может принимать как часть ввода. Вот пример:
user=> (ns-publics (symbol "clojure.string"))
{ends-with? #'clojure.string/ends-with?, capitalize #'clojure.string/capitalize, reverse #'clojure.string/reverse, join #'clojure.string/join, replace-first #'clojure.string/replace-first, starts-with? #'clojure.string/starts-with?, escape #'clojure.string/escape, last-index-of #'clojure.string/last-index-of, re-quote-replacement #'clojure.string/re-quote-replacement, includes? #'clojure.string/includes?, replace #'clojure.string/replace, split-lines #'clojure.string/split-lines, lower-case #'clojure.string/lower-case, trim-newline #'clojure.string/trim-newline, upper-case #'clojure.string/upper-case, split #'clojure.string/split, trimr #'clojure.string/trimr, index-of #'clojure.string/index-of, trim #'clojure.string/trim, triml #'clojure.string/triml, blank? #'clojure.string/blank?}
  • Вы, вероятно, хотите использовать ключи из карты выше (в пространстве имен, которое относится к вашему варианту использования), чтобы проверить ввод, потому что вы можете "экранируйте пространство имен ns-resolve, если вы полностью определите имя функции:
user=> ((ns-resolve (symbol "clojure.string") (symbol "reverse")) "hello")
"olleh"

user=> ((ns-resolve (symbol "clojure.string") (symbol "clojure.core/reverse")) "hello")
(\o \l \l \e \h) ;; Called Clojure's own reverse, probably you don't want to allow this

Теперь, с учетом сказанного, я дам вам несколько бесплатных советов:

Я должен сделать так, чтобы нам не приходилось менять API каждый раз, когда добавляется / удаляется функция

Если вы смотрели некоторые выступления Рича Хикки, вы 'Вы узнаете, что изменения API - разумная тема. В общем, вы должны тщательно подумать, прежде чем добавлять новые функции или подумать об их удалении, потому что похоже, что ваша команда готова срезать углы при объединении клиентов API на одной странице.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...