Skip to content

Use std::shared_ptr for variable resolution #2374

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2e1d1cc
Moves default actions to be part of the rules
zimmerle Apr 6, 2020
7b2c93a
parser: using GNU Bison 3.5.4
zimmerle Apr 14, 2020
5f07a54
Adds new method for rule merge
zimmerle Apr 14, 2020
b422b44
Rule: isMarker is no longer necessary
zimmerle Feb 25, 2019
7531723
Refactoring in the Rule class to make it more elegant
zimmerle Feb 25, 2019
32f3580
Refactoring: rename evaluate to execute on actions
zimmerle Feb 26, 2019
c867e94
Cosmetics: fix some cppcheck complains
zimmerle Apr 29, 2020
803ae35
Move travis to use a new version of Ubuntu
nikolas Oct 31, 2019
c5504cb
Refactoring: Makes transformations to work with new execute signature
zimmerle Feb 26, 2019
cbf41ce
Removes RuleMessage from action execute signature
zimmerle Mar 15, 2019
f092640
Cleanup on Action class
zimmerle Mar 15, 2019
f865730
Moves rule* headers to src/
zimmerle Feb 27, 2019
b8aae97
Cosmetics: Defining a type for RuleId
zimmerle Mar 20, 2019
a3eed59
Adds method getVariableNames to variables
zimmerle Apr 8, 2019
3214cee
Better error handling when loading configurations
zimmerle Mar 21, 2019
ee449f7
Improves rules dump for better testing
zimmerle Apr 11, 2019
2654086
Makes operator to use string_view
zimmerle Mar 5, 2019
629dcd5
Replaces lower case implementation
zimmerle Mar 20, 2019
ea2c75f
tests: Prints test number on segfault
zimmerle May 18, 2020
af1674c
tests: Romeves unused header from a test case
zimmerle May 18, 2020
80fe84a
actions: Compute the rule association during relus load
zimmerle May 18, 2020
2388c6e
actions: Removes Rule parameter from runtime execute
zimmerle May 19, 2020
a6bdf77
cosmetic: Organization on the Action class
zimmerle May 2, 2019
28d3e96
Computes auditlog during rules load time
zimmerle Jun 3, 2020
6e77a72
Action: make sure that null constructor is not used
zimmerle Jun 5, 2020
e725b1f
Removes method isDisruptive from Action class
zimmerle Jun 5, 2020
34bcde2
Makes Lua::run const
zimmerle Jun 8, 2020
9596c9f
Introduces ActionWithExecution
zimmerle Jun 8, 2020
5824470
Makes RuleWithActions const in run time operations
zimmerle May 8, 2019
77eb524
Use std::shared_ptr for variable resolution
WGH- Jul 28, 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
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
22 changes: 15 additions & 7 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,33 +72,38 @@ 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 bpstd::string_view &value,
size_t offset);

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

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 resolve(std::vector<const VariableValue *> *l);
void resolve(std::vector<const VariableValue *> *l,
void resolve(std::vector<std::shared_ptr<const VariableValue>> *l);
void resolve(std::vector<std::shared_ptr<const VariableValue>> *l,
variables::KeyExclusions &ke);

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

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

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

std::unique_ptr<std::string> resolveFirst(const std::string &key);
Expand Down
12 changes: 8 additions & 4 deletions headers/modsecurity/anchored_variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@
#include <utility>
#include <vector>
#include <memory>
#include <cstring>

#include "modsecurity/string_view.hpp"
#endif

#include "modsecurity/variable_value.h"


#ifndef HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_
#define HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_

Expand All @@ -55,17 +59,17 @@ class AnchoredVariable {
m_var(a.m_var) { }
*/

~AnchoredVariable();

void unset();
void set(const std::string &a, size_t offset);
void set(const bpstd::string_view &a, size_t offset);
void set(const char *a, size_t offset);
void set(const std::string &a, size_t offset, size_t offsetLen);
void append(const std::string &a, size_t offset,
bool spaceSeparator = false);
void append(const std::string &a, size_t offset,
bool spaceSeparator, int size);

void evaluate(std::vector<const VariableValue *> *l);
void evaluate(std::vector<std::shared_ptr<const VariableValue>> *l);
std::string * evaluate();
std::unique_ptr<std::string> resolveFirst();

Expand All @@ -75,7 +79,7 @@ class AnchoredVariable {
std::string m_value;

private:
VariableValue *m_var;
VariableValue m_var;
};

} // namespace modsecurity
Expand Down
Loading