mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-13 21:36:00 +03:00
Added m.getvars() and finalised Lua support.
This commit is contained in:
parent
8924f605d4
commit
2068357af8
7
CHANGES
7
CHANGES
@ -1,9 +1,14 @@
|
||||
|
||||
20 Dec 2007 - 2.5.0-rc1
|
||||
21 Dec 2007 - 2.5.0-rc1
|
||||
-----------------------
|
||||
|
||||
Changes since 2.5.0-dev2:
|
||||
|
||||
* Added support for Lua scripting in the following ways: SecRuleScript
|
||||
can be used to specify a script to execute as a rule, the exec
|
||||
action processes Lua scripts internally, and does the @inspectFile
|
||||
operator. Refer to the documentation for more details.
|
||||
|
||||
* Updated included Core Ruleset to version 1.5.1.
|
||||
|
||||
* Changed how allow works. Used on its own it now allows phases 1-4. Used
|
||||
|
@ -39,8 +39,6 @@ APACHECTL = apachectl
|
||||
|
||||
INCLUDES = -I /usr/include/libxml2 -I /usr/include/lua5.1
|
||||
# INCLUDES = -I /usr/include/libxml2 -I /path/to/httpd-x.y/srclib/pcre
|
||||
DEFS = -DWITH_LUA
|
||||
# DEFS = -DWITH_ICONV
|
||||
# DEFS = -DPERFORMANCE_MEASUREMENT
|
||||
# DEFS = -DNO_MODSEC_API
|
||||
# DEFS = -DDEBUG_CONF
|
||||
|
@ -1283,14 +1283,12 @@ static const char *cmd_rule_inheritance(cmd_parms *cmd, void *_dcfg, int flag) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef WITH_LUA
|
||||
static const char *cmd_rule_script(cmd_parms *cmd, void *_dcfg, const char *p1,
|
||||
const char *p2)
|
||||
{
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg, const char *p1) {
|
||||
directory_config *dcfg = (directory_config *)_dcfg;
|
||||
@ -1887,7 +1885,6 @@ const command_rec module_directives[] = {
|
||||
"On or Off"
|
||||
),
|
||||
|
||||
#ifdef WITH_LUA
|
||||
AP_INIT_TAKE12 (
|
||||
"SecRuleScript",
|
||||
cmd_rule_script,
|
||||
@ -1895,7 +1892,6 @@ const command_rec module_directives[] = {
|
||||
CMD_SCOPE_ANY,
|
||||
"" // TODO
|
||||
),
|
||||
#endif
|
||||
|
||||
AP_INIT_ITERATE (
|
||||
"SecRuleRemoveById",
|
||||
|
@ -1,9 +1,6 @@
|
||||
|
||||
#include "msc_lua.h"
|
||||
|
||||
|
||||
#ifdef WITH_LUA
|
||||
|
||||
#include "apr_strings.h"
|
||||
|
||||
typedef struct {
|
||||
@ -123,18 +120,60 @@ static int l_log(lua_State *L) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static apr_array_header_t *resolve_tfns(lua_State *L, int idx, modsec_rec *msr, apr_pool_t *mp) {
|
||||
apr_array_header_t *tfn_arr = NULL;
|
||||
msre_tfn_metadata *tfn = NULL;
|
||||
char *name = NULL;
|
||||
|
||||
tfn_arr = apr_array_make(mp, 25, sizeof(msre_tfn_metadata *));
|
||||
if (tfn_arr == NULL) return NULL;
|
||||
|
||||
if (lua_istable(L, idx)) { /* Is the second parameter an array? */
|
||||
int i, n = lua_objlen(L, idx);
|
||||
|
||||
for(i = 1; i <= n; i++) {
|
||||
lua_rawgeti(L, idx, i);
|
||||
name = (char *)luaL_checkstring(L, -1);
|
||||
tfn = msre_engine_tfn_resolve(msr->modsecurity->msre, name);
|
||||
if (tfn == NULL) {
|
||||
msr_log(msr, 1, "SecRuleScript: Invalid transformation function: %s", name);
|
||||
} else {
|
||||
*(msre_tfn_metadata **)apr_array_push(tfn_arr) = tfn;
|
||||
}
|
||||
}
|
||||
} else if (lua_isstring(L, idx)) { /* The second parameter may be a simple string? */
|
||||
name = (char *)luaL_checkstring(L, idx);
|
||||
tfn = msre_engine_tfn_resolve(msr->modsecurity->msre, name);
|
||||
if (tfn == NULL) {
|
||||
msr_log(msr, 1, "SecRuleScript: Invalid transformation function: %s", name);
|
||||
} else {
|
||||
*(msre_tfn_metadata **)apr_array_push(tfn_arr) = tfn;
|
||||
}
|
||||
} else {
|
||||
// TODO Error
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return tfn_arr;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int l_getvar(lua_State *L) {
|
||||
char *varname = NULL;
|
||||
char *param = NULL;
|
||||
char *varname = NULL, *param = NULL;
|
||||
modsec_rec *msr = NULL;
|
||||
msre_rule *rule = NULL;
|
||||
char *my_error_msg = NULL;
|
||||
char *p1 = NULL;
|
||||
apr_array_header_t *tfn_arr = NULL;
|
||||
msre_var *vx = NULL;
|
||||
|
||||
/* Retrieve parameters. */
|
||||
varname = (char *)luaL_checkstring(L, 1);
|
||||
p1 = (char *)luaL_checkstring(L, 1);
|
||||
|
||||
/* Retrieve msr. */
|
||||
lua_getglobal(L, "__msr");
|
||||
@ -144,100 +183,123 @@ static int l_getvar(lua_State *L) {
|
||||
lua_getglobal(L, "__rule");
|
||||
rule = (msre_rule *)lua_topointer(L, -1);
|
||||
|
||||
/* Resolve variable $varname. */
|
||||
/* Extract the variable name and its parameter from the script. */
|
||||
varname = apr_pstrdup(msr->msc_rule_mptmp, p1);
|
||||
param = strchr(varname, '.');
|
||||
if (param != NULL) {
|
||||
*param = '\0';
|
||||
param++;
|
||||
}
|
||||
|
||||
/* Resolve variable. */
|
||||
msre_var *var = msre_create_var_ex(msr->msc_rule_mptmp, msr->modsecurity->msre,
|
||||
varname, param, msr, &my_error_msg);
|
||||
|
||||
if (var == NULL) {
|
||||
msr_log(msr, 1, "SecRuleScript: Failed to resolve variable: %s", varname);
|
||||
msr_log(msr, 1, "%s", my_error_msg);
|
||||
|
||||
lua_pushnil(L);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
msre_var *vx = NULL;
|
||||
|
||||
vx = generate_single_var(msr, var, rule, msr->msc_rule_mptmp);
|
||||
if (vx != NULL) {
|
||||
char *rval = NULL;
|
||||
long int rval_len = -1;
|
||||
|
||||
/* Transform the variable if a list of transformation
|
||||
* functions has been supplied.
|
||||
*/
|
||||
if (lua_istable(L, 2)) { /* Is the second parameter an array? */
|
||||
int i, n = lua_objlen(L, 2);
|
||||
|
||||
/* Make a copy so that we don't ruin the original value. */
|
||||
vx->value = apr_pstrmemdup(msr->msc_rule_mptmp, vx->value, vx->value_len);
|
||||
|
||||
for(i = 1; i <= n; i++) {
|
||||
msre_tfn_metadata *tfn = NULL;
|
||||
char *name = NULL;
|
||||
int rc = 0;
|
||||
|
||||
lua_rawgeti(L, 2, i);
|
||||
name = (char *)luaL_checkstring(L, -1);
|
||||
tfn = msre_engine_tfn_resolve(msr->modsecurity->msre, name);
|
||||
if (tfn == NULL) {
|
||||
msr_log(msr, 1, "SecRuleScript: Invalid transformation function in getvar() call: %s", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = tfn->execute(msr->msc_rule_mptmp, (unsigned char*)vx->value,
|
||||
vx->value_len, &rval, &rval_len);
|
||||
|
||||
vx->value = rval;
|
||||
vx->value_len = rval_len;
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "T (%d) %s: \"%s\"", rc, tfn->name,
|
||||
log_escape_nq_ex(msr->msc_rule_mptmp, vx->value, vx->value_len));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (lua_isstring(L, 2)) { /* The second parameter may be a simple string? */
|
||||
msre_tfn_metadata *tfn = NULL;
|
||||
char *name = NULL;
|
||||
int rc = 0;
|
||||
|
||||
/* Make a copy so that we don't ruin the original value. */
|
||||
vx->value = apr_pstrmemdup(msr->msc_rule_mptmp, vx->value, vx->value_len);
|
||||
|
||||
name = (char *)luaL_checkstring(L, 2);
|
||||
tfn = msre_engine_tfn_resolve(msr->modsecurity->msre, name);
|
||||
if (tfn == NULL) {
|
||||
msr_log(msr, 1, "SecRuleScript: Invalid transformation function in getvar() call: %s", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = tfn->execute(msr->msc_rule_mptmp, (unsigned char *)vx->value,
|
||||
vx->value_len, &rval, &rval_len);
|
||||
|
||||
vx->value = rval;
|
||||
vx->value_len = rval_len;
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "T (%d) %s: \"%s\"", rc, tfn->name,
|
||||
log_escape_nq_ex(msr->msc_rule_mptmp, vx->value, vx->value_len));
|
||||
}
|
||||
}
|
||||
|
||||
lua_pushlstring(L, vx->value, vx->value_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* Resolve transformation functions. */
|
||||
tfn_arr = resolve_tfns(L, 2, msr, msr->msc_rule_mptmp);
|
||||
|
||||
/* Generate variable. */
|
||||
vx = generate_single_var(msr, var, tfn_arr, rule, msr->msc_rule_mptmp);
|
||||
if (vx == NULL) {
|
||||
lua_pushnil(L);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return variable value. */
|
||||
lua_pushlstring(L, vx->value, vx->value_len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
static int l_getvars(lua_State *L) {
|
||||
const apr_array_header_t *tarr;
|
||||
const apr_table_entry_t *telts;
|
||||
apr_table_t *vartable = NULL;
|
||||
apr_array_header_t *tfn_arr = NULL;
|
||||
char *varname = NULL, *param = NULL;
|
||||
modsec_rec *msr = NULL;
|
||||
msre_rule *rule = NULL;
|
||||
msre_var *vartemplate = NULL;
|
||||
char *my_error_msg = NULL;
|
||||
char *p1 = NULL;
|
||||
int i;
|
||||
|
||||
/* Retrieve parameters. */
|
||||
p1 = (char *)luaL_checkstring(L, 1);
|
||||
|
||||
/* Retrieve msr. */
|
||||
lua_getglobal(L, "__msr");
|
||||
msr = (modsec_rec *)lua_topointer(L, -1);
|
||||
|
||||
/* Retrieve rule. */
|
||||
lua_getglobal(L, "__rule");
|
||||
rule = (msre_rule *)lua_topointer(L, -1);
|
||||
|
||||
/* Extract the variable name and its parameter from the script. */
|
||||
varname = apr_pstrdup(msr->msc_rule_mptmp, p1);
|
||||
param = strchr(varname, '.');
|
||||
if (param != NULL) {
|
||||
*param = '\0';
|
||||
param++;
|
||||
}
|
||||
|
||||
/* Resolve transformation functions. */
|
||||
tfn_arr = resolve_tfns(L, 2, msr, msr->msc_rule_mptmp);
|
||||
|
||||
lua_newtable(L);
|
||||
|
||||
/* Resolve variable. */
|
||||
vartemplate = msre_create_var_ex(msr->msc_rule_mptmp, msr->modsecurity->msre,
|
||||
varname, param, msr, &my_error_msg);
|
||||
|
||||
if (vartemplate == NULL) {
|
||||
msr_log(msr, 1, "%s", my_error_msg);
|
||||
|
||||
/* Returning empty table. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
vartable = generate_multi_var(msr, vartemplate, tfn_arr, rule, msr->msc_rule_mptmp);
|
||||
|
||||
tarr = apr_table_elts(vartable);
|
||||
telts = (const apr_table_entry_t*)tarr->elts;
|
||||
for (i = 0; i < tarr->nelts; i++) {
|
||||
msre_var *var = (msre_var *)telts[i].val;
|
||||
|
||||
lua_pushnumber(L, i + 1); /* Index is not zero-based. */
|
||||
|
||||
lua_newtable(L); /* Per-parameter table. */
|
||||
|
||||
lua_pushstring(L, "name");
|
||||
lua_pushlstring(L, var->name, strlen(var->name));
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_pushstring(L, "value");
|
||||
lua_pushlstring(L, var->value, var->value_len);
|
||||
lua_settable(L, -3);
|
||||
|
||||
lua_settable(L, -3); /* Push one parameter into the results table. */
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg mylib[] = {
|
||||
{ "log", l_log },
|
||||
{ "getvar", l_getvar },
|
||||
{ "getvars", l_getvars },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
@ -317,4 +379,3 @@ int lua_execute(msc_script *script, char *param, modsec_rec *msr, msre_rule *rul
|
||||
return ((*error_msg != NULL) ? RULE_MATCH : RULE_NO_MATCH);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -11,8 +11,6 @@
|
||||
#ifndef _MSC_LUA_H_
|
||||
#define _MSC_LUA_H_
|
||||
|
||||
#if defined(WITH_LUA)
|
||||
|
||||
typedef struct msc_script msc_script;
|
||||
typedef struct msc_script_part msc_script_part;
|
||||
|
||||
@ -39,4 +37,3 @@ char DSOLOCAL *lua_compile(msc_script **script, const char *filename, apr_pool_t
|
||||
int DSOLOCAL lua_execute(msc_script *script, char *param, modsec_rec *msr, msre_rule *rule, char **error_msg);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -1314,7 +1314,6 @@ msre_rule *msre_rule_create(msre_ruleset *ruleset,
|
||||
return rule;
|
||||
}
|
||||
|
||||
#ifdef WITH_LUA
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -1362,7 +1361,6 @@ msre_rule *msre_rule_lua_create(msre_ruleset *ruleset,
|
||||
|
||||
return rule;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Perform non-disruptive actions associated with the provided actionset.
|
||||
@ -2001,11 +1999,9 @@ apr_status_t msre_rule_process(msre_rule *rule, modsec_rec *msr) {
|
||||
apr_pool_clear(msr->msc_rule_mptmp);
|
||||
}
|
||||
|
||||
#if defined(WITH_LUA)
|
||||
if (rule->type == RULE_TYPE_LUA) {
|
||||
return msre_rule_process_lua(rule, msr);
|
||||
}
|
||||
#endif
|
||||
|
||||
return msre_rule_process_normal(rule, msr);
|
||||
}
|
||||
|
@ -65,9 +65,11 @@ int DSOLOCAL msre_parse_generic(apr_pool_t *pool, const char *text, apr_table_t
|
||||
|
||||
int DSOLOCAL rule_id_in_range(int ruleid, const char *range);
|
||||
|
||||
msre_var DSOLOCAL *generate_single_var(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_pool_t *mptmp);
|
||||
msre_var DSOLOCAL *generate_single_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
|
||||
msre_rule *rule, apr_pool_t *mptmp);
|
||||
|
||||
apr_table_t DSOLOCAL *generate_multi_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
|
||||
msre_rule *rule, apr_pool_t *mptmp);
|
||||
|
||||
/* Structures with the corresponding functions */
|
||||
|
||||
@ -143,9 +145,8 @@ struct msre_rule {
|
||||
unsigned int execution_time;
|
||||
#endif
|
||||
|
||||
#if defined(WITH_LUA)
|
||||
/* Compiled Lua script. */
|
||||
msc_script *script;
|
||||
#endif
|
||||
};
|
||||
|
||||
msre_rule DSOLOCAL *msre_rule_create(msre_ruleset *ruleset,
|
||||
|
@ -39,21 +39,118 @@ static void msre_engine_action_register(msre_engine *engine, const char *name, u
|
||||
/**
|
||||
* Generates a single variable (from the supplied metadata).
|
||||
*/
|
||||
msre_var *generate_single_var(modsec_rec *msr, msre_var *var, msre_rule *rule,
|
||||
apr_pool_t *mptmp)
|
||||
msre_var *generate_single_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
|
||||
msre_rule *rule, apr_pool_t *mptmp)
|
||||
{
|
||||
apr_table_t *vartab = NULL;
|
||||
const apr_table_entry_t *te = NULL;
|
||||
const apr_array_header_t *arr = NULL;
|
||||
msre_var *rvar = NULL;
|
||||
int i;
|
||||
|
||||
/* Sanity check. */
|
||||
if ((var == NULL)||(var->metadata == NULL)||(var->metadata->generate == NULL)) return NULL;
|
||||
|
||||
if (var->metadata->generate == NULL) return NULL;
|
||||
vartab = apr_table_make(mptmp, 16);
|
||||
var->metadata->generate(msr, var, rule, vartab, mptmp);
|
||||
|
||||
arr = apr_table_elts(vartab);
|
||||
if (arr->nelts == 0) return NULL;
|
||||
te = (apr_table_entry_t *)arr->elts;
|
||||
te = (apr_table_entry_t *)arr->elts;
|
||||
|
||||
return (msre_var *)te[0].val;
|
||||
rvar = (msre_var *)te[0].val;
|
||||
|
||||
/* Return straight away if there were no
|
||||
* transformation functions supplied.
|
||||
*/
|
||||
if ((tfn_arr == NULL)||(tfn_arr->nelts == 0)) {
|
||||
return rvar;
|
||||
}
|
||||
|
||||
/* Copy the value so that we can transform it in piece. */
|
||||
rvar->value = apr_pstrndup(mptmp, rvar->value, rvar->value_len);
|
||||
|
||||
/* Transform rvar in a loop. */
|
||||
for (i = 0; i < tfn_arr->nelts; i++) {
|
||||
msre_tfn_metadata *tfn = ((msre_tfn_metadata **)tfn_arr->elts)[i];
|
||||
char *rval;
|
||||
int rc;
|
||||
long int rval_len;
|
||||
|
||||
rc = tfn->execute(mptmp, (unsigned char *)rvar->value,
|
||||
rvar->value_len, &rval, &rval_len);
|
||||
|
||||
rvar->value = rval;
|
||||
rvar->value_len = rval_len;
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "T (%d) %s: \"%s\"", rc, tfn->name,
|
||||
log_escape_nq_ex(mptmp, rvar->value, rvar->value_len));
|
||||
}
|
||||
}
|
||||
|
||||
return rvar;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
apr_table_t *generate_multi_var(modsec_rec *msr, msre_var *var, apr_array_header_t *tfn_arr,
|
||||
msre_rule *rule, apr_pool_t *mptmp)
|
||||
{
|
||||
const apr_array_header_t *tarr;
|
||||
const apr_table_entry_t *telts;
|
||||
apr_table_t *vartab = NULL, *tvartab = NULL;
|
||||
msre_var *rvar = NULL;
|
||||
int i, j;
|
||||
|
||||
/* Sanity check. */
|
||||
if ((var == NULL)||(var->metadata == NULL)||(var->metadata->generate == NULL)) return NULL;
|
||||
|
||||
/* Generate variables. */
|
||||
vartab = apr_table_make(mptmp, 16);
|
||||
var->metadata->generate(msr, var, rule, vartab, mptmp);
|
||||
|
||||
/* Return straight away if there were no
|
||||
* transformation functions supplied.
|
||||
*/
|
||||
if ((tfn_arr == NULL)||(tfn_arr->nelts == 0)) {
|
||||
return vartab;
|
||||
}
|
||||
|
||||
tvartab = apr_table_make(mptmp, 16);
|
||||
|
||||
tarr = apr_table_elts(vartab);
|
||||
telts = (const apr_table_entry_t*)tarr->elts;
|
||||
for (j = 0; j < tarr->nelts; j++) {
|
||||
rvar = (msre_var *)telts[j].val;
|
||||
|
||||
/* Copy the value so that we can transform it in piece. */
|
||||
rvar->value = apr_pstrndup(mptmp, rvar->value, rvar->value_len);
|
||||
|
||||
/* Transform rvar in a loop. */
|
||||
for (i = 0; i < tfn_arr->nelts; i++) {
|
||||
msre_tfn_metadata *tfn = ((msre_tfn_metadata **)tfn_arr->elts)[i];
|
||||
char *rval;
|
||||
int rc;
|
||||
long int rval_len;
|
||||
|
||||
rc = tfn->execute(mptmp, (unsigned char *)rvar->value,
|
||||
rvar->value_len, &rval, &rval_len);
|
||||
|
||||
rvar->value = rval;
|
||||
rvar->value_len = rval_len;
|
||||
|
||||
if (msr->txcfg->debuglog_level >= 9) {
|
||||
msr_log(msr, 9, "T (%d) %s: \"%s\"", rc, tfn->name,
|
||||
log_escape_nq_ex(mptmp, rvar->value, rvar->value_len));
|
||||
}
|
||||
}
|
||||
|
||||
apr_table_addn(tvartab, rvar->name, (void *)rvar);
|
||||
}
|
||||
|
||||
return tvartab;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,7 +234,7 @@ int expand_macros(modsec_rec *msr, msc_string *var, msre_rule *rule, apr_pool_t
|
||||
var_resolved = msre_create_var_ex(mptmp, msr->modsecurity->msre, var_name, var_value,
|
||||
msr, &my_error_msg);
|
||||
if (var_resolved != NULL) {
|
||||
var_generated = generate_single_var(msr, var_resolved, rule, mptmp);
|
||||
var_generated = generate_single_var(msr, var_resolved, NULL, rule, mptmp);
|
||||
if (var_generated != NULL) {
|
||||
part = (msc_string *)apr_pcalloc(mptmp, sizeof(msc_string));
|
||||
if (part == NULL) return -1;
|
||||
@ -1457,7 +1554,6 @@ static char *msre_action_exec_validate(msre_engine *engine, msre_action *action)
|
||||
|
||||
/* TODO Support relative filenames. */
|
||||
|
||||
#ifdef WITH_LUA
|
||||
/* Process Lua scripts internally. */
|
||||
if (strlen(filename) > 4) {
|
||||
char *p = filename + strlen(filename) - 4;
|
||||
@ -1472,7 +1568,6 @@ static char *msre_action_exec_validate(msre_engine *engine, msre_action *action)
|
||||
action->param_data = script;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<title>ModSecurity Reference Manual</title>
|
||||
|
||||
<articleinfo>
|
||||
<releaseinfo>Version 2.5.0-rc1/ (December 19, 2007)</releaseinfo>
|
||||
<releaseinfo>Version 2.5.0-rc1/ (December 21, 2007)</releaseinfo>
|
||||
|
||||
<copyright>
|
||||
<year>2004-2007</year>
|
||||
@ -300,6 +300,11 @@
|
||||
installed on the server.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Install the latest version of Lua in the 5.1.x branch, if it
|
||||
isn't already installed on the server.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Unpack the ModSecurity archive</para>
|
||||
</listitem>
|
||||
@ -315,14 +320,13 @@
|
||||
|
||||
<listitem>
|
||||
<para>Edit Makefile to configure the correct include path for libxml
|
||||
(for example: <filename
|
||||
moreinfo="none">INCLUDES=-I/usr/include/libxml2</filename>)</para>
|
||||
(for example <filename moreinfo="none">-I
|
||||
/usr/include/libxml2</filename>)</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>(Optional) If you want to use Lua scripting add
|
||||
<literal>-DWITH_LUA</literal> and configure the path to Lua include
|
||||
files (for example <literal>-I /usr/include/lua5.1</literal>).</para>
|
||||
<para>Edit Makefile to configure the correct incpude path for Lua (for
|
||||
example <literal>-I /usr/include/lua5.1</literal>).</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
@ -339,19 +343,18 @@
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Add one line to your configuration to load libxml2: <filename
|
||||
<para>Load libxml2 before ModSecurity: <filename
|
||||
moreinfo="none">LoadFile /usr/lib/libxml2.so</filename></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>(Optional) Add one line to load Lua before ModSecurity:
|
||||
<literal>LoadFile /usr/lib/liblua5.1.so</literal>.</para>
|
||||
<para>Load Lua before ModSecurity: <literal>LoadFile
|
||||
/usr/lib/liblua5.1.so</literal>.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Add one line to your configuration to load ModSecurity: <literal
|
||||
moreinfo="none">LoadModule security2_module
|
||||
modules/mod_security2.so</literal></para>
|
||||
<para>Load ModSecurity itself: <literal moreinfo="none">LoadModule
|
||||
security2_module modules/mod_security2.so</literal></para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
@ -1805,6 +1808,12 @@ ServerAlias www.app2.com
|
||||
<literal>SecRuleScript</literal> resides. This allows you to place your
|
||||
script in the same folder as the configuration files using them.</para>
|
||||
|
||||
<note>
|
||||
<para>All Lua scripts are compiled at configuration time and cached in
|
||||
memory. To reload scripts you must reload the entire ModSecurity
|
||||
configuration by restarting Apache.</para>
|
||||
</note>
|
||||
|
||||
<para>Example script:</para>
|
||||
|
||||
<programlisting>-- Your script must define the <emphasis>main</emphasis> entry
|
||||
@ -1816,33 +1825,65 @@ function main()
|
||||
m.log(1, "Hello world!");
|
||||
|
||||
-- Retrieve one variable.
|
||||
var1 = m.getvar("REMOTE_ADDR");
|
||||
local var1 = m.getvar("REMOTE_ADDR");
|
||||
|
||||
-- Retrieve one variable, applying one transformation function.
|
||||
-- The second parameter is a string.
|
||||
var2 = m.getvar("REQUEST_URI", "normalisePath");
|
||||
local var2 = m.getvar("REQUEST_URI", "normalisePath");
|
||||
|
||||
-- Retrieve one variable, applying several transformation functions.
|
||||
-- The second parameter is now a list. You should note that m.getvar()
|
||||
-- requires the use of comma to separate collection names from
|
||||
-- variable names. This is because only one variable is returned.
|
||||
var3 = m.getvar("ARGS.p", { "lowercase", "compressWhitespace" } );
|
||||
local var3 = m.getvar("ARGS.p", { "lowercase", "compressWhitespace" } );
|
||||
|
||||
-- If you want this rule to match return a string
|
||||
-- containing the error message. It is a good idea to mention
|
||||
-- where the problem is located.
|
||||
-- containing the error message. The message <emphasis>must</emphasis> contain the name
|
||||
-- of the variable where the problem is located.
|
||||
-- return "Variable ARGS:p looks suspicious!"
|
||||
|
||||
-- Otherwise, simply return null.
|
||||
return null;
|
||||
end</programlisting>
|
||||
|
||||
<para>In this first example we were only retrieving one variable at the
|
||||
time. In this case the name of the variable is known to you. In many
|
||||
cases, however, you will want to examine variables whose names you won't
|
||||
know in advance, for example script parameters.</para>
|
||||
|
||||
<para>Example showing use of <literal>m.getvars()</literal> to retrieve
|
||||
many variables at once:</para>
|
||||
|
||||
<programlisting>function main()
|
||||
-- Retrieve script parameters.
|
||||
local d = m.getvars("ARGS", { "lowercase", "htmlEntityDecode" } );
|
||||
|
||||
-- Loop through the paramters.
|
||||
for i = 1, #d do
|
||||
-- Examine parameter value.
|
||||
if (string.find(d[i].value, "<script")) then
|
||||
-- Always specify the name of the variable where the
|
||||
-- problem is located in the error message.
|
||||
return ("Suspected XSS in variable " .. d[i].name .. ".");
|
||||
end
|
||||
end
|
||||
|
||||
-- Nothing wrong found.
|
||||
return null;
|
||||
end</programlisting>
|
||||
|
||||
<note>
|
||||
<para>Go to <ulink url="http://www.lua.org">http://www.lua.org</ulink>
|
||||
to find more about the Lua programming language. The reference manual
|
||||
too is available online, at <ulink
|
||||
url="http://www.lua.org/manual/5.1/">http://www.lua.org/manual/5.1/</ulink>.</para>
|
||||
</note>
|
||||
|
||||
<note>
|
||||
<para>Lua support is marked as <emphasis>experimental</emphasis>
|
||||
because the way the scripts are written and function names may still
|
||||
change while we are working for the best implementation style.</para>
|
||||
</note>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
@ -3926,9 +3967,8 @@ SecRule IP:AUTH_ATTEMPT "@gt 25" \
|
||||
<title><literal>exec</literal></title>
|
||||
|
||||
<para><emphasis>Description:</emphasis> Executes an external
|
||||
script/binary supplied as parameter. As of v2.5, when the support for
|
||||
Lua scripting is enabled, and the parameter supplied to
|
||||
<literal>exec</literal> is a Lua script (detected by the
|
||||
script/binary supplied as parameter. As of v2.5, if tge parameter
|
||||
supplied to <literal>exec</literal> is a Lua script (detected by the
|
||||
<filename>.lua</filename> extension) the script will be processed
|
||||
<emphasis>internally</emphasis>. This means you will get direct access
|
||||
to the internal request context from the script. Please read the
|
||||
@ -3945,8 +3985,7 @@ SecRule REQUEST_URI "^/cgi-bin/script\.pl" \
|
||||
"log,<emphasis>exec:/usr/local/apache/bin/test.sh</emphasis>"
|
||||
|
||||
# The following is going to process /usr/local/apache/conf/exec.lua
|
||||
# internally as a Lua script on rule match, provided ModSecurity was
|
||||
# compiled with Lua support enabled.
|
||||
# internally as a Lua script on rule match.
|
||||
SecRule ARGS:p attack log,<emphasis>exec:/usr/local/apache/conf/exec.lua</emphasis></programlisting>
|
||||
|
||||
<note>
|
||||
@ -4878,10 +4917,9 @@ SecRule ARGS:route "!<emphasis>@endsWith %{REQUEST_ADDR}</emphasis>" t:none,deny
|
||||
extracted from the request. As of v2.5, if the supplied filename is not
|
||||
absolute it is treated as relative to the directory in which the
|
||||
configuration file resides. Also as of v2.5 if the filename is
|
||||
determined to be a Lua script (based on its extension) and the Lua
|
||||
support is compiled in, the script will be processed by the internal
|
||||
engine. As such it will have full access to the ModSecurity
|
||||
context.</para>
|
||||
determined to be a Lua script (based on its extension) the script will
|
||||
be processed by the internal engine. As such it will have full access to
|
||||
the ModSecurity context.</para>
|
||||
|
||||
<para>Example of using an external binary/script:</para>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user