Пожалуйста, сделайте ваш язык анализируемым / проверяемым для людей, занимающихся компьютерной безопасностью.
Сотрудники службы безопасности должны быть в состоянии найти уязвимости в программе до ее отправки. В идеале, мы звоним раньше и можем комментировать кодовую базу по мере ее развития, но часто нет.
Когда выйдет новая версия языка или базовых библиотек, вещи, которые ранее были безопасными, могут перестать быть:
- библиотеки могут стать более мощными: например, библиотека URL теперь поддерживает
javascript:
- могут быть новые способы преобразования строк или байтов в код: например,
eval
библиотеки десериализации
- методы отражения языка могут стать более мощными: например, экспонирование локальных переменных
Любое из этих изменений может увеличить количество злоупотребляемых правами, которыми обладает программа, но, поскольку количество прав, которыми пользуется программа (при работе с не вредоносными клиентами), не изменилось, специалистам по безопасности трудно понять это без интенсивного повторный аудит.
Поэтому, пожалуйста, подумайте о нас при разработке и создании версий языка. Ниже приведены несколько советов:
Определите несколько примитивов, на которые программа может быть разложена.
HTML5 особенно плох в этом смысле. Они, очевидно, много думают о безопасности и имеют очень умных людей, но вместо того, чтобы указывать новые элементы программы, например, <video>
в терминах старых, или создавать общую абстракцию, в которой новые <video>
и старые <img>
оба могут быть указаны в терминах, <video>
еще нет. еще один одноразовый элемент программы со своими собственными последствиями для безопасности.
Сделайте свой язык пригодным для статического анализа (даже если он не статически типизирован).
Специалисты по безопасности часто используют статический анализ, чтобы найти шаблоны и попытаться исключить части программы, чтобы они могли сосредоточиться на действительно сложных моментах.
Должно быть очевидно, какие идентификаторы являются локальными переменными, а какие нет.
Например, не делайте ту же ошибку, что и в старых версиях JavaScript, из-за чего невозможно определить, x
является ли ссылка на локальную переменную ниже (согласно буквальному прочтению старой версии спецификации):
if (Math.random() > 0.5) {
Object.prototype.x = 0;
}
function f() {
var x = 1;
(function () {
alert(x); // Might alert 0, might alert 1.
})();
}
Разрешить для разложимой безопасности
Многие защищенные системы спроектированы вокруг безопасного ядра, которое сохраняет свойства безопасности, так что специалисты по безопасности могут сосредоточить свои усилия на анализе небольшого количества кода и избавлении большинства программистов от необходимости иметь дело с {раздражающими, педантичными, параноидальными} специалистами по безопасности ,
Должно быть возможно написать такое ядро на вашем языке. Если одно из свойств безопасности вашего языка, это то, что когда-либо будет выбрано только определенное подмножество URL, могут ли разработчики ядра сделать что-то, чтобы направить всю выборку URL через их код? Или статические проверки сборки (например, просмотр импорта) могут выполнять ту же функцию.
Некоторые языки, такие как Newspeak, используют модель возможностей объекта. Это потрясающий и отличный способ получить разложимую безопасность.
Но если вы не можете этого сделать, превращение графов модулей в статически анализируемый артефакт может принести вам немало пользы. Если я могу доказать, что модуль не может достичь модуля файлового ввода-вывода (кроме как путем вызова кода в модуле в TCB), то я могу исключить из этого модуля целые классы проблем.
Ограничить авторитет встроенных скриптовых языков
Многие полезные системы организованы как статическое ядро, которое запускает много кода, написанного на динамических (даже функциональных) языках.
А встраивание языков сценариев может сделать систему намного более расширяемой.
Но язык сценариев не должен обладать всеми полномочиями виртуальной машины.
Если вы решите разрешить встроенные языки сценариев, сделайте так, чтобы вызывающий мог ограничить свои возможности. Модель объектных возможностей (см. Комментарий к Newspeak выше) очень уместна здесь; поэтому при оценке кода на языке сценариев вызывающая сторона должна передать код для выполнения и все глобальные переменные для этого кода.
Рассматривать eval
как язык, внедряющий себя как язык сценариев
Если ваш язык может вызывать свой собственный компилятор, чтобы превратить строку в код, тогда разрешите ее помещать в песочницу так же, как любой встроенный язык сценариев.
Используйте простую модель параллелизма
Мы, сотрудники службы безопасности, не хотим беспокоиться о состоянии гонки, когда пытаемся выяснить, поддерживается ли свойство безопасности.
Пожалуйста, рассмотрите альтернативы многопоточности перед установкой на нити как практически невозможный для безопасности вариант по умолчанию.
Одним из простых является параллелизм цикла событий, подобный тому, который есть в E, Verilog и JavaScript.
Не поощряйте цитирование путаницы
Некоторые языки - это склеенные языки, и они заканчивают тем, что имеют дело со строками на многих разных языках.
Например, JavaScript часто состоит из строк HTML, CSS, XML, JSON и даже JavaScript. Программистам очень трудно помнить, как правильно кодировать строки простого текста при их объединении в строки на других языках, поэтому неудивительно, что в программах JS возникают проблемы с запутыванием в кавычках: XSS - наихудший вариант.
Если вы хотите включить функции компоновки строк, попробуйте уменьшить нагрузку на безопасность программиста. DSL, гигиенические макросы и встроенные языки шаблонов могут быть отличным способом сделать это, перенеся бремя правильного перехода на библиотеку или разработчиков языка и от конечного разработчика.