Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
a320a6c
Moves default actions to be part of the rules
zimmerle Apr 6, 2020
6db9a72
Adds new method for rule merge
zimmerle Apr 14, 2020
9512a4c
Rule: isMarker is no longer necessary
zimmerle Feb 25, 2019
058304f
Refactoring in the Rule class to make it more elegant
zimmerle Feb 25, 2019
fae8308
Refactoring: rename evaluate to execute on actions
zimmerle Feb 26, 2019
756ad61
Cosmetics: fix some cppcheck complains
zimmerle Apr 29, 2020
80224c4
Move travis to use a new version of Ubuntu
nikolas Oct 31, 2019
40146be
Refactoring: Makes transformations to work with new execute signature
zimmerle Feb 26, 2019
492732b
Removes RuleMessage from action execute signature
zimmerle Mar 15, 2019
e7e7b53
Cleanup on Action class
zimmerle Mar 15, 2019
283a591
Moves rule* headers to src/
zimmerle Feb 27, 2019
50f4ccf
Cosmetics: Defining a type for RuleId
zimmerle Mar 20, 2019
82deeaa
Adds method getVariableNames to variables
zimmerle Apr 8, 2019
9e7c8f2
Better error handling when loading configurations
zimmerle Mar 21, 2019
60d6e6d
Improves rules dump for better testing
zimmerle Apr 11, 2019
364d7ea
Makes operator to use string_view
zimmerle Mar 5, 2019
1cc4790
Replaces lower case implementation
zimmerle Mar 20, 2019
61ce984
tests: Prints test number on segfault
zimmerle May 18, 2020
6797b6d
tests: Romoves unused header from a test case
zimmerle May 18, 2020
8ed2880
actions: Compute the rule association during rules load
zimmerle May 18, 2020
8fbb7b0
actions: Removes Rule parameter from runtime execute
zimmerle May 19, 2020
ba90d6e
Computes auditlog during rules load time
zimmerle Jun 3, 2020
5b7fe82
Action: make sure that null constructor is not used
zimmerle Jun 5, 2020
a064202
Removes method isDisruptive from Action class
zimmerle Jun 5, 2020
e29e3f1
Makes Lua::run const
zimmerle Jun 8, 2020
6541c94
Introduces ActionWithExecution
zimmerle Jun 8, 2020
a89228d
Makes RuleWithActions const in run time operations
zimmerle May 8, 2019
4046053
Make all "rule id" variables of type RuleId
WGH- Jul 24, 2020
c3a4191
Remove unnecessary copying in transformations
WGH- Jul 22, 2020
89e1336
Use 'equal_range' instead of full scan for rule exceptions
zimmerle Aug 10, 2020
ccf4dc7
Removes init from SetVar
zimmerle Aug 20, 2020
8f541f1
Having RunTimeString in a better shape
zimmerle Aug 20, 2020
9a96db4
Use std::shared_ptr for variable resolution
WGH- Jul 28, 2020
bc45a82
Refactoring on variables::Variable
zimmerle Aug 21, 2020
01b4062
Cosmetics: Using VariableValues instead of std::vector<...>
zimmerle Aug 24, 2020
b407435
Delays variable name resolution to whenever it is necessary
zimmerle Aug 25, 2020
26a5d92
Removes unecessary ptr copy form VariableValue
zimmerle Aug 25, 2020
2377820
Replaces getKeyWithCollection with getName on VariableValue
zimmerle Aug 25, 2020
2ac776b
Removes copy form VariableValue
zimmerle Aug 26, 2020
a2e3414
Adds support for string_view in Variable
zimmerle Aug 26, 2020
ee92652
Reduce the workload on VariableValue
zimmerle Sep 17, 2020
2341270
Uses unique_ptr on REMOTE_USER
zimmerle Sep 18, 2020
45435d0
Constify Transaction on variable resolution
zimmerle Sep 18, 2020
38f92a4
Refactoring on the action addition to RuleWithAction
zimmerle Sep 23, 2020
e20462f
Adjustments on the error log
zimmerle Sep 24, 2020
baf1899
Having RuleWithActionsProperties()
zimmerle Oct 19, 2020
bb908bd
Implement id ranges for ctl:ruleRemoveTargetById
martinhsv Oct 21, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
dist: trusty
dist: bionic
sudo: true

addons:
Expand All @@ -9,7 +9,6 @@ addons:
- libgeoip-dev
- liblua5.2-dev
- liblmdb-dev
- cppcheck

language: cpp

Expand Down Expand Up @@ -38,9 +37,12 @@ before_script:
- '[ "$TRAVIS_OS_NAME" != osx ] || brew install libmaxminddb'
- '[ "$TRAVIS_OS_NAME" != osx ] || brew install lmdb'
- '[ "$TRAVIS_OS_NAME" != linux ] || sudo add-apt-repository --yes ppa:maxmind/ppa'
- '[ "$TRAVIS_OS_NAME" != linux ] || sudo add-apt-repository --yes ppa:grochefort/cppcheck'
- '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-get update'
- '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-cache search maxmind'
- '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-get install -y libmaxminddb-dev'
- '[ "$TRAVIS_OS_NAME" != linux ] || sudo apt-get install -y cppcheck'
- '[ "$TRAVIS_OS_NAME" != linux ] || cppcheck --version'

script:
- ./build.sh
Expand Down
34 changes: 33 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
@@ -1,6 +1,38 @@
v3.x.y - YYYY-MMM-DD (to be released)
-------------------------------------


- Implement id ranges for ctl:ruleRemoveTargetById
[#2110 - @j0k2r, @martinhsv]
- Removed unnecessary while processing the transformations.
[#2368 - @WGH-, @zimmerle]
- auditlog: Computes whether or not to save while loading the rules.
[@zimmerle]
- actions: Computes Rule association while loading the rules given a
performance boost on run time.
[@zimmerle]
- Regression: Mark the test as failed in case of segfault.
[@zimmerle]
- Replaced t:lowerCase backend for a better performance.
[@zimmerle]
- More structured rules dump. Better supporting debugging.
[@zimmerle]
- Added the basics for supporting better error/warning handling while
loading configurations.
[@zimmerle]
- IMPORTANT: SecDefaultAction behaves changing: SecDefaultAction specified
on a child configuration will overwrite the ones specified on the parent;
Previously it was concatenating.
[@zimmerle]
- Using std::shared_ptr instead of generates its own references counters
for Rules and related.
[@zimmerle]
- Better handle shared_pointers on messages aiming for better performance.
[@zimmerle]
- Better handle memory usage on transformations aiming for better
performance.
[@zimmerle]
- Coding refactoring on the Rule class. The Rule class is now refactored
into RuleWithOperator, RuleWithActions, and RuleUnconditional.
- Fix IP address logging in Section A
[Issue #2300 - @inaratech, @zavazingo, @martinhsv]
- Adds support to lua 5.4
Expand Down
6 changes: 4 additions & 2 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,16 @@ parser:

cppcheck:
@cppcheck -U YYSTYPE -U MBEDTLS_MD5_ALT -U MBEDTLS_SHA1_ALT \
-D MS_CPPCHECK_DISABLED_FOR_PARSER \
-D MS_CPPCHECK_DISABLED_FOR_PARSER -U YY_USER_INIT \
--suppressions-list=./test/cppcheck_suppressions.txt \
--enable=all \
--inconclusive \
--template="warning: {file},{line},{severity},{id},{message}" \
-I headers -I . -I others -I src -I others/mbedtls -I src/parser \
--error-exitcode=1 \
-i "src/parser/seclang-parser.cc" -i "src/parser/seclang-scanner.cc" \
-i "src/parser/seclang-parser.cc" \
-i "src/parser/seclang-scanner.cc" \
-i "parser/driver.cc" \
--force --verbose .


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,21 +176,22 @@ class ReadingLogsViaRuleMessage {
return;
}

const modsecurity::RuleMessage *ruleMessage = \
reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev);
modsecurity::RuleMessage ruleMessage(
*reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev));

std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId);
std::cout << " phase: " << std::to_string(ruleMessage->m_phase);

std::cout << "Rule Id: " << std::to_string(ruleMessage.getRuleId());
std::cout << " phase: " << std::to_string(ruleMessage.getPhase());
std::cout << std::endl;
if (ruleMessage->m_isDisruptive) {
if (ruleMessage.isDisruptive()) {
std::cout << " * Disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(&ruleMessage);
std::cout << std::endl;
std::cout << " ** %d is meant to be informed by the webserver.";
std::cout << std::endl;
} else {
std::cout << " * Match, but no disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(&ruleMessage);
std::cout << std::endl;
}
}
Expand Down
14 changes: 7 additions & 7 deletions examples/using_bodies_in_chunks/simple_request.cc
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,21 @@ static void logCb(void *data, const void *ruleMessagev) {
return;
}

const modsecurity::RuleMessage *ruleMessage = \
reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev);
modsecurity::RuleMessage ruleMessage(
*reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev));

std::cout << "Rule Id: " << std::to_string(ruleMessage->m_ruleId);
std::cout << " phase: " << std::to_string(ruleMessage->m_phase);
std::cout << "Rule Id: " << std::to_string(ruleMessage.getRuleId());
std::cout << " phase: " << std::to_string(ruleMessage.getPhase());
std::cout << std::endl;
if (ruleMessage->m_isDisruptive) {
if (ruleMessage.isDisruptive()) {
std::cout << " * Disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(&ruleMessage);
std::cout << std::endl;
std::cout << " ** %d is meant to be informed by the webserver.";
std::cout << std::endl;
} else {
std::cout << " * Match, but no disruptive action: ";
std::cout << modsecurity::RuleMessage::log(ruleMessage);
std::cout << modsecurity::RuleMessage::log(&ruleMessage);
std::cout << std::endl;
}
}
Expand Down
148 changes: 69 additions & 79 deletions headers/modsecurity/actions/action.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,11 @@
#ifdef __cplusplus

#include <string>
#include <iostream>
#include <memory>

#include <assert.h>

#endif

#include "modsecurity/intervention.h"
#include "modsecurity/rule.h"
#include "modsecurity/rule_with_actions.h"

#ifndef HEADERS_MODSECURITY_ACTIONS_ACTION_H_
#define HEADERS_MODSECURITY_ACTIONS_ACTION_H_
Expand All @@ -32,103 +29,96 @@

namespace modsecurity {
class Transaction;
class RuleWithOperator;

namespace actions {


class Action {
public:
explicit Action(const std::string& _action)
: m_isNone(false),
temporaryAction(false),
action_kind(2),
m_name(nullptr),
m_parser_payload("") {
set_name_and_payload(_action);
}
explicit Action(const std::string& _action, int kind)
: m_isNone(false),
temporaryAction(false),
action_kind(kind),
m_name(nullptr),
m_parser_payload("") {
set_name_and_payload(_action);
}
Action()
: m_parserPayload(""),
m_name("")
{
assert(0);
}


explicit Action(const std::string& action)
: m_parserPayload(sort_payload(action)),
m_name(sort_name(action))
{ }

virtual ~Action() { }

virtual std::string evaluate(const std::string &exp,
Transaction *transaction);
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction);
virtual bool evaluate(RuleWithActions *rule, Transaction *transaction,
std::shared_ptr<RuleMessage> ruleMessage) {
return evaluate(rule, transaction);
Action(const Action &other)
: m_parserPayload(other.m_parserPayload),
m_name(other.m_name)
{ }


Action &operator=(const Action& a) {
m_name = a.m_name;
m_parserPayload = a.m_parserPayload;
return *this;
}
virtual bool init(std::string *error) { return true; }
virtual bool isDisruptive() { return false; }


void set_name_and_payload(const std::string& data) {
virtual ~Action()
{ }


virtual bool init(std::string *error) {
return true;
}

const std::string *getName() const noexcept {
return &m_name;
}


protected:
std::string m_parserPayload;


private:
std::string m_name;

static size_t get_payload_pos(const std::string& data) {
size_t pos = data.find(":");
std::string t = "t:";

if (data.compare(0, t.length(), t) == 0) {
pos = data.find(":", 2);
}

return pos;
}


static std::string sort_name(const std::string& data) {
size_t pos = get_payload_pos(data);
if (pos == std::string::npos) {
m_name = std::shared_ptr<std::string>(new std::string(data));
return;
return data;
}

m_name = std::shared_ptr<std::string>(new std::string(data, 0, pos));
m_parser_payload = std::string(data, pos + 1, data.length());
std::string ret(data, 0, pos);
return ret;
}


if (m_parser_payload.at(0) == '\'' && m_parser_payload.size() > 2) {
m_parser_payload.erase(0, 1);
m_parser_payload.pop_back();
static std::string sort_payload(const std::string& data) {
size_t pos = get_payload_pos(data);
std::string ret("");
if (pos != std::string::npos) {
ret = std::string(data, pos + 1, data.length());

if (ret.at(0) == '\'' && ret.size() > 2) {
ret.erase(0, 1);
ret.pop_back();
}
}
}

bool m_isNone;
bool temporaryAction;
int action_kind;
std::shared_ptr<std::string> m_name;
std::string m_parser_payload;

/**
*
* Define the action kind regarding to the execution time.
*
*
*/
enum Kind {
/**
*
* Action that are executed while loading the configuration. For instance
* the rule ID or the rule phase.
*
*/
ConfigurationKind,
/**
*
* Those are actions that demands to be executed before call the operator.
* For instance the tranformations.
*
*
*/
RunTimeBeforeMatchAttemptKind,
/**
*
* Actions that are executed after the execution of the operator, only if
* the operator returned Match (or True). For instance the disruptive
* actions.
*
*/
RunTimeOnlyIfMatchKind,
};
};
return ret;
}
};


} // namespace actions
Expand Down
34 changes: 19 additions & 15 deletions headers/modsecurity/anchored_set_variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@
#include <vector>
#include <algorithm>
#include <memory>

#include "modsecurity/string_view.hpp"
#endif

#include "modsecurity/variable_value.h"


#ifndef HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_
#define HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_

Expand Down Expand Up @@ -69,36 +72,37 @@ struct MyHash{


class AnchoredSetVariable : public std::unordered_multimap<std::string,
VariableValue *, MyHash, MyEqual> {
std::shared_ptr<const VariableValue>, MyHash, MyEqual> {
public:
AnchoredSetVariable(Transaction *t, const std::string &name);
~AnchoredSetVariable();

void unset();

void set(const std::string &key, const std::string &value,
size_t offset);
void set(const std::string &key, const std::string &value, size_t offset) {
set(key, value, offset, value.size());
}

void set(const std::string &key, const std::string &value,
size_t offset, size_t len);

void setCopy(std::string key, std::string value, size_t offset);
void set(const std::string &key, const bpstd::string_view &value,
size_t offset);

void resolve(std::vector<const VariableValue *> *l);
void resolve(std::vector<const VariableValue *> *l,
variables::KeyExclusions &ke);
void resolve(VariableValues *l) const noexcept;
void resolve(VariableValues *l,
const variables::KeyExclusions &ke) const noexcept;

void resolve(const std::string &key,
std::vector<const VariableValue *> *l);
VariableValues *l) const noexcept;

void resolveRegularExpression(Utils::Regex *r,
std::vector<const VariableValue *> *l);
void resolveRegularExpression(const Utils::Regex *r,
VariableValues *l) const noexcept;

void resolveRegularExpression(Utils::Regex *r,
std::vector<const VariableValue *> *l,
variables::KeyExclusions &ke);
void resolveRegularExpression(const Utils::Regex *r,
VariableValues *l,
const variables::KeyExclusions &ke) const noexcept;

std::unique_ptr<std::string> resolveFirst(const std::string &key);
std::unique_ptr<std::string> resolveFirst(const std::string &key) const noexcept;

Transaction *m_transaction;
std::string m_name;
Expand Down
Loading