Найти - Пользователи
Полная версия: Сканер уязвимостей веб-приложений. Несколько вопросов по архитектуре.
Начало » Python для экспертов » Сканер уязвимостей веб-приложений. Несколько вопросов по архитектуре.
1 2
pento
Всем доброго времени суток.
После перебора попавшихся под руку open source XSS сканеров, понял, что того, чего хотелось бы нет. А хотелось бы хотя бы функционал Xspider.
Собственно, сканер планируется расширяемым, но не по сигнатурам, как в nikto.
В основном затачивается под XSS и SQL уязвимости. GTK GUI и консольные интерфейсы. Работа с задачами и экспорт отчётов в XML/TXT.
А теперь к вопросам :)
1. насколько удачна следующая структура размещения файлов:
spec@baza:~/projects/xcobra > tree 
.
|-- tags
|-- xcobra
| |-- __init__.py
| |-- plugins
| | |-- __init__.py
| | |-- xssplugin.py
| |-- urlfinder.py
| |-- xcobra.py
`-- xcobra.py
xcobra.py ни что иное как
from xcobra.xcobra import Xcobra
import sys
app = Xcobra()
app.run()
Что мне при таком раскладе (файловой структуре) не нравится, так это конструкции вида
        from plugins import xssplugin
        plugin = xssplugin.XSSPlugin()
2. Как посоветуете реализовать работу с плугинами? Регистрация плугина в приложении? Интерфейс? Просто я никогда работу с плугинами не реализовывал,..не охота сильно по граблям ходить и велосипед помимо основного приложения изобретать :)
Andity
2. http://jenyay.net/index.php?n=Programming.PyPlugins
bialix
про плагины уже как-то здесь обсуждалось. Я тогда рекомендовал посмотреть на решение в коде bzr. Ваша предполагаемая организация плагинов очень похожа на bzr. Советую посмотреть код.
pento
Andity
Спасибо за ссылку!
bialix
Хммм, надо будет покопаться в этом “базаре” :)
bialix
bzrlib/plugin.py
pento
bialix
Хмм, посмотрел bzrlib/plugin.py. Не совсем понравилось использование exec.
for name in plugin_names:
        try:
            exec "import bzrlib.plugins.%s" % name in {}
        except KeyboardInterrupt:
            raise
        except Exception, e:

в ссылке выше используется вызов __import__(), что по идеи более правильно для таких целей.
bialix
нравится/ненравится. правильно/неправильно… забавно. вы делаете далеко идущие выводы даже не зная откуда взялся такой код. а ведь он взялся не просто так.
pento
bialix, само собой я не думал, ставить себя выше разработчиков “базара”, тем более, что являюсь начинающим программистом на питоне.
Просто у меня ещё с JavaScript/Perl/PHP вызывают подозрения любые вызовы конструкций типа eval, а в данном случае exec. Это как с рекурсией.
Если есть возможность избежать подобного кода, то зачем его использовать?
В данном случае, есть специальная встроенная функция, тогда, если нет весомых причин, то зачем ею пренебрегать?
В любом случае, спасибо за советы :)

P.S. Кстати, есть предположения, почему разработчиками “базара” был выбран именно такой способ импорта?
bialix
этот код появился как замена imp.load_module (см. стандартный модуль imp). Появился этот код вкупе с другим в этом модуле для того, чтобы плагины могли импортировать друг друга. Насколько я помню функция __import__ никогда не использовалась в Базаре, потому что она имеет ограниченную семантику. Почитайте help на нее.

И вообще-то функции и методы с двумя подчеркиваниями вокруг имени имеют специальный смысл в питоне. Чаще всего их переопределяют. Вобщем __import__ хоть и работает, но это не лучший выбор. Эта функция в частности возвращает самый верхний пакет в случае __import__('lib.plugins.foo') это будет lib. Вобщем не считайте ее панацеей. Для разнообразия гляньте хоть на imp.

exec хоть и выглядит страшно, но работает гораздо правильнее. Тем более что он запускается в пустом пространстве имен (exec … in {}) так что ничего вам не испортит.

статья по ссылке jenyay описывает упрощенный вариант загрузки и использования плагинов, исходя из предположения, что плагины пишутся по каким-то правилам, а также что имена модулей плагинов заранее известны. В Базаре загрузка плагина – это импортирование его кода из любого каталога под любым допустимым в питоне именем. Поэтому для поддержки загрузки плагинов в варианте exe (py2exe) я написал функцию load_from_zip. По ссылке загрузка произвольных плагинов из library.zip не рассматривается. А плавно как-то эта проблема обходится стороной. Ну вобщем и понятно: автор статьи не захотел парить себе голову сложностями.

В Базаре для плагинов используется особенность Питона: во время импорта в Питоне код модуля исполняется. Т.е. во время импорта модуль может дергать функции из основной библиотеки проекта и регистрировать какие-то новые сервисы и классы. Для поддержки этого в Базаре реализованы внутренние реестры для различных подсистем (команды, форматы репозитория, транспорты и т.п.).

Вообще тема разработки приложения с поддержкой плагинов очень отличается от традиционных закрытых и монолитных приложений. Хотя бы тем, что вы не знаете заранее какие плагины будут использоваться и что они привнесут в рантайме. Поэтому мягко говоря статья по ссылке хороша для общего развития. Но реально плагины имеют такую кучу граблей разложеных повсюду, и их все надо учитывать…

Я например несколько месяцев назад искал нормальный редактор с поддержкой возможности писать для него плагины на питоне. Фиг вам. Нормальной, удобной поддержки плагинов я не нашел.
Андрей Светлов
По поводу __import__. Она весьма хороша, когда нужно импортировать неизвестный модуль (имя вычисляется динамически). Практически полностью эквивалентна конструкции import something (за исключением того, что ничего не добавляет в globals). sys.modules изменяются корректно. Для обхода указанных bialix сложностей использовал обертки:

def import_mod(name):

mod = __import__(name)
components = name.split('.')
for comp in components:
mod = getattr(mod, comp)
return mod

def import_name(name):
elems = name.split('.')
mod_name = ‘.’.join(elems)
name = elems
mod = __import__(mod_name, globals(), locals(), )
try:
return getattr(mod, name)
except AttributeError:
raise ImportError, ‘module %s has not attribute %s’%(mod_name, elems)


Замена __import__ - грязный хак с множеством неприятных побочных эффектов (сталкивался, поэтому и говорю). С принятием PEP 302 заменять стало не нужно (смотреть соседнюю ветку. Модуль imp предназначен главным образом для написания import hooks.

То, что вставили в базаре - съедобно. Но, ИМХО, можно и чуть элегантней. Врочем, это не тот вопрос, по которому нужно всерьез спорить. Так - тоже неплохо.

Про сложности архитектуры приложения с поддержкой плагинов в свое время уже говорили…
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB