Это не уязвимость, а бекдор. Если проект использует eval, compile, pickle, shelve и прочее - тут гадать не приходится - это бекдор. А те дeбилы, которые ставят какое попало гoвно из пакетов, даже не удосужившись просканировать код на предмет eval, compile, pickle, shelve, subprocess, os, cython заслуживают того, что получают.А основателя проекта надо внести в чёрный список как работника спецслужб, потому что это лично его фейл, что на code review не был завёрнут любой код, использующий опасные функции.
А теперь давайте подумаем, что с этим дерьмом делать.
IMHO выход только один - пакеты питона должны иметь манифест, в котором прописаны разрешения, и эти разрешения должны энфорситься на уровне интерпретатора. Динамические импорты, евалы и компиляция кода должны быть по умолчанию запрещены, на всё это должно быть отдельное разрешение.
Введём несколько определений.
* security context - список того, что можно делать модулю и его зависимостям. Каждому модулю назначается security context. Существует особый security context `*`, означающий "эту переменную можно читать всем контекстам".
* security marker - метка, присваиваемая каждому символу, используемая для проверки привилегий. Маркер содержит в себе два множества указателей на контекст: входное и выходное. Входное определяет тех, кто повлиял на переменную, выходное - всех, кому разрешено её читать. Все созданные в модуле переменные по-умолчанию имеют marker, входное множество которого состоит из контекста этого модуля, а выходное - из контекста "*".
* манифест - набор метаданных в декларативной форме, описывающий в том числе привилегии модуля.
* переменная a влияет на переменную b когда значение переменной b при прочих равных условиях (значения остальных переменных, отсутствие истиной случайности) зависит только от переменной a.
Примеры:
```
b=a+1
```
```
if a==0xf00c:
b*=100
else:
b*=1000
```
Влияние транзитивно: если а влияет на b и b влияет на c, то a влияет на c.
При влиянии одной переменной на другую маркер влияющей переменной вливается в маркер влияемой.
* слияние маркеров. При вливании маркера a в маркер b входное множество указателей на контекст маркера b заменяется на объединение входных множеств маркеров a и b. Выходное множество заменяется на пересечение. Если выходное множество пустое, сразу происходит ошибка.
* import - использование модулем модуля.
В начале каждого исходника размещается манифест.
1 В этом манифесте перечисляются ВСЕ импорты модуля. То есть если модуль использует numpy, то об этом пишется в манифесте.
```imports numpy```
2 перечисляются используемые разрешения.
Если сам модуль читает произвольные файлы, то пишется "use permission filesystem:read-any".
```
def readShit(fn):
with open(fn): # проверка контекста производится при вызове open
```
Если сам модуль произвольные файлы не читает, какие файлы читаются не контролирует, но одна из его зависимостей это делает и, этот кусок кода будет исполнен в ходе работы модуля, и для нормальной работы данного модуля требуется, чтобы зависимость действительно имела возможность прочитать любые файлы, то пишется
`dependency_name: uses permission filesystem:read-any`.
```
from shit import loadPalletes
def a():
pals=loadPalletes()
```
```
def loadPalletes():
with open(palettesDir / "palettes.sqlite") as f:
```
где palettesDir может быть любой папкой в системе.
Если сам модуль произвольные файлы по своей инициативе не читает, а читает по запросу вызывающего модуля, то пишется
`provides permission filesystem:read-any`.
Например,
```
from shit import loadPallete
def a(fileName):
pals=loadPallete(fileName)
```
```
def loadPallete(fileName):
with open(fileName) as f:
```
.
* проверка привилегий
Привилегии проверяются на этапе компиляции AST в байт-код. Без выполнения. Такая вот питонья ржавчина. Проверка привилегий происходит при вызове функций и при чтении переменных.
* привилегированные функции - функции, при вызове которых проверяются привилегии. Переменная, подаваемая на вход функции, в входном множестве security markerа не должна содержать контекстов, не имеющих этой привилегии.
Возвращаемое значение привилегированной функции имеет security marker, в выходное множество которого является подмножеством объединения входных множеств аргументов.
У нас ещё есть время до python 4, так что предлагаю начать разработку системы уже сейчас.
Регаться на баг-трекере не буду, залейте туда текст этого сообщения за меня. Прошу считать текст этого сообщения общественным достоянием.