Compare commits

...

10 Commits

Author SHA1 Message Date
openeuler-ci-bot
355f4cd417
!50 Fix HTTP service startup failure
From: @starlet-dx 
Reviewed-by: @wu-leilei 
Signed-off-by: @wu-leilei
2024-05-07 01:46:08 +00:00
starlet-dx
498cf8cbca Fix HTTP service startup failure 2024-05-07 09:34:34 +08:00
openeuler-ci-bot
874053013c
!41 Fix CVE-2022-48279
From: @starlet-dx 
Reviewed-by: @wu-leilei 
Signed-off-by: @wu-leilei
2024-03-26 09:19:49 +00:00
starlet-dx
c27ee70936 Fix CVE-2022-48279 2024-03-26 10:23:08 +08:00
openeuler-ci-bot
ee260ce51a !10 [sync] PR-6: Upgrade mod_security to 2.9.5 for fix CVE-2021-42717
Merge pull request !10 from openeuler-sync-bot/sync-pr6-openEuler-20.03-LTS-SP1-to-openEuler-20.03-LTS-SP3
2021-12-15 06:14:48 +00:00
starlet-dx
b495b0af90 Upgrade mod_security to 2.9.5 for fix CVE-2021-42717
(cherry picked from commit d6ee3431721635bfcbbe1e0dbd0ee54beea2aa92)
2021-12-15 11:10:29 +08:00
openeuler-ci-bot
f7bedeb457 !4 rebuild for mod_security
Merge pull request !4 from wangchen/mod-security-LTS
2020-05-21 19:18:50 +08:00
wangchen2020
83f233a3b7 rebuild for mod_security 2020-05-18 17:57:28 +08:00
openeuler-ci-bot
2499f5930f !2 package init
Merge pull request !2 from fun_yang/master
2020-02-17 20:34:47 +08:00
fun_yang
790462571f package init 2020-02-14 15:43:49 +08:00
8 changed files with 759 additions and 75 deletions

5
10-mod_security.conf Normal file
View File

@ -0,0 +1,5 @@
LoadModule security2_module modules/mod_security2.so
<IfModule !mod_unique_id.c>
LoadModule unique_id_module modules/mod_unique_id.so
</IfModule>

405
CVE-2022-48279.patch Normal file
View File

@ -0,0 +1,405 @@
From 7a489bd07c66d3df19a320b4306e00c49716dbb0 Mon Sep 17 00:00:00 2001
From: Martin Vierula <martin.vierula@trustwave.com>
Date: Wed, 7 Sep 2022 11:09:47 -0700
Subject: [PATCH] Multipart parsing fixes and new MULTIPART_PART_HEADERS
collection
---
CHANGES | 2 +
apache2/msc_multipart.c | 148 ++++++++++++++------
apache2/msc_multipart.h | 19 +++
apache2/re_variables.c | 57 ++++++++
tests/regression/misc/00-multipart-parser.t | 45 ++++++
5 files changed, 230 insertions(+), 41 deletions(-)
diff --git a/apache2/msc_multipart.c b/apache2/msc_multipart.c
index d087c863e..4128ab17e 100644
--- a/apache2/msc_multipart.c
+++ b/apache2/msc_multipart.c
@@ -325,7 +325,14 @@ static int multipart_process_part_header(modsec_rec *msr, char **error_msg) {
}
msr->mpd->mpp_state = 1;
+ msr->mpd->mpp_substate_part_data_read = 0;
msr->mpd->mpp->last_header_name = NULL;
+
+ /* Record the last part header line in the collection */
+ if (msr->mpd->mpp->last_header_line != NULL) {
+ *(char **)apr_array_push(msr->mpd->mpp->header_lines) = msr->mpd->mpp->last_header_line;
+ msr_log(msr, 9, "Multipart: Added part header line \"%s\"", msr->mpd->mpp->last_header_line);
+ }
} else {
/* Header line. */
@@ -379,12 +386,28 @@ static int multipart_process_part_header(modsec_rec *msr, char **error_msg) {
*error_msg = apr_psprintf(msr->mp, "Multipart: Part header too long.");
return -1;
}
+ if ((msr->mpd->mpp->last_header_line != NULL) && (msr->mpd->mpp->last_header_name != NULL)
+ && (new_value != NULL)) {
+ msr->mpd->mpp->last_header_line = apr_psprintf(msr->mp,
+ "%s: %s", msr->mpd->mpp->last_header_name, new_value);
+ }
+
} else {
char *header_name, *header_value, *data;
/* new header */
+ /* Record the most recently-seen part header line in the collection */
+ if (msr->mpd->mpp->last_header_line != NULL) {
+ *(char **)apr_array_push(msr->mpd->mpp->header_lines) = msr->mpd->mpp->last_header_line;
+ msr_log(msr, 9, "Multipart: Added part header line \"%s\"", msr->mpd->mpp->last_header_line);
+ }
+
data = msr->mpd->buf;
+
+ msr->mpd->mpp->last_header_line = apr_pstrdup(msr->mp, data);
+ remove_lf_crlf_inplace(msr->mpd->mpp->last_header_line);
+
while((*data != ':') && (*data != '\0')) data++;
if (*data == '\0') {
*error_msg = apr_psprintf(msr->mp, "Multipart: Invalid part header (colon missing): %s.",
@@ -438,6 +461,8 @@ static int multipart_process_part_data(modsec_rec *msr, char **error_msg) {
if (error_msg == NULL) return -1;
*error_msg = NULL;
+ msr->mpd->mpp_substate_part_data_read = 1;
+
/* Preserve some bytes for later. */
if ( ((MULTIPART_BUF_SIZE - msr->mpd->bufleft) >= 1)
&& (*(p - 1) == '\n') )
@@ -680,10 +705,14 @@ static int multipart_process_boundary(modsec_rec *msr, int last_part, char **err
if (msr->mpd->mpp == NULL) return -1;
msr->mpd->mpp->type = MULTIPART_FORMDATA;
msr->mpd->mpp_state = 0;
+ msr->mpd->mpp_substate_part_data_read = 0;
msr->mpd->mpp->headers = apr_table_make(msr->mp, 10);
if (msr->mpd->mpp->headers == NULL) return -1;
msr->mpd->mpp->last_header_name = NULL;
+ msr->mpd->mpp->last_header_line = NULL;
+ msr->mpd->mpp->header_lines = apr_array_make(msr->mp, 2, sizeof(char *));
+ if (msr->mpd->mpp->header_lines == NULL) return -1;
msr->mpd->reserve[0] = 0;
msr->mpd->reserve[1] = 0;
@@ -983,6 +1012,19 @@ int multipart_complete(modsec_rec *msr, char **error_msg) {
&& (*(msr->mpd->buf + 2 + strlen(msr->mpd->boundary)) == '-')
&& (*(msr->mpd->buf + 2 + strlen(msr->mpd->boundary) + 1) == '-') )
{
+ if ((msr->mpd->crlf_state_buf_end == 2) && (msr->mpd->flag_lf_line != 1)) {
+ msr->mpd->flag_lf_line = 1;
+ if (msr->mpd->flag_crlf_line) {
+ msr_log(msr, 4, "Multipart: Warning: mixed line endings used (CRLF/LF).");
+ } else {
+ msr_log(msr, 4, "Multipart: Warning: incorrect line endings used (LF).");
+ }
+ }
+ if (msr->mpd->mpp_substate_part_data_read == 0) {
+ /* it looks like the final boundary, but it's where part data should begin */
+ msr->mpd->flag_invalid_part = 1;
+ msr_log(msr, 4, "Multipart: Warning: Invalid part (data contains final boundary)");
+ }
/* Looks like the final boundary - process it. */
if (multipart_process_boundary(msr, 1 /* final */, error_msg) < 0) {
msr->mpd->flag_error = 1;
@@ -1075,54 +1117,63 @@ int multipart_process_chunk(modsec_rec *msr, const char *buf,
if ( (strlen(msr->mpd->buf) >= strlen(msr->mpd->boundary) + 2)
&& (strncmp(msr->mpd->buf + 2, msr->mpd->boundary, strlen(msr->mpd->boundary)) == 0) )
{
- char *boundary_end = msr->mpd->buf + 2 + strlen(msr->mpd->boundary);
- int is_final = 0;
+ if (msr->mpd->crlf_state_buf_end == 2) {
+ msr->mpd->flag_lf_line = 1;
+ }
+ if ((msr->mpd->mpp_substate_part_data_read == 0) && (msr->mpd->boundary_count > 0)) {
+ /* string matches our boundary, but it's where part data should begin */
+ msr->mpd->flag_invalid_part = 1;
+ msr_log(msr, 4, "Multipart: Warning: Invalid part (data contains boundary)");
+ } else {
+ char *boundary_end = msr->mpd->buf + 2 + strlen(msr->mpd->boundary);
+ int is_final = 0;
+
+ /* Is this the final boundary? */
+ if ((*boundary_end == '-') && (*(boundary_end + 1)== '-')) {
+ is_final = 1;
+ boundary_end += 2;
+
+ if (msr->mpd->is_complete != 0) {
+ msr->mpd->flag_error = 1;
+ *error_msg = apr_psprintf(msr->mp,
+ "Multipart: Invalid boundary (final duplicate).");
+ return -1;
+ }
+ }
- /* Is this the final boundary? */
- if ((*boundary_end == '-') && (*(boundary_end + 1)== '-')) {
- is_final = 1;
- boundary_end += 2;
+ /* Allow for CRLF and LF line endings. */
+ if ( ( (*boundary_end == '\r')
+ && (*(boundary_end + 1) == '\n')
+ && (*(boundary_end + 2) == '\0') )
+ || ( (*boundary_end == '\n')
+ && (*(boundary_end + 1) == '\0') ) )
+ {
+ if (*boundary_end == '\n') {
+ msr->mpd->flag_lf_line = 1;
+ } else {
+ msr->mpd->flag_crlf_line = 1;
+ }
- if (msr->mpd->is_complete != 0) {
- msr->mpd->flag_error = 1;
- *error_msg = apr_psprintf(msr->mp,
- "Multipart: Invalid boundary (final duplicate).");
- return -1;
- }
- }
+ if (multipart_process_boundary(msr, (is_final ? 1 : 0), error_msg) < 0) {
+ msr->mpd->flag_error = 1;
+ return -1;
+ }
- /* Allow for CRLF and LF line endings. */
- if ( ( (*boundary_end == '\r')
- && (*(boundary_end + 1) == '\n')
- && (*(boundary_end + 2) == '\0') )
- || ( (*boundary_end == '\n')
- && (*(boundary_end + 1) == '\0') ) )
- {
- if (*boundary_end == '\n') {
- msr->mpd->flag_lf_line = 1;
- } else {
- msr->mpd->flag_crlf_line = 1;
- }
+ if (is_final) {
+ msr->mpd->is_complete = 1;
+ }
- if (multipart_process_boundary(msr, (is_final ? 1 : 0), error_msg) < 0) {
+ processed_as_boundary = 1;
+ msr->mpd->boundary_count++;
+ }
+ else {
+ /* error */
msr->mpd->flag_error = 1;
+ *error_msg = apr_psprintf(msr->mp,
+ "Multipart: Invalid boundary: %s",
+ log_escape_nq(msr->mp, msr->mpd->buf));
return -1;
}
-
- if (is_final) {
- msr->mpd->is_complete = 1;
- }
-
- processed_as_boundary = 1;
- msr->mpd->boundary_count++;
- }
- else {
- /* error */
- msr->mpd->flag_error = 1;
- *error_msg = apr_psprintf(msr->mp,
- "Multipart: Invalid boundary: %s",
- log_escape_nq(msr->mp, msr->mpd->buf));
- return -1;
}
} else { /* It looks like a boundary but we couldn't match it. */
char *p = NULL;
@@ -1221,6 +1272,21 @@ int multipart_process_chunk(modsec_rec *msr, const char *buf,
msr->mpd->bufptr = msr->mpd->buf;
msr->mpd->bufleft = MULTIPART_BUF_SIZE;
msr->mpd->buf_contains_line = (c == 0x0a) ? 1 : 0;
+
+ if (c == 0x0a) {
+ if (msr->mpd->crlf_state == 1) {
+ msr->mpd->crlf_state = 3;
+ } else {
+ msr->mpd->crlf_state = 2;
+ }
+ }
+ msr->mpd->crlf_state_buf_end = msr->mpd->crlf_state;
+ }
+
+ if (c == 0x0d) {
+ msr->mpd->crlf_state = 1;
+ } else if (c != 0x0a) {
+ msr->mpd->crlf_state = 0;
}
if ((msr->mpd->is_complete) && (inleft != 0)) {
diff --git a/apache2/msc_multipart.h b/apache2/msc_multipart.h
index a0f6a08dd..13db0658f 100644
--- a/apache2/msc_multipart.h
+++ b/apache2/msc_multipart.h
@@ -55,6 +55,8 @@ struct multipart_part {
char *last_header_name;
apr_table_t *headers;
+ char *last_header_line;
+ apr_array_header_t *header_lines;
unsigned int offset;
unsigned int length;
@@ -81,6 +83,15 @@ struct multipart_data {
char *bufptr;
int bufleft;
+ /* line ending status seen immediately before current position.
+ * 0 = neither LF nor CR; 1 = prev char CR; 2 = prev char LF alone;
+ * 3 = prev two chars were CRLF
+ */
+ int crlf_state;
+
+ /* crlf_state at end of previous buffer */
+ int crlf_state_buf_end;
+
unsigned int buf_offset;
/* pointer that keeps track of a part while
@@ -94,6 +105,14 @@ struct multipart_data {
*/
int mpp_state;
+ /* part parsing substate; if mpp_state is 1 (collecting
+ * data), then for this variable:
+ * 0 means we have not yet read any data between the
+ * post-headers blank line and the next boundary
+ * 1 means we have read at some data after that blank line
+ */
+ int mpp_substate_part_data_read;
+
/* because of the way this parsing algorithm
* works we hold back the last two bytes of
* each data chunk so that we can discard it
diff --git a/apache2/re_variables.c b/apache2/re_variables.c
index 400738615..f3015acd9 100644
--- a/apache2/re_variables.c
+++ b/apache2/re_variables.c
@@ -1394,6 +1394,52 @@ static int var_files_combined_size_generate(modsec_rec *msr, msre_var *var, msre
return 1;
}
+/* MULTIPART_PART_HEADERS */
+
+static int var_multipart_part_headers_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
+ apr_table_t *vartab, apr_pool_t *mptmp)
+{
+ multipart_part **parts = NULL;
+ int i, j, count = 0;
+
+ if (msr->mpd == NULL) return 0;
+
+ parts = (multipart_part **)msr->mpd->parts->elts;
+ for(i = 0; i < msr->mpd->parts->nelts; i++) {
+ int match = 0;
+
+ /* Figure out if we want to include this variable. */
+ if (var->param == NULL) match = 1;
+ else {
+ if (var->param_data != NULL) { /* Regex. */
+ char *my_error_msg = NULL;
+ if (!(msc_regexec((msc_regex_t *)var->param_data, parts[i]->name,
+ strlen(parts[i]->name), &my_error_msg) == PCRE_ERROR_NOMATCH)) match = 1;
+ } else { /* Simple comparison. */
+ if (strcasecmp(parts[i]->name, var->param) == 0) match = 1;
+ }
+ }
+
+ /* If we had a match add this argument to the collection. */
+ if (match) {
+ for (j = 0; j < parts[i]->header_lines->nelts; j++) {
+ char *header_line = ((char **)parts[i]->header_lines->elts)[j];
+ msre_var *rvar = apr_pmemdup(mptmp, var, sizeof(msre_var));
+
+ rvar->value = header_line;
+ rvar->value_len = strlen(rvar->value);
+ rvar->name = apr_psprintf(mptmp, "MULTIPART_PART_HEADERS:%s",
+ log_escape_nq(mptmp, parts[i]->name));
+ apr_table_addn(vartab, rvar->name, (void *)rvar);
+
+ count++;
+ }
+ }
+ }
+
+ return count;
+}
+
/* MODSEC_BUILD */
static int var_modsec_build_generate(modsec_rec *msr, msre_var *var, msre_rule *rule,
@@ -2966,6 +3012,17 @@ void msre_engine_register_default_variables(msre_engine *engine) {
PHASE_REQUEST_BODY
);
+ /* MULTIPART_PART_HEADERS */
+ msre_engine_variable_register(engine,
+ "MULTIPART_PART_HEADERS",
+ VAR_LIST,
+ 0, 1,
+ var_generic_list_validate,
+ var_multipart_part_headers_generate,
+ VAR_CACHE,
+ PHASE_REQUEST_BODY
+ );
+
/* GEO */
msre_engine_variable_register(engine,
"GEO",
diff --git a/tests/regression/misc/00-multipart-parser.t b/tests/regression/misc/00-multipart-parser.t
index 3c1f41b7d..e5ee4c13c 100644
--- a/tests/regression/misc/00-multipart-parser.t
+++ b/tests/regression/misc/00-multipart-parser.t
@@ -1849,3 +1849,48 @@
),
},
+# part headers
+{
+ type => "misc",
+ comment => "multipart parser (part headers)",
+ conf => qq(
+ SecRuleEngine On
+ SecDebugLog $ENV{DEBUG_LOG}
+ SecDebugLogLevel 9
+ SecRequestBodyAccess On
+ SecRule MULTIPART_STRICT_ERROR "\@eq 1" "phase:2,deny,status:400,id:500168"
+ SecRule REQBODY_PROCESSOR_ERROR "\@eq 1" "phase:2,deny,status:400,id:500169"
+ SecRule MULTIPART_PART_HEADERS:image "\@rx content-type:.*jpeg" "phase:2,deny,status:403,id:500170,t:lowercase"
+ ),
+ match_log => {
+ debug => [ qr/500170.*against MULTIPART_PART_HEADERS:image.*Rule returned 1./s, 1 ],
+ },
+ match_response => {
+ status => qr/^403$/,
+ },
+ request => new HTTP::Request(
+ POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt",
+ [
+ "Content-Type" => q(multipart/form-data; boundary=0000),
+ ],
+ normalize_raw_request_data(
+ q(
+ --0000
+ Content-Disposition: form-data; name="username"
+
+ Bill
+ --0000
+ Content-Disposition: form-data; name="email"
+
+ bill@fakesite.com
+ --0000
+ Content-Disposition: form-data; name="image"; filename="image.jpg"
+ Content-Type: image/jpeg
+
+ BINARYDATA
+ --0000--
+ ),
+ ),
+ ),
+},
+

View File

@ -1,36 +0,0 @@
# mod_security
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

View File

@ -1,39 +0,0 @@
# mod_security
#### 介绍
{**以下是码云平台说明,您可以替换此简介**
码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 码云特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目
5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

226
mod_security.conf Normal file
View File

@ -0,0 +1,226 @@
# -- Rule engine initialization ----------------------------------------------
# Enable ModSecurity, attaching it to every transaction. Use detection
# only to start with, because that minimises the chances of post-installation
# disruption.
#
SecRuleEngine DetectionOnly
# -- Request body handling ---------------------------------------------------
# Allow ModSecurity to access request bodies. If you don't, ModSecurity
# won't be able to see any POST parameters, which opens a large security
# hole for attackers to exploit.
#
SecRequestBodyAccess On
# Enable XML request body parser.
# Initiate XML Processor in case of xml content-type
#
SecRule REQUEST_HEADERS:Content-Type "(?:application(?:/soap\+|/)|text/)xml" \
"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"
# Enable JSON request body parser.
# Initiate JSON Processor in case of JSON content-type; change accordingly
# if your application does not use 'application/json'
#
SecRule REQUEST_HEADERS:Content-Type "application/json" \
"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON"
# Maximum request body size we will accept for buffering. If you support
# file uploads then the value given on the first line has to be as large
# as the largest file you are willing to accept. The second value refers
# to the size of data, with files excluded. You want to keep that value as
# low as practical.
#
SecRequestBodyLimit 13107200
SecRequestBodyNoFilesLimit 131072
# Store up to 128 KB of request body data in memory. When the multipart
# parser reachers this limit, it will start using your hard disk for
# storage. That is slow, but unavoidable.
#
SecRequestBodyInMemoryLimit 131072
# What do do if the request body size is above our configured limit.
# Keep in mind that this setting will automatically be set to ProcessPartial
# when SecRuleEngine is set to DetectionOnly mode in order to minimize
# disruptions when initially deploying ModSecurity.
#
SecRequestBodyLimitAction Reject
# Verify that we've correctly processed the request body.
# As a rule of thumb, when failing to process a request body
# you should reject the request (when deployed in blocking mode)
# or log a high-severity alert (when deployed in detection-only mode).
#
SecRule REQBODY_ERROR "!@eq 0" \
"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"
# By default be strict with what we accept in the multipart/form-data
# request body. If the rule below proves to be too strict for your
# environment consider changing it to detection-only. You are encouraged
# _not_ to remove it altogether.
#
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
"id:'200003',phase:2,t:none,log,deny,status:400, \
msg:'Multipart request body failed strict validation: \
PE %{REQBODY_PROCESSOR_ERROR}, \
BQ %{MULTIPART_BOUNDARY_QUOTED}, \
BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
DB %{MULTIPART_DATA_BEFORE}, \
DA %{MULTIPART_DATA_AFTER}, \
HF %{MULTIPART_HEADER_FOLDING}, \
LF %{MULTIPART_LF_LINE}, \
SM %{MULTIPART_MISSING_SEMICOLON}, \
IQ %{MULTIPART_INVALID_QUOTING}, \
IP %{MULTIPART_INVALID_PART}, \
IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"
# Did we see anything that might be a boundary?
#
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" \
"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'"
# PCRE Tuning
# We want to avoid a potential RegEx DoS condition
#
SecPcreMatchLimit 1000
SecPcreMatchLimitRecursion 1000
# Some internal errors will set flags in TX and we will need to look for these.
# All of these are prefixed with "MSC_". The following flags currently exist:
#
# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
#
SecRule TX:/^MSC_/ "!@streq 0" \
"id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"
# -- Response body handling --------------------------------------------------
# Allow ModSecurity to access response bodies.
# You should have this directive enabled in order to identify errors
# and data leakage issues.
#
# Do keep in mind that enabling this directive does increases both
# memory consumption and response latency.
#
SecResponseBodyAccess On
# Which response MIME types do you want to inspect? You should adjust the
# configuration below to catch documents but avoid static files
# (e.g., images and archives).
#
SecResponseBodyMimeType text/plain text/html text/xml
# Buffer response bodies of up to 512 KB in length.
SecResponseBodyLimit 524288
# What happens when we encounter a response body larger than the configured
# limit? By default, we process what we have and let the rest through.
# That's somewhat less secure, but does not break any legitimate pages.
#
SecResponseBodyLimitAction ProcessPartial
# -- Filesystem configuration ------------------------------------------------
# The location where ModSecurity stores temporary files (for example, when
# it needs to handle a file upload that is larger than the configured limit).
#
# This default setting is chosen due to all systems have /tmp available however,
# this is less than ideal. It is recommended that you specify a location that's private.
#
SecTmpDir /tmp/
# The location where ModSecurity will keep its persistent data. This default setting
# is chosen due to all systems have /tmp available however, it
# too should be updated to a place that other users can't access.
#
SecDataDir /tmp/
# -- File uploads handling configuration -------------------------------------
# The location where ModSecurity stores intercepted uploaded files. This
# location must be private to ModSecurity. You don't want other users on
# the server to access the files, do you?
#
#SecUploadDir /opt/modsecurity/var/upload/
# By default, only keep the files that were determined to be unusual
# in some way (by an external inspection script). For this to work you
# will also need at least one file inspection rule.
#
#SecUploadKeepFiles RelevantOnly
# Uploaded files are by default created with permissions that do not allow
# any other user to access them. You may need to relax that if you want to
# interface ModSecurity to an external program (e.g., an anti-virus).
#
#SecUploadFileMode 0600
# -- Debug log configuration -------------------------------------------------
# The default debug log configuration is to duplicate the error, warning
# and notice messages from the error log.
#
#SecDebugLog /opt/modsecurity/var/log/debug.log
#SecDebugLogLevel 3
# -- Audit log configuration -------------------------------------------------
# Log the transactions that are marked by a rule, as well as those that
# trigger a server error (determined by a 5xx or 4xx, excluding 404,
# level response status codes).
#
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"
# Log everything we know about a transaction.
SecAuditLogParts ABIJDEFHZ
# Use a single file for logging. This is much easier to look at, but
# assumes that you will use the audit log only ocassionally.
#
SecAuditLogType Serial
SecAuditLog /var/log/modsec_audit.log
# Specify the path for concurrent audit logging.
#SecAuditLogStorageDir /opt/modsecurity/var/audit/
# -- Miscellaneous -----------------------------------------------------------
# Use the most commonly used application/x-www-form-urlencoded parameter
# separator. There's probably only one application somewhere that uses
# something else so don't expect to change this value.
#
SecArgumentSeparator &
# Settle on version 0 (zero) cookies, as that is what most applications
# use. Using an incorrect cookie version may open your installation to
# evasion attacks (against the rules that examine named cookies).
#
SecCookieFormat 0
# Specify your Unicode Code Point.
# This mapping is used by the t:urlDecodeUni transformation function
# to properly map encoded data to your language. Properly setting
# these directives helps to reduce false positives and negatives.
#
#SecUnicodeMapFile unicode.mapping 20127
# Improve the quality of ModSecurity by sharing information about your
# current ModSecurity version and dependencies versions.
# The following information will be shared: ModSecurity version,
# Web Server version, APR version, PCRE version, Lua version, Libxml2
# version, Anonymous unique id for host.
SecStatusEngine On

116
mod_security.spec Normal file
View File

@ -0,0 +1,116 @@
%{!?_httpd_apxs: %{expand: %%global _httpd_apxs %%{_sbindir}/apxs}}
%{!?_httpd_mmn: %{expand: %%global _httpd_mmn %%(cat %{_includedir}/httpd/.mmn || echo 0-0)}}
%{!?_httpd_modconfdir: %{expand: %%global _httpd_modconfdir %%{_sysconfdir}/httpd/conf.d}}
%{!?_httpd_confdir: %{expand: %%global _httpd_confdir %%{_sysconfdir}/httpd/conf.d}}
%{!?_httpd_moddir: %{expand: %%global _httpd_moddir %%{_libdir}/httpd/modules}}
%global mod_audit_log_collector 0
Name: mod_security
Version: 2.9.5
Release: 3
Summary: Security module for the Apache HTTP Server
License: ASL 2.0
URL: http://www.modsecurity.org/
Source: https://github.com/SpiderLabs/ModSecurity/releases/download/v%{version}/modsecurity-%{version}.tar.gz
Source1: mod_security.conf
Source2: 10-mod_security.conf
Source3: modsecurity_localrules.conf
# https://github.com/SpiderLabs/ModSecurity/commit/51a30d7b406af95c4143560d9753cf0b6d2151f5
Patch0: CVE-2022-48279.patch
Requires: httpd httpd-mmn = %{_httpd_mmn}
BuildRequires: gcc make perl-generators httpd-devel yajl yajl-devel
BuildRequires: pkgconfig(lua) pkgconfig(libcurl) pkgconfig(libxml-2.0) pkgconfig(libpcre)
%description
This software is also called Modsec,it is an open-source web application firewall.
It is designed for Apache HTTP Server.ModSecurity is commonly deployed to provide
protections against generic classed of vulnerabilities.The install of this package
is easy and you can read the README.TXT for more information.
%if %mod_audit_log_collector
%package -n mlogc
Summary: Collect mod_security audit log
Requires: mod_security
%description -n mlogc
This package collects mod_security audit log.
%endif
%prep
%autosetup -p1 -n modsecurity-%{version}
%build
%configure --with-yajl --with-apxs=%{_httpd_apxs} --enable-pcre-match-limit-recursion=1000000 --enable-pcre-match-limit=1000000
sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
make %{_smp_mflags}
%install
install -d %{buildroot}%{_bindir}
install -d %{buildroot}%{_sbindir}
install -d %{buildroot}%{_httpd_moddir}
install -m0755 apache2/.libs/mod_security2.so %{buildroot}%{_httpd_moddir}/mod_security2.so
install -d %{buildroot}%{_sysconfdir}/httpd/modsecurity.d/
install -d %{buildroot}%{_sysconfdir}/httpd/modsecurity.d/local_rules
install -d %{buildroot}%{_sysconfdir}/httpd/modsecurity.d/activated_rules
install -m 700 -d $RPM_BUILD_ROOT%{_localstatedir}/lib/%{name}
install -Dp -m0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/httpd/modsecurity.d/local_rules/
%if "%{_httpd_modconfdir}" != "%{_httpd_confdir}"
install -Dp -m0644 %{SOURCE1} %{buildroot}%{_httpd_confdir}/mod_security.conf
sed -i 's/Include/IncludeOptional/' %{buildroot}%{_httpd_confdir}/mod_security.conf
install -Dp -m0644 %{SOURCE2} %{buildroot}%{_httpd_modconfdir}/10-mod_security.conf
%else
install -d -m0755 %{buildroot}%{_httpd_confdir}
cat %{SOURCE2} %{SOURCE1} > %{buildroot}%{_httpd_confdir}/mod_security.conf
%endif
%if %mod_audit_log_collector
install -d %{buildroot}%{_localstatedir}/log/mlogc
install -d %{buildroot}%{_localstatedir}/log/mlogc/data
install -m0644 mlogc/mlogc-default.conf %{buildroot}%{_sysconfdir}/mlogc.conf
install -m0755 mlogc/mlogc %{buildroot}%{_bindir}/mlogc
install -m0755 mlogc/mlogc-batch-load.pl %{buildroot}%{_bindir}/mlogc-batch-load
%endif
%files
%doc README.* NOTICE LICENSE CHANGES
%{_httpd_moddir}/mod_security2.so
%config(noreplace) %{_httpd_confdir}/*.conf
%if "%{_httpd_modconfdir}" != "%{_httpd_confdir}"
%config(noreplace) %{_httpd_modconfdir}/*.conf
%endif
%dir %{_sysconfdir}/httpd/modsecurity.d
%dir %{_sysconfdir}/httpd/modsecurity.d/local_rules
%dir %{_sysconfdir}/httpd/modsecurity.d/activated_rules
%attr(770,apache,root) %dir %{_localstatedir}/lib/%{name}
%config(noreplace) %{_sysconfdir}/httpd/modsecurity.d/local_rules/*.conf
%if %mod_audit_log_collector
%files -n mlogc
%doc mlogc/INSTALL
%attr(0755,root,root) %dir %{_localstatedir}/log/mlogc
%attr(0770,root,apache) %dir %{_localstatedir}/log/mlogc/data
%attr(0640,root,apache) %config(noreplace) %{_sysconfdir}/mlogc.conf
%attr(0755,root,root) %{_bindir}/mlogc-batch-load
%attr(0755,root,root) %{_bindir}/mlogc
%endif
%changelog
* Mon May 06 2024 yaoxin <yao_xin001@hoperun.com> - 2.9.5-3
- Fix HTTP service startup failure
* Tue Mar 26 2024 yaoxin <yao_xin001@hoperun.com> - 2.9.5-2
- Fix CVE-2022-48279
* Tue Dec 14 2021 yaoxin <yaoxin30@huawei.com> - 2.9.5-1
- Upgrade mod_security to 2.9.5 for fix CVE-2021-42717
* Mon May 18 2020 wangchen <wangchen137@huawei.com> - 2.9.2-8
- rebuild for mod_security
* Wed Nov 20 2019 openEuler Buildteam <buildteam@openeuler.org> - 2.9.2-7
- Type:enhancement
- Id:NA
- SUG:NA
- DESC:modify the spec

BIN
modsecurity-2.9.5.tar.gz Normal file

Binary file not shown.

View File

@ -0,0 +1,7 @@
# You can use this file/directory to drop your local rules or
# to remove some rules provided by mod_security_crs package with SecRuleRemoveById
#
# You can also disable mod_security for some incompatible web applications (eg. phpMyAdmin).
#
#