Similar presentations:
Защита кода на Python или как скрывать нескрываемое?
1.
Защита кодана Python
или как скрывать
нескрываемое?
2.
О чем доклад?Повесть о развитии проекта
и о том, как мы дошли до жизни такой
Рассказ о боли защиты кода
Итоги, к которым мы пришли
3.
О себеРуководитель отдела
Техлид
Backend: Python, Go
Иногда DevOps…
4.
Чем мы занимаемся?Видеонаблюдение
Удаленная телеметрия
Умный дом
СКУД
5.
Чем мы занимаемся?6.
Наша слава в интернете7.
Коротко о проектеЯдро
Python / Django
Service 1
Python
Service 2
Go
8.
Что такое УД?Клиенты
ЮЛ
Клиенты
9.
Коробочное решениеЯдро
Python / Django
Service 1
Python
Service 2
Go
10.
Зачем?11.
Зачем?Законодательство
12.
Зачем?Законодательство
Географическая
удаленность
13.
Зачем?Законодательство
Географическая
удаленность
Так спокойнее
14.
Вопросы по перездуОтрицание
Гнев
Торг
Депрессия
Как разворачивать?
Какие ресурсы нужны?
Защита кода
15.
От чего защищаться?16.
От чего защищаться?Защита
от модификации
17.
От чего защищаться?Защита
от модификации
Защита
от тиражирования
18.
С этим вопросом…19.
Критерии оценки методов20.
Критерии оценки методовБезопасность
21.
Критерии оценки методовБезопасность
Простота
настройки
22.
Критерии оценки методовБезопасность
Простота
настройки
Поддержка
23.
Нефункциональные требования24.
Нефункциональные требованияСохранить
преимущества языка
25.
Нефункциональные требованияСохранить
преимущества языка
Как можно меньше
изменений в проекте
26.
Какие есть решения?27.
Решение №1 - смирись28.
Решение №1 - смирисьPython про другое!
Предназначен
делиться знаниями,
а не скрывать их
29.
Решение №1 - смирись— А почему его зовут Неуловимым Джо, Билли?
— Потому что его никто ещё не поймал, Гарри.
— А почему его никто ещё не поймал, Билли?
— Потому что он никому не нужен, Гарри.
30.
Решение №1 – выводыНичего не нужно делать
Метод работает до первого мошенника
Безопасность
Простота настройки
Поддержка
1/10
10/10
10/10
31.
Решение №2 - перепиши32.
ВыводыКод скрыт под компиляцией
Долго и дорого
Теряем преимущества Python
(простота синтаксиса, время онбординга, скорость разработки)
Безопасность
Простота настройки
Поддержка
9/10
2/10
7/10
33.
Решение №2.1 – перепиши на CythonCython – язык программирования,
упрощающий написание модулей
С/C++ кода для Python
http://docs.cython.org
/en/latest/src/tutorial
/pure.html
Особенности Cython:
- Работа со строками
- Оператор IS
34.
Решение №2.1 – выводыКод скрыт под компиляцией
Можно передавать python-файлы без изменения
Для лучшей защиты кода требует разметки
Нюансы самого языка
Безопасность
Простота настройки
Поддержка
8/10
2/10
6/10
35.
Решение №2.2 – JIT-компиляторhttps://numba.pydata.org/
from numba import jit
@jit
def f(x, y):
return x + y
36.
Решение №2.2 – выводыКод скрыт под компиляцией
Обязательно требует разметки
Новый стек для команды
Безопасность
Простота настройки
Поддержка
8/10
2/10
4/10
37.
Решения №2 - выводыКод становится более защищенным
Много месяцев разработки в 3 проектах
Безопасность
Простота настройки
Поддержка
9/10
2/10
8/10
38.
Решение №3 – отдавай pyc-файлыByte
Code
Run
Code
39.
Решение №3 – отдавай pyc-файлыОбратимость байткода
def foo():
"""Тестовая функция"""
print("Hello, Ufadevconf!")
if __name__ == "__main__":
foo()
python -m compileall main.py
40.
Решение №3 – отдавай pyc-файлыОбратимость байткода
41.
Решение №3 – отдавай pyc-файлыОбратимость байткода
https://pypi.org/project/uncompyle6/
42.
Решение №3 – отдавай pyc-файлыОбратимость байткода
43.
Решение №3 – выводыПодходит, если нужно хоть как-то скрыть код
быстро и без переписывания
Нативен для Python
Безопасность
Простота настройки
Поддержка
0/10
9/10
9/10
44.
Решение №4 – обфускация кодаhttps://github.com/dashingsoft/pyarmor
45.
Решение №4 – выводыБыстро
Trial-версия имеет ограничение в 32768 байт
Безопасность
Простота настройки
Поддержка
8/10
5/10
6/10
46.
Решение №5 – готовое решение47.
Решение №6 – Pyinstallerhttps://pyinstaller.org/en/stable/
pip install -U pyinstaller
pyinstaller your_program.py
48.
Решение №7 – свой импортерPEP 302 – New Import Hooks
PEP 451 - A ModuleSpec Type for the Import System
49.
Решение №7 – свой импортерFinder и Loader
PEP 302
До версии 3.4
- finder.find_module(fullname, path=None)
- loader.load_module(fullname)
PEP 451
С версии 3.4
-
finder.find_spec(name, path, target)
loader.exec_module(module)
loader.create_module(spec)
50.
Решение №7 – свой импортерimport foo
Делаем все возможное
sys.modules
sys.meta_path
sys.path_importer_cache
Нашли?
sys.path_hooks
Да
ImportError
51.
Решение №7 – свой импортерSOURCE_SUFFIXES = ['.py']
BYTECODE_SUFFIXES = ['.pyc']
def _get_supported_file_loaders():
extensions = ExtensionFileLoader, _imp.extension_suffixes()
source = SourceFileLoader, SOURCE_SUFFIXES
bytecode = SourcelessFileLoader, BYTECODE_SUFFIXES
return [extensions, source, bytecode]
52.
Решение №7 – свой импортерСвой
Loader
class MyLoader(SourceLoader):
def get_data(self, filename):
with open(filename) as f:
a = f.read().encode('utf-8')
if a == b"":
return a
data = base64.b64decode(a)
return data
53.
Решение №7 – свой импортерИнъекция в Python
loader_details = MyLoader, [".pyenc"]
def install():
sys.path_hooks.insert(0, MyFinder.path_hook(loader_details))
sys.path_importer_cache.clear()
invalidate_caches()
54.
Решение №7 – свой импортерПример
https://github.com/UsmanovTimur/encoding_django
55.
Решение №7 – выводыМожно внести свою логику
Сложный в понимании и реализации
Некоторые python-библиотеки перестают работать
Безопасность
Простота настройки
Поддержка
7/10
1/10
1/10
56.
Могло быть так57.
Решение №8 – транспиляцияТранспиляция – перевод исходного
кода программы с одного языка
программирования на другой.
Nuitka – транспайлер, который
транслирует код Python в исполняемые
файлы или исходный код C/C++
58.
Решение №8 – транспиляцияВарианты сборки
1) Собрать исполняемый файл
python -m nuitka --follow-imports program.py
Подходит для сервисов в себе
Долго собирается и много весит
59.
Решение №8 – транспиляцияВарианты сборки
2) Собрать исполняемый модуль
python -m nuitka --module some_module.py
Гибкий вариант
Есть шанс наплодить много файлов
60.
Решение №8 – транспиляцияПростой способ применения
for f in $(find . -name "*.py" |grep -v __init__.py)
do
echo $f
nuitka3 --module --output-dir=$(dirname $f)
--no-pyi-file $f
rm $f
done
--remove-output
61.
Решение №8 – транспиляцияЕще вариация
for f in $(cat encrypt_files.txt)
do
echo $f
nuitka3 --module --output-dir=$(dirname $f) $f
rm $f
done
62.
Решение №8 – транспиляцияВарианты сборки
3) Собрать исполняемый пакет
python -m nuitka --module package --include-package=package
В Django могут возникнуть проблемы с
импортами миграций
Их можно закрыть как модуль
63.
Решение №8 – транспиляцияСборка пакета
nuitka3 --module core --include-package=core --removeoutput --no-pyi-file --follow-import-to=core
64.
Решение №8 – выводыЕсли у вас компактный микросервис - супер
Если у вас монолит на 5k только python-файлов –
закрыть все не сможете
Итоговые бинарники работают “бесшовно”
Нужно шаманить с настройкой
Безопасность
Простота настройки
Поддержка
9/10
4-8/10
8/10
65.
Решение №9 – несофтовые способы1) Шифрование ВМ
2) Железный сервер с эксклюзивным доступом
- Посчитать экономику
- Вопрос масштабирования и замены оборудования
1) Размещение в облаке той страны где клиент
- За пределами РФ – боль!
1) Добавьте ценность вашему продукту(обновления
багфиксы и т.д.)
66.
Выводы по решениямПерепиши
Безопасность
Простота
настройки
Поддержка
PYC
Pyarmor
Pyinstaller
Importer
Nuitka
9
0
8
3
7
9
2
9
5
3
1
8
7
9
6
3
1
8
67.
Nuitka – нравиться!Простота
Скорость внедрения
Гибкость настройки
Не нужно переучивать
разработчиков. Вся магия CI
68.
КонецСпасибо за внимание!