Skip to content

Commit ad930e6

Browse files
committed
Integrate modsecurity logs into django
1 parent 9d15553 commit ad930e6

File tree

5 files changed

+39
-7
lines changed

5 files changed

+39
-7
lines changed

django_pymodsecurity/middleware.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def __init__(self, get_response):
2525
self.get_response = get_response
2626

2727
self.modsecurity = ModSecurity.ModSecurity()
28+
self.modsecurity.setServerLogCb(self.modsecurity_log_callback)
2829
self.rules = ModSecurity.Rules()
2930

3031
self.rule_files = getattr(settings, SETTINGS_NAMES['rule_files'], None)
@@ -42,6 +43,9 @@ def __init__(self, get_response):
4243
if self.rule_lines is not None:
4344
self.load_rules(self.rule_lines)
4445

46+
def modsecurity_log_callback(self, data, msg):
47+
logger.info(msg)
48+
4549
@property
4650
def rules_count(self):
4751
return self._rules_count
@@ -58,7 +62,6 @@ def load_rule_files(self, rule_files):
5862
if rules_count < 0:
5963
msg = '[ModSecurity] Error trying to load rule file %s. %s' % (
6064
rule_file, self.rules.getParserError())
61-
print(msg)
6265
logger.warning(msg)
6366
else:
6467
self._rules_count += rules_count
@@ -75,7 +78,6 @@ def load_rules(self, rules):
7578
if rules_count < 0:
7679
msg = '[ModSecurity] Error trying to load rules: %s' % self.rules.getParserError(
7780
)
78-
print(msg)
7981
logger.warning(msg)
8082
else:
8183
self._rules_count += rules_count

environment.devenv.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: django-pymodsecurity
22

33
dependencies:
44
- django=2.1.2
5-
- pymodsecurity=0.0.2
5+
- pymodsecurity=0.0.3
66
- pytest
77
- pytest-runner
88
- pytest-mock

setup.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,5 @@
99
author_email='[email protected]',
1010
license='MIT',
1111
packages=['django_pymodsecurity'],
12-
install_requires=[
13-
'Django',
14-
'pymodsecurity'
15-
],
12+
install_requires=['Django', 'pymodsecurity'],
1613
zip_safe=False)
File renamed without changes.

tests/test_main.py

+33
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,36 @@ def test_no_intervention(middleware, get_response, request_factory):
8484
obtained = middleware(request)
8585

8686
assert obtained == get_response.mock_response
87+
88+
89+
def test_log(get_response, request_factory, mocker):
90+
from django_pymodsecurity.middleware import PyModSecurityMiddleware
91+
92+
request = request_factory.post(
93+
'/api/users', {
94+
'hello': 'world',
95+
'attack': True
96+
},
97+
content_type='application/json')
98+
99+
get_response.mock_response = HttpResponse('Original response')
100+
101+
rule = 'SecRuleEngine On\n'
102+
rule += 'SecRequestBodyAccess On\n'
103+
rule += 'SecRule REQUEST_BODY "@contains attack" "id:43,phase:2,allow,msg:\'log test ok\'"'
104+
105+
mocker.spy(PyModSecurityMiddleware, 'modsecurity_log_callback')
106+
middleware = PyModSecurityMiddleware(get_response)
107+
assert middleware.rules.load(rule) > 0, \
108+
middleware.rules.getParserError() or 'Failed to load rule'
109+
110+
response = middleware(request)
111+
112+
assert response == get_response.mock_response
113+
assert response.status_code == 200
114+
115+
assert middleware.modsecurity_log_callback.call_count == 1
116+
obj, data, msg = middleware.modsecurity_log_callback.call_args_list[0][0]
117+
assert obj == middleware
118+
assert data is None
119+
assert 'log test ok' in msg

0 commit comments

Comments
 (0)