Skip to content

Commit 2d1898a

Browse files
WGH-zimmerle
authored andcommitted
Update operator verifyCC to use Regex class
1 parent f171713 commit 2d1898a

File tree

3 files changed

+35
-83
lines changed

3 files changed

+35
-83
lines changed

src/operators/verify_cc.cc

Lines changed: 19 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -15,38 +15,15 @@
1515

1616
#include "src/operators/verify_cc.h"
1717

18-
#include <pcre.h>
1918
#include <iostream>
2019
#include <cstring>
2120
#include <vector>
2221

2322
#include "src/operators/operator.h"
2423

25-
#if PCRE_HAVE_JIT
26-
#define pcre_study_opt PCRE_STUDY_JIT_COMPILE
27-
#else
28-
#define pcre_study_opt 0
29-
#endif
30-
31-
3224
namespace modsecurity {
3325
namespace operators {
3426

35-
VerifyCC::~VerifyCC() {
36-
if (m_pc != NULL) {
37-
pcre_free(m_pc);
38-
m_pc = NULL;
39-
}
40-
if (m_pce != NULL) {
41-
#if PCRE_HAVE_JIT
42-
pcre_free_study(m_pce);
43-
#else
44-
pcre_free(m_pce);
45-
#endif
46-
m_pce = NULL;
47-
}
48-
}
49-
5027
/**
5128
* Luhn Mod-10 Method (ISO 2894/ANSI 4.13)
5229
*/
@@ -90,70 +67,36 @@ int VerifyCC::luhnVerify(const char *ccnumber, int len) {
9067

9168

9269
bool VerifyCC::init(const std::string &param2, std::string *error) {
93-
const char *errptr = NULL;
94-
int erroffset = 0;
95-
96-
m_pc = pcre_compile(m_param.c_str(), PCRE_DOTALL|PCRE_MULTILINE,
97-
&errptr, &erroffset, NULL);
98-
if (m_pc == NULL) {
99-
error->assign(errptr);
100-
return false;
101-
}
70+
m_re.reset(new modsecurity::regex::Regex(m_param));
10271

103-
m_pce = pcre_study(m_pc, pcre_study_opt, &errptr);
104-
if (m_pce == NULL) {
105-
if (errptr == NULL) {
106-
/*
107-
* Per pcre_study(3) m_pce == NULL && errptr == NULL means
108-
* that no addional information is found, so no need to study
109-
*/
110-
return true;
111-
}
112-
error->assign(errptr);
72+
if (!m_re->ok()) {
73+
*error = "Failed to compile regular expression " + m_re->getPattern();
11374
return false;
11475
}
115-
11676
return true;
11777
}
11878

11979

12080
bool VerifyCC::evaluate(Transaction *t, Rule *rule,
12181
const std::string& i, std::shared_ptr<RuleMessage> ruleMessage) {
122-
int offset = 0;
123-
bool is_cc = false;
124-
int target_length = i.length();
125-
126-
for (offset = 0; offset < target_length; offset++) {
127-
std::string match;
128-
int ovector[33];
129-
memset(ovector, 0, sizeof(ovector));
130-
int ret = pcre_exec(m_pc, m_pce, i.c_str(), i.size(), offset,
131-
0, ovector, 33) > 0;
132-
133-
/* If there was no match, then we are done. */
134-
if (ret == PCRE_ERROR_NOMATCH) {
135-
break;
136-
}
137-
if (ret < 0) {
138-
return false;
139-
}
140-
if (ret > 0) {
141-
match = std::string(i, ovector[0], ovector[1] - ovector[0]);
142-
is_cc = luhnVerify(match.c_str(), match.size());
143-
if (is_cc) {
144-
if (t) {
145-
if (rule && t && rule->m_containsCaptureAction) {
146-
t->m_collections.m_tx_collection->storeOrUpdateFirst(
147-
"0", std::string(match));
148-
ms_dbg_a(t, 7, "Added VerifyCC match TX.0: " + \
149-
std::string(match));
150-
}
151-
ms_dbg_a(t, 9, "CC# match \"" + m_param +
152-
"\" at " + i + ". [offset " +
153-
std::to_string(offset) + "]");
82+
83+
// ModSecurity v2 chacked for overlapping matches here,
84+
// so do we here
85+
for (const auto &m : m_re->searchAll(i, /* overlapping */ true)) {
86+
const auto &s = m.group(0).string;
87+
bool is_cc = luhnVerify(s.data(), s.size());
88+
if (is_cc) {
89+
if (t) {
90+
if (rule && t && rule->m_containsCaptureAction) {
91+
t->m_collections.m_tx_collection->storeOrUpdateFirst(
92+
"0", s);
93+
ms_dbg_a(t, 7, "Added VerifyCC match TX.0: " + s);
15494
}
155-
return true;
95+
ms_dbg_a(t, 9, "CC# match \"" + m_param +
96+
"\" at " + i + ". [offset " +
97+
std::to_string(m.group(0).offset) + "]");
15698
}
99+
return true;
157100
}
158101
}
159102

src/operators/verify_cc.h

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#ifndef SRC_OPERATORS_VERIFY_CC_H_
1717
#define SRC_OPERATORS_VERIFY_CC_H_
1818

19-
#include <pcre.h>
2019
#include <string>
2120
#include <memory>
2221
#include <utility>
@@ -30,19 +29,16 @@ class VerifyCC : public Operator {
3029
public:
3130
/** @ingroup ModSecurity_Operator */
3231
explicit VerifyCC(std::unique_ptr<RunTimeString> param)
33-
: Operator("VerifyCC", std::move(param)),
34-
m_pc(NULL),
35-
m_pce(NULL) { }
36-
~VerifyCC();
32+
: Operator("VerifyCC", std::move(param))
33+
{ }
3734

3835
int luhnVerify(const char *ccnumber, int len);
3936
bool evaluate(Transaction *t, Rule *rule,
4037
const std::string& input,
4138
std::shared_ptr<RuleMessage> ruleMessage) override;
4239
bool init(const std::string &param, std::string *error) override;
4340
private:
44-
pcre *m_pc;
45-
pcre_extra *m_pce;
41+
std::unique_ptr<modsecurity::regex::Regex> m_re;
4642
};
4743

4844
} // namespace operators

test/test-cases/regression/operator-verifycc.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,18 @@
4242
"SecRuleEngine On",
4343
"SecRule ARGS \"@verifycc \\d{13,16}\" \"id:1,phase:2,capture,pass,t:trim\""
4444
]
45+
},
46+
{
47+
"enabled":1,
48+
"version_min":300000,
49+
"version_max":0,
50+
"title":"Testing Operator :: @verifycc with invalid regular expression",
51+
"expected":{
52+
"parser_error":"Rules error.*Failed to compile regular expression \\\\d\\{13\\,16\\}\\("
53+
},
54+
"rules":[
55+
"SecRuleEngine On",
56+
"SecRule ARGS \"@verifycc \\d{13,16}(\" \"id:1,phase:2,pass,t:trim\""
57+
]
4558
}
4659
]

0 commit comments

Comments
 (0)