├── CHANGES ├── Makefile ├── README.md ├── modsecurity ├── __init__.py └── modsecurity.i ├── setup.py └── tests └── t.py /CHANGES: -------------------------------------------------------------------------------- 1 | DD mmm YYYY - To be released 2 | ---------------------------- 3 | 4 | * Make it compatible with Python3 and a refactoring at find_modsec. 5 | [Julien Voisin] 6 | * Update the README and installation documentation. 7 | [Chaim Sanders] 8 | * The project is workable and published. 9 | [Felipe Zimmerle] 10 | 11 | 12 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: 2 | swig -I/usr/local/modsecurity/include/ -python -builtin -Wall -Wextra -c++ modsecurity/modsecurity.i 3 | python setup.py build_ext --inplace 4 | 5 | test: 6 | tests/t.py 7 | 8 | install: 9 | python setup.py install --prefix=/usr 10 | 11 | clean: 12 | @rm modsecurity/modsecurity_wrap.cxx 13 | @rm -rf build 14 | @rm _modsecurity.so 15 | @rm modsecurity/modsecurity.py 16 | @rm *.pyc tests/*.pyc modsecurity/*.pyc 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NOTE 2 | 3 | This project was outdated by the **pymodsecurity** project (https://github.com/actions-security/pymodsecurity). At **pymodsecurity** you can get a more stable and feature complete bindings for libmodsecurity. 4 | 5 | # Introduction 6 | 7 | The following are a set of Swig generated Python bindings for libmodsecurity. These bindings will allow users to utilize the exposed libmodsecurity interfaces directly from python, without the use of ctypes. 8 | 9 | # Compilation 10 | 11 | Although these are python scripts DO NOT use setup.py to compile this. Instead, one should use the Makefile in order to compile these. This can be done by typing 'make'. Be aware that the Python development headers and Swig are required to build this package. These can be obtained on RHEL via 'dnf install swig python-devel' 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /modsecurity/__init__.py: -------------------------------------------------------------------------------- 1 | from modsecurity import * 2 | -------------------------------------------------------------------------------- /modsecurity/modsecurity.i: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity, http://www.modsecurity.org/ 3 | * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License. You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | * 14 | * Author: Felipe "Zimmerle" Costa 15 | * 16 | */ 17 | 18 | %module modsecurity 19 | 20 | %include 21 | %include 22 | %include 23 | %include 24 | %include 25 | %include "attribute.i" 26 | %include "carrays.i" 27 | %include "typemaps.i" 28 | 29 | #%ignore RulesProperties::parserError; 30 | 31 | %{ 32 | #include "modsecurity/intervention.h" 33 | #include "modsecurity/collection/variable.h" 34 | #include "modsecurity/collection/collection.h" 35 | #include "modsecurity/collection/collections.h" 36 | #include "modsecurity/transaction.h" 37 | #include "modsecurity/debug_log.h" 38 | #include "modsecurity/modsecurity.h" 39 | #include "modsecurity/rules_properties.h" 40 | #include "modsecurity/rules.h" 41 | #include "modsecurity/rule.h" 42 | 43 | using std::basic_string; 44 | %} 45 | 46 | %rename(_del) modsecurity::collection::Variables::del(const std::string& key); 47 | %rename(_del) modsecurity::collection::Collections::del(const std::string& key); 48 | 49 | %immutable modsecurity::ModSecurityIntervention_t::url; 50 | %immutable modsecurity::ModSecurityIntervention_t::log; 51 | 52 | %immutable modsecurity::Transaction::m_clientIpAddress; 53 | %immutable modsecurity::Transaction::m_httpVersion; 54 | %immutable modsecurity::Transaction::m_method; 55 | %immutable modsecurity::Transaction::m_serverIpAddress; 56 | %immutable modsecurity::Transaction::m_uri; 57 | 58 | %ignore modsecurity::RulesProperties::parserError const; 59 | %ignore modsecurity::Transaction::m_requestBody; 60 | %ignore modsecurity::Transaction::m_responseBody; 61 | 62 | %include "modsecurity/intervention.h" 63 | %include "modsecurity/collection/variable.h" 64 | %include "modsecurity/collection/collection.h" 65 | %include "modsecurity/collection/collections.h" 66 | %include "modsecurity/transaction.h" 67 | %include "modsecurity/debug_log.h" 68 | %include "modsecurity/modsecurity.h" 69 | %include "modsecurity/rules_properties.h" 70 | %include "modsecurity/rules.h" 71 | %include "modsecurity/rule.h" 72 | 73 | 74 | %template(RuleVector) std::vector; 75 | %template(VectorOfRuleVector) std::vector >; 76 | %template(StringVector) std::vector; 77 | 78 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | 4 | ModSecurity, http://www.modsecurity.org/ 5 | Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) 6 | 7 | You may not use this file except in compliance with 8 | the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | If any of the files related to licensing are missing or if you have any 13 | other questions related to licensing please contact Trustwave Holdings, Inc. 14 | directly using the email address security@modsecurity.org. 15 | 16 | Author: Felipe "Zimmerle" Costa 17 | 18 | """ 19 | 20 | from distutils.core import setup, Extension 21 | import os 22 | import sys 23 | 24 | possible_modsecurity_dirs = [ 25 | "/usr/local/modsecurity/", 26 | "/usr/", 27 | "/usr/local/" 28 | ] 29 | 30 | libraries_dir = [ 31 | "lib/", 32 | "lib64/", 33 | "./" 34 | ] 35 | 36 | headers_dir = [ 37 | "include/", 38 | "headers/", 39 | "./" 40 | ] 41 | 42 | 43 | def find_modsec(): 44 | def find_library(modsec_dir): 45 | for i in libraries_dir: 46 | path = os.path.join(modsec_dir, i, "libmodsecurity.so") 47 | if os.path.isfile(path): 48 | return os.path.join(modsec_dir, i) 49 | return None 50 | 51 | def find_header(modsec_dir): 52 | for i in headers_dir: 53 | path = os.path.join(modsec_dir, i, "modsecurity", "modsecurity.h") 54 | if os.path.isfile(path): 55 | return os.path.join(modsec_dir, i) 56 | return None 57 | 58 | inc = lib = None 59 | for modsec_dir in possible_modsecurity_dirs: 60 | if not inc: 61 | inc = find_header(modsec_dir) 62 | if not lib: 63 | lib = find_library(modsec_dir) 64 | 65 | return (inc, lib) 66 | 67 | inc_dir, lib_dir = find_modsec() 68 | 69 | 70 | print("*** found modsecurity at:") 71 | print(" headers: " + str(inc_dir)) 72 | print(" library: " + str(lib_dir)) 73 | 74 | 75 | if inc_dir == None or lib_dir == None: 76 | print("libModSecurity was not found in your system.") 77 | print("Make sure you have libModSecurity correctly installed in your system.") 78 | sys.exit(1) 79 | 80 | 81 | #if os.path.isfile("modsecurity/_modsecurity_module.cc") == False: 82 | # print "Swig generated code was not found. Please run `make' first" 83 | # sys.exit(1) 84 | 85 | 86 | extension_mod = Extension( 87 | "_modsecurity", [ 88 | "modsecurity/modsecurity_wrap.cxx" 89 | ], 90 | libraries=["modsecurity"], 91 | swig_opts=['-Wextra', '-builtin'], 92 | library_dirs=[lib_dir], 93 | runtime_library_dirs=[lib_dir], 94 | include_dirs=[inc_dir, "."], 95 | extra_compile_args=["-std=c++11", "-Wno-maybe-uninitialized"] 96 | ) 97 | 98 | 99 | setup( 100 | name = "modsecurity", 101 | description = 'Python Bindings for libModSecurity', 102 | author = 'Felipe Zimmerle', 103 | author_email = 'felipe@zimmerle.org', 104 | url = 'https://github.com/SpiderLabs/ModSecurity-Python-bindings', 105 | ext_modules = [extension_mod], 106 | packages = ['modsecurity'], 107 | classifiers = [ 108 | 'Topic :: Security', 109 | 'Topic :: Internet :: WWW/HTTP' 110 | ] 111 | ) 112 | 113 | 114 | -------------------------------------------------------------------------------- /tests/t.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | """ 3 | 4 | ModSecurity, http://www.modsecurity.org/ 5 | Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) 6 | 7 | You may not use this file except in compliance with 8 | the License. You may obtain a copy of the License at 9 | 10 | http://www.apache.org/licenses/LICENSE-2.0 11 | 12 | If any of the files related to licensing are missing or if you have any 13 | other questions related to licensing please contact Trustwave Holdings, Inc. 14 | directly using the email address security@modsecurity.org. 15 | 16 | Author: Felipe "Zimmerle" Costa 17 | 18 | """ 19 | 20 | import sys 21 | import unittest 22 | 23 | sys.path.append("..") 24 | sys.path.append(".") 25 | import modsecurity 26 | 27 | 28 | class TestStringMethods(unittest.TestCase): 29 | 30 | def test_version(self): 31 | self.assertRegexpMatches(str(modsecurity.ModSecurity().whoAmI()), ".*ModSecurity.*") 32 | 33 | def test_load_rules(self): 34 | rules = modsecurity.Rules() 35 | ret = rules.load('SecRule ARGS_POST|XML:/* "(\n|\r)" "id:1,deny,phase:2"') 36 | self.assertEqual(ret, 1) 37 | ret = rules.load(""" 38 | SecRule ARGS_POST|XML:/* "(\n|\r)" "id:1,deny,phase:2" 39 | SecRule ARGS_POST|XML:/* "(\n|\r)" "id:2,deny,phase:2" 40 | """) 41 | self.assertEqual(ret, 2) 42 | ret = rules.getRulesForPhase(3) 43 | self.assertEqual(ret.size(), 3) 44 | 45 | def test_load_bad_rules(self): 46 | rules = modsecurity.Rules() 47 | ret = rules.load('SecRule ARGS_POST|XML:/* "(\n|\r)" "deny,phase:2"') 48 | self.assertEqual(ret, -1) 49 | ret = rules.getParserError() 50 | self.assertRegexpMatches(ret, "Rules must have an ID.*") 51 | 52 | if __name__ == '__main__': 53 | unittest.main() 54 | 55 | --------------------------------------------------------------------------------