|
15 | 15 |
|
16 | 16 | #include "src/operators/verify_cc.h"
|
17 | 17 |
|
18 |
| -#include <pcre.h> |
19 | 18 | #include <iostream>
|
20 | 19 | #include <cstring>
|
21 | 20 | #include <vector>
|
22 | 21 |
|
23 | 22 | #include "src/operators/operator.h"
|
24 | 23 |
|
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 |
| - |
32 | 24 | namespace modsecurity {
|
33 | 25 | namespace operators {
|
34 | 26 |
|
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 |
| - |
50 | 27 | /**
|
51 | 28 | * Luhn Mod-10 Method (ISO 2894/ANSI 4.13)
|
52 | 29 | */
|
@@ -90,70 +67,36 @@ int VerifyCC::luhnVerify(const char *ccnumber, int len) {
|
90 | 67 |
|
91 | 68 |
|
92 | 69 | bool VerifyCC::init(const std::string ¶m2, 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)); |
102 | 71 |
|
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(); |
113 | 74 | return false;
|
114 | 75 | }
|
115 |
| - |
116 | 76 | return true;
|
117 | 77 | }
|
118 | 78 |
|
119 | 79 |
|
120 | 80 | bool VerifyCC::evaluate(Transaction *t, Rule *rule,
|
121 | 81 | 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); |
154 | 94 | }
|
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) + "]"); |
156 | 98 | }
|
| 99 | + return true; |
157 | 100 | }
|
158 | 101 | }
|
159 | 102 |
|
|
0 commit comments