Skip to content

Commit 25175dd

Browse files
author
Felipe Zimmerle
committed
Adds support to verify CPF operator
1 parent 787b388 commit 25175dd

File tree

2 files changed

+162
-12
lines changed

2 files changed

+162
-12
lines changed

src/operators/verify_cpf.cc

+125-6
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,132 @@
2222
namespace modsecurity {
2323
namespace operators {
2424

25+
int VerifyCPF::convert_to_int(const char c)
26+
{
27+
int n;
28+
if ((c>='0') && (c<='9'))
29+
n = c - '0';
30+
else if ((c>='A') && (c<='F'))
31+
n = c - 'A' + 10;
32+
else if ((c>='a') && (c<='f'))
33+
n = c - 'a' + 10;
34+
else
35+
n = 0;
36+
return n;
37+
}
38+
39+
bool VerifyCPF::verify(const char *cpfnumber, int len) {
40+
int factor, part_1, part_2, var_len = len;
41+
unsigned int sum = 0, i = 0, cpf_len = 11, c;
42+
int cpf[11];
43+
char s_cpf[11];
44+
char bad_cpf[12][12] = { "00000000000",
45+
"01234567890",
46+
"11111111111",
47+
"22222222222",
48+
"33333333333",
49+
"44444444444",
50+
"55555555555",
51+
"66666666666",
52+
"77777777777",
53+
"88888888888",
54+
"99999999999"};
55+
56+
while ((*cpfnumber != '\0') && ( var_len > 0))
57+
{
58+
if (*cpfnumber != '-' || *cpfnumber != '.')
59+
{
60+
if (i < cpf_len && isdigit(*cpfnumber))
61+
{
62+
s_cpf[i] = *cpfnumber;
63+
cpf[i] = convert_to_int(*cpfnumber);
64+
i++;
65+
}
66+
}
67+
cpfnumber++;
68+
var_len--;
69+
}
70+
71+
72+
if (i != cpf_len)
73+
{
74+
return 0;
75+
}
76+
else
77+
{
78+
for (i = 0; i< cpf_len; i++)
79+
{
80+
if (strncmp(s_cpf,bad_cpf[i],cpf_len) == 0)
81+
{
82+
return 0;
83+
}
84+
}
85+
}
86+
87+
part_1 = convert_to_int(s_cpf[cpf_len-2]);
88+
part_2 = convert_to_int(s_cpf[cpf_len-1]);
89+
90+
c = cpf_len;
91+
92+
for (i = 0; i < 9; i++) {
93+
sum += (cpf[i] * --c);
94+
}
95+
96+
factor = (sum % cpf_len);
97+
98+
if(factor < 2) {
99+
cpf[9] = 0;
100+
} else {
101+
cpf[9] = cpf_len-factor;
102+
}
103+
104+
sum = 0;
105+
c = cpf_len;
106+
107+
for (i = 0;i < 10; i++)
108+
sum += (cpf[i] * c--);
109+
110+
factor = (sum % cpf_len);
111+
112+
if (factor < 2) {
113+
cpf[10] = 0;
114+
} else {
115+
cpf[10] = cpf_len-factor;
116+
}
117+
118+
if (part_1 == cpf[9] && part_2 == cpf[10])
119+
{
120+
return true;
121+
}
122+
123+
return false;
124+
}
125+
126+
127+
bool VerifyCPF::evaluate(Transaction *transaction, Rule *rule,
128+
const std::string& input, std::shared_ptr<RuleMessage> ruleMessage) {
129+
std::list<SMatch> matches;
130+
bool is_cpf = false;
131+
int i;
132+
133+
if (m_param.empty()) {
134+
return false;
135+
}
136+
137+
for (i = 0; i < input.size() - 1 && is_cpf == false; i++) {
138+
matches = m_re->searchAll(input.substr(i, input.size()));
139+
140+
for (const auto & i : matches) {
141+
is_cpf = verify(i.match.c_str(), i.match.size());
142+
logOffset(ruleMessage, i.m_offset, i.m_length);
143+
if (is_cpf) {
144+
goto out;
145+
}
146+
}
147+
}
25148

26-
bool VerifyCPF::evaluate(Transaction *transaction, const std::string &str) {
27-
/**
28-
* @todo Implement the operator VerifyCPF.
29-
* Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#verifyCPF
30-
*/
31-
return true;
149+
out:
150+
return is_cpf;
32151
}
33152

34153

src/operators/verify_cpf.h

+37-6
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,56 @@
1919
#include <string>
2020

2121
#include "src/operators/operator.h"
22+
#include "src/utils/regex.h"
23+
2224

2325
namespace modsecurity {
24-
namespace operators {
26+
using Utils::SMatch;
27+
using Utils::regex_search;
28+
using Utils::Regex;
2529

30+
namespace operators {
2631

2732
class VerifyCPF : public Operator {
2833
public:
2934
/** @ingroup ModSecurity_Operator */
3035
VerifyCPF(std::string o, std::string p, bool n)
31-
: Operator(o, p, n) { }
36+
: Operator(o, p, n) {
37+
m_re = new Regex(p);
38+
}
39+
VerifyCPF(std::string name, std::string param)
40+
: Operator(name, param) {
41+
m_re = new Regex(param);
42+
}
3243
explicit VerifyCPF(std::string param)
33-
: Operator("VerifyCPF", param) { }
34-
bool evaluate(Transaction *transaction, const std::string &str) override;
35-
};
44+
: Operator("VerifyCPF", param) {
45+
m_re = new Regex(param);
46+
}
3647

48+
~VerifyCPF() {
49+
delete m_re;
50+
}
51+
bool evaluate(Transaction *transaction, Rule *rule,
52+
const std::string &input) override {
53+
return evaluate(transaction, NULL, input, NULL);
54+
}
55+
bool evaluate(Transaction *transaction,
56+
const std::string &input) override {
57+
return evaluate(transaction, NULL, input);
58+
}
59+
bool evaluate(Transaction *transaction, Rule *rule,
60+
const std::string& input,
61+
std::shared_ptr<RuleMessage> ruleMessage) override;
62+
63+
int convert_to_int(const char c);
64+
bool verify(const char *ssnumber, int len);
65+
66+
private:
67+
Regex *m_re;
68+
};
3769

3870
} // namespace operators
3971
} // namespace modsecurity
4072

4173

42-
4374
#endif // SRC_OPERATORS_VERIFY_CPF_H_

0 commit comments

Comments
 (0)