Adds support to Python scripts on ModSecurity core.

Analog of what we have for Lua, Python support is now added by this commit.
This is very experimental.
This commit is contained in:
Felipe Zimmerle
2014-08-26 07:18:57 -07:00
parent c17bf6ad42
commit 2440a23921
18 changed files with 903 additions and 18 deletions

56
scripts/python/modsecurity.py Executable file
View File

@@ -0,0 +1,56 @@
#!/usr/bin/env python
from __future__ import print_function
import sys
# Needs to be singlenton ?
class Singleton(object):
_instances = {}
"""
def __new__(class_, *args, **kwargs):
if class_ not in class_._instances:
class_._instances[class_] = super(Singleton, class_).__new__(class_, *args, **kwargs)
return class_._instances[class_]
"""
class ModSecurity():
def __init__(self):
self.default_attr = ["default_attr", "name", "modsecCore"]
self.name = None
self.modsecCore = None
def setModSecurityCore(self, cb):
self.modsecCore = cb
self.log(8, "Log attached");
return True
def log(self, level, msg):
if self.modsecCore == None:
print("ModSecurity Python: ", str(level) + " " + str(msg), file=sys.stderr)
else:
self.modsecCore.log(level, msg)
return True
def __getattribute__(self, key):
v = None
try:
v = object.__getattribute__(self, key)
if hasattr(v, '__get__'):
return v.__get__(None, self)
except:
if self.modsecCore != None:
v = self.modsecCore.getVariable(key)
return v
def __setattr__(self, name, value):
self.__dict__[name] = value
if name not in self.default_attr:
if self.modsecCore != None:
self.modsecCore.setVariable("tx." + name, value)
"""
TODO: transformation
"""

15
scripts/python/setup.py Normal file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env python
from distutils.core import setup
setup(name="ModSecurity Python extension",
version="0.1",
description="ModSecurity python externsion",
author="Felipe Zimmerle",
author_email="felipe@zimmerle.org",
url="http://www.modsecurity.org",
py_modules=['modsecurity'],
keywords="ModSecurity WAF Security",
)

50
scripts/python/skell.py Executable file
View File

@@ -0,0 +1,50 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# ModSecurity core binding.
from modsecurity import ModSecurity
class ModSecurityExtension(ModSecurity):
"""
Class ModSecurityExtension should represents your custom module.
Nocite that this class should derivate from ModSecurity and should
implement the method process.
"""
def __init__(self):
ModSecurity.__init__(self)
def process(self):
"""
The method is called by ModSecurity core whenever a request is
needed to be evaluated.
"""
# self.log can be utilised to produce content inside the SecDebugLog
# (https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#secdebuglog)
self.log(8, "This is our custom Python script, it seems that I am working"
"like a charm.")
self.log(8, "Hum... Do we have something at FILES_TMPNAMES? %s" %
self.FILES_TMPNAMES)
# Returns True whenever you want to send a "match" to ModSecurity core.
return True
# Should be used to test your custom extension, deattached from ModSecurity core.
if __name__ == "__main__":
myExtension = ModSecurityExtension()
# Setting FILES_TMPNAMES property.
# https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#files_tmpnames
myExtension.FILES_TMPNAMES = [ "/etc/issue", "/etc/resolv.conf" ]
# Process the content.
ret = myExtension.process()
if ret == True:
print("Matched!")
else:
print("_not_ matched")