mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-11-15 17:12:14 +03:00
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:
@@ -20,6 +20,7 @@ mod_security2_la_SOURCES = acmp.c \
|
||||
msc_multipart.c \
|
||||
msc_parsers.c \
|
||||
msc_pcre.c \
|
||||
msc_python.c \
|
||||
msc_release.c \
|
||||
msc_reqbody.c \
|
||||
msc_tree.c \
|
||||
@@ -41,6 +42,7 @@ mod_security2_la_CFLAGS = @APR_CFLAGS@ \
|
||||
@LUA_CFLAGS@ \
|
||||
@MODSEC_EXTRA_CFLAGS@ \
|
||||
@PCRE_CFLAGS@ \
|
||||
@PYTHON_CFLAGS@ \
|
||||
@YAJL_CFLAGS@
|
||||
|
||||
|
||||
@@ -53,6 +55,7 @@ mod_security2_la_LIBADD = @APR_LDADD@ \
|
||||
@LIBXML2_LDADD@ \
|
||||
@LUA_LDADD@ \
|
||||
@PCRE_LDADD@ \
|
||||
@PYTHON_LDADD@ \
|
||||
@YAJL_LDADD@
|
||||
|
||||
if AIX
|
||||
@@ -63,7 +66,9 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
|
||||
endif
|
||||
|
||||
if HPUX
|
||||
@@ -74,6 +79,7 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -85,6 +91,7 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -96,6 +103,7 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -107,6 +115,7 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version -R @PCRE_LD_PATH
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -118,6 +127,7 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -129,6 +139,7 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -140,6 +151,7 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#include "msc_lua.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
#include "msc_python.h"
|
||||
#endif
|
||||
|
||||
/* -- Directory context creation and initialisation -- */
|
||||
|
||||
@@ -771,11 +774,19 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
|
||||
/* Create the rule now. */
|
||||
switch(type) {
|
||||
#if defined(WITH_LUA)
|
||||
case RULE_TYPE_LUA :
|
||||
case RULE_TYPE_LUA:
|
||||
rule = msre_rule_lua_create(dcfg->ruleset, cmd->directive->filename,
|
||||
cmd->directive->line_num, p1, p2, &my_error_msg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
case RULE_TYPE_PYTHON:
|
||||
rule = msre_rule_python_create(dcfg->ruleset, cmd->directive->filename,
|
||||
cmd->directive->line_num, p1, p2, &my_error_msg);
|
||||
break;
|
||||
#endif
|
||||
|
||||
default :
|
||||
rule = msre_rule_create(dcfg->ruleset, type, cmd->directive->filename,
|
||||
cmd->directive->line_num, p1, p2, p3, &my_error_msg);
|
||||
@@ -790,6 +801,9 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
|
||||
if (
|
||||
#if defined(WITH_LUA)
|
||||
type != RULE_TYPE_LUA &&
|
||||
#endif
|
||||
#ifdef WITH_PYTHON
|
||||
type != RULE_TYPE_PYTHON &&
|
||||
#endif
|
||||
(dcfg->tmp_chain_starter == NULL))
|
||||
if(rule->actionset == NULL)
|
||||
@@ -799,23 +813,32 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
|
||||
if(rule->actionset->id == NOT_SET_P
|
||||
#if defined(WITH_LUA)
|
||||
&& (type != RULE_TYPE_LUA)
|
||||
#endif
|
||||
#ifdef WITH_PYTHON
|
||||
&& (type != RULE_TYPE_PYTHON)
|
||||
#endif
|
||||
)
|
||||
return "ModSecurity: No action id present within the rule";
|
||||
#if defined(WITH_LUA)
|
||||
if(type != RULE_TYPE_LUA)
|
||||
|
||||
#ifdef WITH_LUA
|
||||
if (type != RULE_TYPE_LUA)
|
||||
#endif
|
||||
{
|
||||
rid = apr_hash_get(dcfg->rule_id_htab, rule->actionset->id, APR_HASH_KEY_STRING);
|
||||
if(rid != NULL) {
|
||||
return "ModSecurity: Found another rule with the same id";
|
||||
} else {
|
||||
apr_hash_set(dcfg->rule_id_htab, apr_pstrdup(dcfg->mp, rule->actionset->id), APR_HASH_KEY_STRING, apr_pstrdup(dcfg->mp, "1"));
|
||||
}
|
||||
#ifdef WITH_PYTHON
|
||||
if (type != RULE_TYPE_PYTHON)
|
||||
#endif
|
||||
{
|
||||
rid = apr_hash_get(dcfg->rule_id_htab, rule->actionset->id, APR_HASH_KEY_STRING);
|
||||
if(rid != NULL) {
|
||||
return "ModSecurity: Found another rule with the same id";
|
||||
} else {
|
||||
apr_hash_set(dcfg->rule_id_htab, apr_pstrdup(dcfg->mp, rule->actionset->id), APR_HASH_KEY_STRING, apr_pstrdup(dcfg->mp, "1"));
|
||||
}
|
||||
|
||||
//tmp_rule = msre_ruleset_fetch_rule(dcfg->ruleset, rule->actionset->id, offset);
|
||||
//if(tmp_rule != NULL)
|
||||
// return "ModSecurity: Found another rule with the same id";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2246,13 +2269,30 @@ static const char *cmd_rule_inheritance(cmd_parms *cmd, void *_dcfg, int flag)
|
||||
static const char *cmd_rule_script(cmd_parms *cmd, void *_dcfg,
|
||||
const char *p1, const char *p2)
|
||||
{
|
||||
#if defined(WITH_LUA)
|
||||
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
|
||||
return add_rule(cmd, (directory_config *)_dcfg, RULE_TYPE_LUA, filename, p2, NULL);
|
||||
#else
|
||||
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool, "Ignoring SecRuleScript \"%s\" directive (%s:%d): No Lua scripting support.", p1, cmd->directive->filename, cmd->directive->line_num);
|
||||
|
||||
if (strlen(filename) > 3) {
|
||||
const char *p = filename + strlen(filename) - 3;
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
if ((p[0] == '.')&&(p[1] == 'p')&&(p[2] == 'y'))
|
||||
{
|
||||
return add_rule(cmd, (directory_config *)_dcfg, RULE_TYPE_PYTHON, filename, p2, NULL);
|
||||
}
|
||||
#endif
|
||||
#ifdef WITH_LUA
|
||||
if ((p[0] == 'l')&&(p[1] == 'u')&&(p[2] == 'a'))
|
||||
{
|
||||
return add_rule(cmd, (directory_config *)_dcfg, RULE_TYPE_LUA, filename, p2, NULL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(WITH_PYTHON) || !defined(WITH_LUA)
|
||||
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool, "Ignoring SecRuleScript \"%s\" directive (%s:%d): No Lua scripting or Python support.", p1, cmd->directive->filename, cmd->directive->line_num);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg,
|
||||
|
||||
@@ -37,6 +37,10 @@
|
||||
#include "msc_lua.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
#include "msc_python.h"
|
||||
#endif
|
||||
|
||||
#include "msc_status_engine.h"
|
||||
|
||||
/* ModSecurity structure */
|
||||
|
||||
@@ -60,6 +60,10 @@ typedef struct msc_parm msc_parm;
|
||||
#include "msc_lua.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
#include "msc_python.h"
|
||||
#endif
|
||||
|
||||
#define PHASE_REQUEST_HEADERS 1
|
||||
#define PHASE_REQUEST_BODY 2
|
||||
#define PHASE_RESPONSE_HEADERS 3
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
MOD_SECURITY2 = mod_security2 apache2_config apache2_io apache2_util \
|
||||
re re_operators re_actions re_tfns re_variables msc_json \
|
||||
msc_logging msc_xml msc_multipart modsecurity msc_parsers msc_util msc_pcre \
|
||||
persist_dbm msc_reqbody pdf_protect msc_geo msc_gsb msc_crypt msc_tree msc_unicode acmp msc_lua
|
||||
persist_dbm msc_reqbody pdf_protect msc_geo msc_gsb msc_crypt msc_tree msc_unicode acmp msc_lua \
|
||||
msc_python
|
||||
|
||||
H = re.h modsecurity.h msc_logging.h msc_multipart.h msc_parsers.h msc_json.h \
|
||||
msc_pcre.h msc_util.h msc_xml.h persist_dbm.h apache2.h pdf_protect.h \
|
||||
msc_geo.h msc_gsb.h msc_crypt.h msc_tree.h msc_unicode.h acmp.h utf8tables.h msc_lua.h
|
||||
msc_geo.h msc_gsb.h msc_crypt.h msc_tree.h msc_unicode.h acmp.h utf8tables.h msc_lua.h \
|
||||
msc_python.h
|
||||
|
||||
${MOD_SECURITY2:=.slo}: ${H}
|
||||
${MOD_SECURITY2:=.lo}: ${H}
|
||||
|
||||
442
apache2/msc_python.c
Normal file
442
apache2/msc_python.c
Normal file
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*/
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
|
||||
#include "msc_python.h"
|
||||
|
||||
#include "apr_lib.h"
|
||||
#include "apr_strmatch.h"
|
||||
#include "apr_strings.h"
|
||||
#include "apache2.h"
|
||||
#include <Python.h>
|
||||
|
||||
#define PY_STR_DBG(arg, msr, z) { if (arg == NULL) { msr_log(msr, 8, "Python -%s-:", z); } else { PyObject *e = PyObject_Repr(arg); PyObject *a = PyUnicode_AsEncodedString(e, "utf-8", NULL); char *s = PyBytes_AsString(a); msr_log(msr, 8, "Python -%s-: %s", z, s); } }
|
||||
|
||||
/* ModSecurityI */
|
||||
|
||||
static PyObject *pyModSecurityI_log(PyObject *self, PyObject *args, PyObject *kwds) {
|
||||
char *str = NULL;
|
||||
int level = 0;
|
||||
PyObject *capsuleModSecurity = NULL;
|
||||
modsec_rec *msr = NULL;
|
||||
|
||||
if (PyArg_ParseTuple(args, "is", &level, &str) == 0)
|
||||
{
|
||||
/* PyArg already set this.
|
||||
* PyErr_SetString(PyExc_TypeError, "log() takes exactly 2 arguments.");
|
||||
*/
|
||||
goto end;
|
||||
}
|
||||
|
||||
capsuleModSecurity = PyObject_GetAttrString(self, "capsuleModSecurity");
|
||||
if (capsuleModSecurity == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error paramenter.
|
||||
PyErr_SetString(PyExc_TypeError, "log() needs ModSecurity core to be attached.");
|
||||
goto end;
|
||||
}
|
||||
|
||||
msr = PyCapsule_GetPointer(capsuleModSecurity, "modsecurity");
|
||||
if (msr == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error paramenter.
|
||||
PyErr_SetString(PyExc_TypeError, "log() needs ModSecurity core to be attached.");
|
||||
goto end_no_msr;
|
||||
}
|
||||
|
||||
msr_log(msr, level, str);
|
||||
|
||||
end_no_msr:
|
||||
Py_DECREF(capsuleModSecurity);
|
||||
end:
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *pyModSecurityI_setCapsuleModSecurity(PyObject *self, PyObject *args, PyObject *kwds) {
|
||||
PyObject *capsule = NULL;
|
||||
|
||||
if (PyArg_ParseTuple(args, "O", &capsule) == 0)
|
||||
{
|
||||
/* PyArg already set this.
|
||||
* PyErr_SetString(PyExc_TypeError, "setCapsuleModSecurity() takes exactly 1 argument.");
|
||||
*/
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (capsule == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "setCapsuleModSecurity() Capsule cannot be NULL.");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (PyModule_AddObject(self, "capsuleModSecurity", capsule) == -1)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "setCapsuleModSecurity() Failed to save capsule.");
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *pyModSecurityI_setCapsuleRule(PyObject *self, PyObject *args, PyObject *kwds) {
|
||||
PyObject *capsule = NULL;
|
||||
|
||||
if (PyArg_ParseTuple(args, "O", &capsule) == 0)
|
||||
{
|
||||
/* PyArg already set this.
|
||||
* PyErr_SetString(PyExc_TypeError, "setCapsuleRule() takes exactly 1 argument.");
|
||||
*/
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (capsule == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "setCapsuleRule() Capsule cannot be NULL.");
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (PyModule_AddObject(self, "capsuleRule", capsule) == -1)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "setCapsuleRule() Failed to save capsule.");
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *pyModSecurityI_getVariable(PyObject *self, PyObject *args, PyObject *kwds) {
|
||||
char *my_error_msg = NULL;
|
||||
const char *var_name = NULL;
|
||||
const apr_array_header_t *arr = NULL;
|
||||
PyObject *ret = Py_None;
|
||||
PyObject *capsuleRule = NULL;
|
||||
PyObject *capsuleModSecurity = NULL;
|
||||
msre_rule *rule = NULL;
|
||||
msre_var *var = NULL;
|
||||
modsec_rec *msr = NULL;
|
||||
apr_table_t *vartab = NULL;
|
||||
|
||||
if (PyArg_ParseTuple(args, "s", &var_name) == 0)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
capsuleRule = PyObject_GetAttrString(self, "capsuleRule");
|
||||
if (capsuleRule == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "getVariable() needs ModSecurity core to be attached.");
|
||||
goto end_no_rule;
|
||||
}
|
||||
|
||||
capsuleModSecurity = PyObject_GetAttrString(self, "capsuleModSecurity");
|
||||
if (capsuleModSecurity == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "getVariable() needs ModSecurity core to be attached.");
|
||||
goto end_no_msr;
|
||||
}
|
||||
|
||||
rule = PyCapsule_GetPointer(capsuleRule, "rule");
|
||||
msr = PyCapsule_GetPointer(capsuleModSecurity, "modsecurity");
|
||||
if (rule == NULL || msr == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "getVariable() needs ModSecurity core to be attached.");
|
||||
goto end_no_rule_or_msr;
|
||||
}
|
||||
|
||||
var = msre_create_var_ex(msr->msc_rule_mptmp, msr->modsecurity->msre,
|
||||
var_name, '\0', msr, &my_error_msg);
|
||||
|
||||
if (var == NULL)
|
||||
{
|
||||
goto end_no_var;
|
||||
}
|
||||
|
||||
vartab = apr_table_make(msr->msc_rule_mptmp, 16);
|
||||
if (vartab == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "getVariable() Internal error, failed to create var table.");
|
||||
goto end_no_vartab;
|
||||
}
|
||||
|
||||
var->metadata->generate(msr, var, rule, vartab, msr->msc_rule_mptmp);
|
||||
arr = apr_table_elts(vartab);
|
||||
|
||||
if (arr->nelts == 1)
|
||||
{
|
||||
msre_var *vx = generate_single_var(msr, var, NULL, rule, msr->msc_rule_mptmp);
|
||||
if (vx != NULL)
|
||||
{
|
||||
ret = Py_BuildValue("s", vx->value);
|
||||
}
|
||||
}
|
||||
else if (arr->nelts > 1)
|
||||
{
|
||||
// FIXME: We should have an object to encapsulate this dictionary, in order to auto-save the changes.
|
||||
int i = 0;
|
||||
const apr_table_entry_t *te = NULL;
|
||||
PyObject *pDict = PyDict_New();
|
||||
|
||||
te = (apr_table_entry_t *)arr->elts;
|
||||
|
||||
for (i = 0; i < arr->nelts; i++)
|
||||
{
|
||||
msre_var *str = (msre_var *) te[i].val;
|
||||
PyDict_SetItemString(pDict, str->name + strlen(var->name) + 1, Py_BuildValue("s", str->value));
|
||||
}
|
||||
|
||||
ret = pDict;
|
||||
}
|
||||
|
||||
end_no_vartab:
|
||||
end_no_var:
|
||||
end_no_rule_or_msr:
|
||||
Py_DECREF(capsuleModSecurity);
|
||||
end_no_msr:
|
||||
Py_DECREF(capsuleRule);
|
||||
end_no_rule:
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static PyObject *pyModSecurityI_applyTransformation(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
|
||||
// TODO: Implement.
|
||||
|
||||
PyErr_SetString(PyExc_TypeError, "applyTransformation() is not ready yet.");
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *pyModSecurityI_setVariable(PyObject *self, PyObject *args, PyObject *kwds)
|
||||
{
|
||||
char *name = NULL;
|
||||
char *value = NULL;
|
||||
PyObject *ret = Py_None;
|
||||
PyObject *capsuleRule = NULL;
|
||||
PyObject *capsuleModSecurity = NULL;
|
||||
msre_rule *rule = NULL;
|
||||
modsec_rec *msr = NULL;
|
||||
|
||||
if (PyArg_ParseTuple(args, "ss", &name, &value) == 0)
|
||||
{
|
||||
goto end;
|
||||
}
|
||||
|
||||
capsuleRule = PyObject_GetAttrString(self, "capsuleRule");
|
||||
if (capsuleRule == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "setVariable() needs ModSecurity core to be attached.");
|
||||
goto end_no_rule;
|
||||
}
|
||||
|
||||
capsuleModSecurity = PyObject_GetAttrString(self, "capsuleModSecurity");
|
||||
if (capsuleModSecurity == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "setVariable() needs ModSecurity core to be attached.");
|
||||
goto end_no_msr;
|
||||
}
|
||||
|
||||
rule = PyCapsule_GetPointer(capsuleRule, "rule");
|
||||
msr = PyCapsule_GetPointer(capsuleModSecurity, "modsecurity");
|
||||
if (rule == NULL || msr == NULL)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "setVariable() needs ModSecurity core to be attached.");
|
||||
goto end_no_rule_or_msr;
|
||||
}
|
||||
|
||||
|
||||
if (msre_action_setvar_execute(msr, msr->msc_rule_mptmp, rule, name, value) != 1)
|
||||
{
|
||||
// FIXME: Use the correct error object.
|
||||
PyErr_SetString(PyExc_TypeError, "setVariable() Internal error. Failed to save variable.");
|
||||
goto end_failed_to_set;
|
||||
}
|
||||
|
||||
end_failed_to_set:
|
||||
end_no_rule_or_msr:
|
||||
Py_DECREF(capsuleModSecurity);
|
||||
end_no_msr:
|
||||
Py_DECREF(capsuleRule);
|
||||
end_no_rule:
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef pyModSecurityI_functions[] = {
|
||||
{ "log", (PyCFunction)pyModSecurityI_log, METH_VARARGS, NULL },
|
||||
{ "setCapsuleModSecurity", (PyCFunction)pyModSecurityI_setCapsuleModSecurity, METH_VARARGS, NULL },
|
||||
{ "setCapsuleRule", (PyCFunction)pyModSecurityI_setCapsuleRule, METH_VARARGS, NULL },
|
||||
{ "getVariable", (PyCFunction)pyModSecurityI_getVariable, METH_VARARGS, NULL },
|
||||
{ "setVariable", (PyCFunction)pyModSecurityI_setVariable, METH_VARARGS, NULL },
|
||||
{ "applyTransformation", (PyCFunction)pyModSecurityI_applyTransformation, METH_VARARGS, NULL },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
static struct PyModuleDef pyModSecurityI_def = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"ModSecurityI",
|
||||
NULL,
|
||||
0,
|
||||
pyModSecurityI_functions,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
// FIXME: Split files.
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
char *python_load(msc_python_script **script, const char *filename, apr_pool_t *pool)
|
||||
{
|
||||
PyObject *pName, *pModule;
|
||||
const char *path = NULL;
|
||||
const char *file = NULL;
|
||||
const char *module = NULL;
|
||||
|
||||
/*
|
||||
* Script path?
|
||||
* FIXME: Avoid to use apr_ functions
|
||||
*/
|
||||
file = apr_filepath_name_get(filename);
|
||||
path = apr_pstrndup(pool, filename, strlen(filename) - strlen(file));
|
||||
|
||||
Py_Initialize();
|
||||
|
||||
PyObject* sysPath = PySys_GetObject((char*)"path");
|
||||
PyList_Append(sysPath, PyUnicode_FromFormat("."));
|
||||
PyList_Append(sysPath, PyUnicode_FromFormat(path));
|
||||
|
||||
module = apr_pstrndup(pool, file, strlen(file) - strlen(".py"));
|
||||
Py_SetProgramName((wchar_t *)module); /* FIXME */
|
||||
|
||||
pName = PyUnicode_FromString(module);
|
||||
pModule = PyImport_Import(pName);
|
||||
|
||||
if (pModule == NULL) {
|
||||
const char *s = NULL;
|
||||
PyObject *err = NULL;
|
||||
PyObject *exc_type = NULL, *exc_value = NULL, *exc_tb = NULL;
|
||||
|
||||
PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
|
||||
err = PyObject_Repr(exc_value); //Now a unicode object
|
||||
PyObject* pyStr = PyUnicode_AsEncodedString(err, "utf-8", NULL);
|
||||
s = PyBytes_AS_STRING(pyStr);
|
||||
|
||||
return apr_psprintf(pool, "ModSecurity: Failed to load script: %s - %s",
|
||||
filename, s);
|
||||
}
|
||||
|
||||
(*script) = apr_pcalloc(pool, sizeof(msc_python_script));
|
||||
(*script)->name = strdup(filename);
|
||||
(*script)->pName = pName;
|
||||
(*script)->pModule = pModule;
|
||||
(*script)->extInstance = NULL;
|
||||
|
||||
Py_DECREF(pName);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// FIXME: Error handling
|
||||
int python_execute(msc_python_script *script, char *param, modsec_rec *msr, msre_rule *rule, char **error_msg) {
|
||||
apr_time_t time_before;
|
||||
int ret = RULE_NO_MATCH;
|
||||
PyObject* methodRes = NULL;
|
||||
PyObject *extObject = NULL;
|
||||
|
||||
if (error_msg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
*error_msg = NULL;
|
||||
|
||||
// if (script->extInstance == NULL) // FIXME: without cache this will draing the performance.
|
||||
// {
|
||||
extObject = PyObject_GetAttrString(script->pModule, "ModSecurityExtension");
|
||||
script->extInstance = PyObject_CallObject(extObject, NULL);
|
||||
|
||||
PyObject *logMod = PyModule_Create(&pyModSecurityI_def);
|
||||
PyObject *capsule_msr = PyCapsule_New(msr, "modsecurity", NULL);
|
||||
PyObject *capsule_rule = PyCapsule_New(rule, "rule", NULL);
|
||||
PyObject* setCapsule1 = PyObject_CallMethod(logMod, "setCapsuleModSecurity", "(O)", capsule_msr);
|
||||
PyObject* setCapsule2 = PyObject_CallMethod(logMod, "setCapsuleRule", "(O)", capsule_rule);
|
||||
|
||||
|
||||
PyObject* setLog = PyObject_CallMethod(script->extInstance, "setModSecurityCore", "(O)", logMod);
|
||||
if (setLog == NULL)
|
||||
{
|
||||
const char *s = NULL;
|
||||
PyObject *exc_type = NULL, *exc_value = NULL, *exc_tb = NULL, *err = NULL;
|
||||
|
||||
PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
|
||||
err = PyObject_Repr(exc_value); //Now a unicode object
|
||||
|
||||
PyObject* pyStr = PyUnicode_AsEncodedString(err, "utf-8", NULL);
|
||||
s = PyBytes_AS_STRING(pyStr);
|
||||
msr_log(msr, 8, "Python problem: %s", s);
|
||||
}
|
||||
// }
|
||||
methodRes = PyObject_CallMethod(script->extInstance, "process", NULL);
|
||||
|
||||
if (methodRes == NULL)
|
||||
{
|
||||
const char *s = NULL;
|
||||
PyObject *exc_type = NULL, *exc_value = NULL, *exc_tb = NULL, *err = NULL;
|
||||
|
||||
PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
|
||||
err = PyObject_Repr(exc_value); //Now a unicode object
|
||||
|
||||
PyObject* pyStr = PyUnicode_AsEncodedString(err, "utf-8", NULL);
|
||||
s = PyBytes_AS_STRING(pyStr);
|
||||
|
||||
*error_msg = apr_psprintf(msr->mp, "Python script failed: '%s'.", s);
|
||||
goto end;
|
||||
}
|
||||
if (methodRes == Py_True)
|
||||
{
|
||||
*error_msg = apr_psprintf(msr->mp, "Python script matched");
|
||||
ret = RULE_MATCH;
|
||||
}
|
||||
|
||||
Py_DECREF(methodRes);
|
||||
end:
|
||||
// Py_DECREF(extInstance);
|
||||
// Py_DECREF(extObject);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WITH_PYTHON */
|
||||
38
apache2/msc_python.h
Normal file
38
apache2/msc_python.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
|
||||
* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*/
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
|
||||
#ifndef _MSC_PYTHON_H_
|
||||
#define _MSC_PYTHON_H_
|
||||
|
||||
typedef struct msc_python_script msc_python_script;
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "apr_general.h"
|
||||
#include "apr_tables.h"
|
||||
#include "modsecurity.h"
|
||||
|
||||
struct msc_python_script {
|
||||
const char *name;
|
||||
PyObject *pName;
|
||||
PyObject *pModule;
|
||||
PyObject *extInstance;
|
||||
};
|
||||
|
||||
char DSOLOCAL *python_load(msc_python_script **script, const char *filename, apr_pool_t *pool);
|
||||
|
||||
#endif /* _MSC_PYTHON_H_ */
|
||||
#endif /* WITH_PYTHON */
|
||||
107
apache2/re.c
107
apache2/re.c
@@ -20,6 +20,10 @@
|
||||
#include "msc_lua.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
#include "msc_python.h"
|
||||
#endif
|
||||
|
||||
static const char *const severities[] = {
|
||||
"EMERGENCY",
|
||||
"ALERT",
|
||||
@@ -2327,6 +2331,19 @@ char * msre_rule_generate_unparsed(apr_pool_t *pool, const msre_rule *rule, con
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef WITH_PYTHON
|
||||
case RULE_TYPE_PYTHON:
|
||||
/* SecRuleScript */
|
||||
if (r_actions == NULL) {
|
||||
unparsed = apr_psprintf(pool, "SecRuleScript \"%s\"", r_args);
|
||||
}
|
||||
else {
|
||||
unparsed = apr_psprintf(pool, "SecRuleScript \"%s\" \"%s\"",
|
||||
r_args, log_escape(pool, r_actions));
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return unparsed;
|
||||
@@ -2466,6 +2483,54 @@ msre_rule *msre_rule_lua_create(msre_ruleset *ruleset,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
/**
|
||||
* Allocate and initialize the main structure needed for Python
|
||||
* script execution.
|
||||
*
|
||||
*/
|
||||
msre_rule *msre_rule_python_create(msre_ruleset *ruleset,
|
||||
const char *fn, int line, const char *script_filename,
|
||||
const char *actions, char **error_msg)
|
||||
{
|
||||
msre_rule *rule;
|
||||
char *my_error_msg;
|
||||
char *filename = (char *)rule->op_param;
|
||||
|
||||
if (error_msg == NULL) return NULL;
|
||||
*error_msg = NULL;
|
||||
|
||||
rule = (msre_rule *)apr_pcalloc(ruleset->mp, sizeof(msre_rule));
|
||||
if (rule == NULL) return NULL;
|
||||
|
||||
rule->type = RULE_TYPE_PYTHON;
|
||||
rule->ruleset = ruleset;
|
||||
rule->filename = apr_pstrdup(ruleset->mp, fn);
|
||||
rule->line_num = line;
|
||||
|
||||
/* Load the script */
|
||||
*error_msg = python_load(&rule->python_script, script_filename, ruleset->mp);
|
||||
if (*error_msg != NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Parse actions */
|
||||
if (actions != NULL) {
|
||||
/* Create per-rule actionset */
|
||||
rule->actionset = msre_actionset_create(ruleset->engine, ruleset->mp, actions, &my_error_msg);
|
||||
if (rule->actionset == NULL) {
|
||||
*error_msg = apr_psprintf(ruleset->mp, "Error parsing actions: %s", my_error_msg);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the unparsed rule */
|
||||
rule->unparsed = msre_rule_generate_unparsed(ruleset->mp, rule, NULL, script_filename, NULL);
|
||||
|
||||
return rule;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Perform non-disruptive actions associated with the provided actionset.
|
||||
*/
|
||||
@@ -3331,6 +3396,41 @@ static apr_status_t msre_rule_process_lua(msre_rule *rule, modsec_rec *msr) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
static apr_status_t msre_rule_process_python(msre_rule *rule, modsec_rec *msr) {
|
||||
msre_actionset *acting_actionset = NULL;
|
||||
char *my_error_msg = NULL;
|
||||
int rc = 0;
|
||||
/* Choose the correct metadata/disruptive action actionset. */
|
||||
acting_actionset = rule->actionset;
|
||||
if (rule->chain_starter != NULL) {
|
||||
acting_actionset = rule->chain_starter->actionset;
|
||||
}
|
||||
|
||||
rc = python_execute(rule->python_script, NULL, msr, rule, &my_error_msg);
|
||||
if (rc < 0) {
|
||||
msr_log(msr, 1, "%s", my_error_msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* A non-NULL error message means the rule matched. */
|
||||
if (my_error_msg != NULL) {
|
||||
/* Perform non-disruptive actions. */
|
||||
msre_perform_nondisruptive_actions(msr, rule, rule->actionset, msr->msc_rule_mptmp);
|
||||
|
||||
/* Perform disruptive actions, but only if
|
||||
* this rule is not part of a chain.
|
||||
*/
|
||||
if (rule->actionset->is_chained == 0) {
|
||||
msre_perform_disruptive_actions(msr, rule, acting_actionset, msr->msc_rule_mptmp, my_error_msg);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@@ -3350,6 +3450,13 @@ static apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
if (rule->type == RULE_TYPE_PYTHON) {
|
||||
return msre_rule_process_python(rule, msr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return msre_rule_process_normal(rule, msr);
|
||||
}
|
||||
|
||||
|
||||
19
apache2/re.h
19
apache2/re.h
@@ -46,6 +46,10 @@ typedef struct msre_cache_rec msre_cache_rec;
|
||||
#include "msc_lua.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
#include "msc_python.h"
|
||||
#endif
|
||||
|
||||
/* Actions, variables, functions and operator functions */
|
||||
char DSOLOCAL *update_rule_target_ex(modsec_rec *msr, msre_ruleset *ruleset, msre_rule *rule, const char *p2,
|
||||
const char *p3);
|
||||
@@ -136,7 +140,10 @@ int DSOLOCAL msre_ruleset_phase_rule_remove_with_exception(msre_ruleset *ruleset
|
||||
#define RULE_TYPE_ACTION 1 /* SecAction */
|
||||
#define RULE_TYPE_MARKER 2 /* SecMarker */
|
||||
#if defined(WITH_LUA)
|
||||
#define RULE_TYPE_LUA 3 /* SecRuleScript */
|
||||
#define RULE_TYPE_LUA 3 /* SecRuleScript - lua */
|
||||
#endif
|
||||
#ifdef WITH_PYTHON
|
||||
#define RULE_TYPE_PYTHON 4 /* SecRuleScript - python */
|
||||
#endif
|
||||
|
||||
struct msre_rule {
|
||||
@@ -167,6 +174,10 @@ struct msre_rule {
|
||||
msc_script *script;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
msc_python_script *python_script;
|
||||
#endif
|
||||
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 0
|
||||
ap_regex_t *sub_regex;
|
||||
#else
|
||||
@@ -192,6 +203,12 @@ msre_rule DSOLOCAL *msre_rule_lua_create(msre_ruleset *ruleset,
|
||||
const char *actions, char **error_msg);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
msre_rule DSOLOCAL *msre_rule_python_create(msre_ruleset *ruleset,
|
||||
const char *fn, int line, const char *script_filename,
|
||||
const char *actions, char **error_msg);
|
||||
#endif
|
||||
|
||||
#define VAR_SIMPLE 0 /* REQUEST_URI */
|
||||
#define VAR_LIST 1
|
||||
|
||||
|
||||
@@ -3733,6 +3733,23 @@ static int msre_op_inspectFile_init(msre_rule *rule, char **error_msg) {
|
||||
|
||||
filename = resolve_relative_path(rule->ruleset->mp, rule->filename, filename);
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
/* ENH Write & use string_ends(s, e). */
|
||||
if (strlen(rule->op_param) > 3) {
|
||||
char *p = filename + strlen(filename) - 3;
|
||||
if ((p[0] == '.')&&(p[1] == 'p')&&(p[2] == 'y'))
|
||||
{
|
||||
msc_python_script *script = NULL;
|
||||
|
||||
/* Compile script. */
|
||||
*error_msg = python_load(&script, filename, rule->ruleset->mp);
|
||||
if (*error_msg != NULL) return -1;
|
||||
|
||||
rule->op_param_data = script;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WITH_LUA)
|
||||
/* ENH Write & use string_ends(s, e). */
|
||||
if (strlen(rule->op_param) > 4) {
|
||||
@@ -3748,7 +3765,7 @@ static int msre_op_inspectFile_init(msre_rule *rule, char **error_msg) {
|
||||
rule->op_param_data = script;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (rule->op_param_data == NULL) {
|
||||
/* ENH Verify the script exists and that we have
|
||||
|
||||
56
scripts/python/modsecurity.py
Executable file
56
scripts/python/modsecurity.py
Executable 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
15
scripts/python/setup.py
Normal 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
50
scripts/python/skell.py
Executable 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")
|
||||
|
||||
@@ -21,6 +21,7 @@ standalone_la_SOURCES = ../apache2/acmp.c \
|
||||
../apache2/msc_multipart.c \
|
||||
../apache2/msc_parsers.c \
|
||||
../apache2/msc_pcre.c \
|
||||
../apache2/msc_python.c \
|
||||
../apache2/msc_release.c \
|
||||
../apache2/msc_reqbody.c \
|
||||
../apache2/msc_tree.c \
|
||||
@@ -51,6 +52,7 @@ standalone_la_CFLAGS = -DVERSION_NGINX \
|
||||
@LUA_CFLAGS@ \
|
||||
@MODSEC_EXTRA_CFLAGS@ \
|
||||
@PCRE_CFLAGS@ \
|
||||
@PYTHON_CFLAGS@ \
|
||||
@YAJL_CFLAGS@
|
||||
|
||||
standalone_la_CPPFLAGS = @APR_CPPFLAGS@ \
|
||||
@@ -62,6 +64,7 @@ standalone_la_LIBADD = @APR_LDADD@ \
|
||||
@LIBXML2_LDADD@ \
|
||||
@LUA_LDADD@ \
|
||||
@PCRE_LDADD@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDADD@
|
||||
|
||||
if AIX
|
||||
@@ -72,6 +75,7 @@ standalone_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -83,6 +87,7 @@ standalone_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -94,6 +99,7 @@ standalone_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -105,6 +111,7 @@ standalone_la_LDFLAGS = -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -116,6 +123,7 @@ standalone_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -127,6 +135,7 @@ standalone_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -138,6 +147,7 @@ standalone_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -149,5 +159,6 @@ standalone_la_LDFLAGS = -no-undefined -module -avoid-version \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
endif
|
||||
|
||||
@@ -14,6 +14,7 @@ msc_test_SOURCES = msc_test.c \
|
||||
$(top_srcdir)/apache2/msc_multipart.c \
|
||||
$(top_srcdir)/apache2/msc_parsers.c \
|
||||
$(top_srcdir)/apache2/msc_pcre.c \
|
||||
$(top_srcdir)/apache2/msc_python.c \
|
||||
$(top_srcdir)/apache2/msc_release.c \
|
||||
$(top_srcdir)/apache2/msc_reqbody.c \
|
||||
$(top_srcdir)/apache2/msc_tree.c \
|
||||
@@ -36,6 +37,7 @@ msc_test_CFLAGS = @APR_CFLAGS@ \
|
||||
@LUA_CFLAGS@ \
|
||||
@MODSEC_EXTRA_CFLAGS@ \
|
||||
@PCRE_CFLAGS@ \
|
||||
@PYTHON_CFLAGS@ \
|
||||
@YAJL_CFLAGS@
|
||||
|
||||
msc_test_CPPFLAGS = -I$(top_srcdir)/apache2 \
|
||||
@@ -48,6 +50,7 @@ msc_test_LDADD = @APR_LDADD@ \
|
||||
@LIBXML2_LDADD@ \
|
||||
@LUA_LDADD@ \
|
||||
@PCRE_LDADD@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDADD@
|
||||
|
||||
msc_test_LDFLAGS = @APR_LDFLAGS@ \
|
||||
@@ -56,6 +59,7 @@ msc_test_LDFLAGS = @APR_LDFLAGS@ \
|
||||
@LIBXML2_LDFLAGS@ \
|
||||
@LUA_LDFLAGS@ \
|
||||
@PCRE_LDFLAGS@ \
|
||||
@PYTHON_LDFLAGS@ \
|
||||
@YAJL_LDFLAGS@
|
||||
|
||||
check_SCRIPTS = run-unit-tests.pl
|
||||
|
||||
21
tests/regression/nginx/conf/script.py
Executable file
21
tests/regression/nginx/conf/script.py
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from modsecurity import ModSecurity
|
||||
|
||||
class ModSecurityExtension(ModSecurity):
|
||||
def process(self):
|
||||
self.log(8, "Python test message.")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
myExtension = ModSecurityExtension()
|
||||
|
||||
# Process the content.
|
||||
ret = myExtension.process()
|
||||
|
||||
if ret == True:
|
||||
print("Matched!")
|
||||
else:
|
||||
print("_not_ matched")
|
||||
|
||||
24
tests/regression/rule/01-python-script.t
Normal file
24
tests/regression/rule/01-python-script.t
Normal file
@@ -0,0 +1,24 @@
|
||||
### Test for SecRuleScript
|
||||
|
||||
# Python
|
||||
{
|
||||
type => "rule",
|
||||
comment => "SecRuleScript (Python match)",
|
||||
conf => qq(
|
||||
SecRuleEngine On
|
||||
SecDebugLog $ENV{DEBUG_LOG}
|
||||
SecDebugLogLevel 9
|
||||
SecRuleScript "script.py" "phase:2,deny"
|
||||
),
|
||||
match_log => {
|
||||
-error => [ qr/Python script matched\./, 1 ],
|
||||
debug => [ qr/Python test message\./, 1 ],
|
||||
},
|
||||
match_response => {
|
||||
status => qr/^200$/,
|
||||
},
|
||||
request => new HTTP::Request(
|
||||
GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?foo=bar&foo2=bar2",
|
||||
),
|
||||
}
|
||||
|
||||
21
tests/regression/server_root/conf/script.py
Executable file
21
tests/regression/server_root/conf/script.py
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from modsecurity import ModSecurity
|
||||
|
||||
class ModSecurityExtension(ModSecurity):
|
||||
def process(self):
|
||||
self.log(8, "Python test message.")
|
||||
return False
|
||||
|
||||
if __name__ == "__main__":
|
||||
myExtension = ModSecurityExtension()
|
||||
|
||||
# Process the content.
|
||||
ret = myExtension.process()
|
||||
|
||||
if ret == True:
|
||||
print("Matched!")
|
||||
else:
|
||||
print("_not_ matched")
|
||||
|
||||
Reference in New Issue
Block a user