Thread: [mod-security-users] My variable seems to never expire...
Brought to you by:
victorhora,
zimmerletw
|
From: Mikaël P. <mik...@bo...> - 2020-09-15 19:30:15
|
Hello,
I'm new in modSecurity rules and I try to define some rules in my
modsecurity config (NGinx and libmodsecurity 3.0.3 - Debian).
One of these rules is a limit rate rule: I would like to limit users to 20
req/mn on my /api.* . So I define theses :
SecRule REQUEST_COOKIES:PHPSESSID "!^$" \
"id:400010,\
phase:1,\
pass,\
nolog,\
setsid:%{REQUEST_COOKIES.PHPSESSID}"
SecRule REQUEST_URI "^/api/" \
"id:400011,\
phase:2,\
pass,\
nolog,\
setvar:'session.api_req_counter=+1',\
expirevar:'session.api_req_counter=60'"
SecRule SESSION:API_REQ_COUNTER "@gt 20" \
"id:400012,\
deny,\
status:429,\
log,\
msg:'RATELIMITED',\
chain"
SecRule REQUEST_URI "^/api/"
It works: requests are denied! but they are forever. My
variable session.api_req_counter is never reseted.
Could you help me?
Thanks,
--
Mikaël,
|
|
From: Ervin H. <ai...@gm...> - 2020-09-15 19:56:22
|
Hi Mikaël, On Tue, Sep 15, 2020 at 08:29:50PM +0200, Mikaël Pirio wrote: ... > SecRule REQUEST_URI "^/api/" \ > "id:400011,\ > phase:2,\ > pass,\ > nolog,\ > setvar:'session.api_req_counter=+1',\ > expirevar:'session.api_req_counter=60'" ... > It works: requests are denied! but they are forever. My > variable session.api_req_counter is never reseted. I didn't checked the logic of the rules, but after the quick view I assume the expirevar has no effect (it's not implemented). Btw it's documented: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#expirevar "Supported on libModSecurity: TBI" a. |
|
From: logo <lo...@kr...> - 2020-09-15 20:30:08
|
Hi Ervin, > Am 15.09.2020 um 21:56 schrieb Ervin Hegedüs <ai...@gm...>: > > Hi Mikaël, > > On Tue, Sep 15, 2020 at 08:29:50PM +0200, Mikaël Pirio wrote: > ... > >> SecRule REQUEST_URI "^/api/" \ >> "id:400011,\ >> phase:2,\ >> pass,\ >> nolog,\ >> setvar:'session.api_req_counter=+1',\ >> expirevar:'session.api_req_counter=60'" > ... > >> It works: requests are denied! but they are forever. My >> variable session.api_req_counter is never reseted. > > I didn't checked the logic of the rules, but after the quick view > I assume the expirevar has no effect (it's not implemented). > > Btw it's documented: > > https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#expirevar > > "Supported on libModSecurity: TBI" > What does TBI mean? Peter > > a. > > > > _______________________________________________ > mod-security-users mailing list > mod...@li... > https://lists.sourceforge.net/lists/listinfo/mod-security-users > Commercial ModSecurity Rules and Support from Trustwave's SpiderLabs: > http://www.modsecurity.org/projects/commercial/rules/ > http://www.modsecurity.org/projects/commercial/support/ |
|
From: Ervin H. <ai...@gm...> - 2020-09-15 20:45:06
|
Hi logo, On Tue, Sep 15, 2020 at 10:29:47PM +0200, logo wrote: > > I didn't checked the logic of the rules, but after the quick view > > I assume the expirevar has no effect (it's not implemented). > > > > Btw it's documented: > > > > https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#expirevar > > > > "Supported on libModSecurity: TBI" > > > > What does TBI mean? I guess it means "To Be Implemented". But you can check it in the source - this is the parser, as you can see the scanned token points to the empty action: https://github.com/SpiderLabs/ModSecurity/blob/v3/master/src/parser/seclang-parser.cc#L5027-L5028 and this action does nothing: https://github.com/SpiderLabs/ModSecurity/blob/v3/master/src/actions/action.cc a. |
|
From: Mikaël P. <mik...@bo...> - 2020-09-15 20:58:25
|
Hi Ervin, Thank you very much. I suspected it but I wanted to have confirmation 😢 ... Do you know if there is a way to emulate this behavior? Le mar. 15 sept. 2020 à 22:46, Ervin Hegedüs <ai...@gm...> a écrit : > Hi logo, > > On Tue, Sep 15, 2020 at 10:29:47PM +0200, logo wrote: > > > I didn't checked the logic of the rules, but after the quick view > > > I assume the expirevar has no effect (it's not implemented). > > > > > > Btw it's documented: > > > > > > > https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual-(v2.x)#expirevar > > > > > > "Supported on libModSecurity: TBI" > > > > > > > What does TBI mean? > > I guess it means "To Be Implemented". > > But you can check it in the source - this is the parser, as you > can see the scanned token points to the empty action: > > > https://github.com/SpiderLabs/ModSecurity/blob/v3/master/src/parser/seclang-parser.cc#L5027-L5028 > > and this action does nothing: > > https://github.com/SpiderLabs/ModSecurity/blob/v3/master/src/actions/action.cc > > > a. > > > > _______________________________________________ > mod-security-users mailing list > mod...@li... > https://lists.sourceforge.net/lists/listinfo/mod-security-users > Commercial ModSecurity Rules and Support from Trustwave's SpiderLabs: > http://www.modsecurity.org/projects/commercial/rules/ > http://www.modsecurity.org/projects/commercial/support/ > |
|
From: Ervin H. <ai...@gm...> - 2020-09-15 21:17:03
|
Hi Mikaël, On Tue, Sep 15, 2020 at 10:49:55PM +0200, Mikaël Pirio wrote: > Hi Ervin, > > Thank you very much. I suspected it but I wanted to have confirmation 😢 ... sorry for bad news.. > Do you know if there is a way to emulate this behavior? try to check this hack: https://github.com/SpiderLabs/ModSecurity/issues/1803#issuecomment-474884652 but the other user wrote that it didn't worked for him (I also didn't checked the details...) https://github.com/SpiderLabs/ModSecurity/issues/1803#issuecomment-661514169 a. |
|
From: Mikaël P. <mik...@bo...> - 2020-09-17 17:05:30
|
@Ervin Thanks. These rules seems to work:
#
# Rate-limiting rules identified by PHPSESSIONID on /api requests
#
# Variables:
# SESSION:API_REQ_COUNTER counter of API requests
# TX:API_REQ_COUNTER_MAX max number of API requests which can pass
in %{tx.api_req_counter_timeout} seconds
# TX:API_REQ_COUNTER_TIMEOUT period in seconds a blocked PHP session id
will be blocked on API requests
#
# As a precondition for these rules, please set the following 2 variables:
# - TX:API_REQ_COUNTER_MAX
# - TX:API_REQ_COUNTER_TIMEOUT
#
# Define TX:API_REQ_COUNTER_MAX and TX_REQ_COUNTER_TIMEOUT
SecAction \
"id:1,\
phase:1,\
nolog,\
pass,\
t:none,\
setvar:tx.api_req_counter_timeout=60,\
setvar:tx.api_req_counter_max=100"
#
# Define SESSION
#
SecRule REQUEST_COOKIES:PHPSESSID "!^$" \
"id:2,\
phase:1,\
pass,\
nolog,\
setsid:%{REQUEST_COOKIES.PHPSESSID}"
###################################################
# TEMPORARY WORKAROUND FOR not working `expirevar`
###################################################
# Expire variables
SecRule &SESSION:API_REQ_COUNTER__EXPIRE_TIMESTAMP "@eq 1" \
"id:3,\
phase:1,\
pass,\
t:none,\
nolog,\
chain"
SecRule SESSION:API_REQ_COUNTER__EXPIRE_TIMESTAMP "@lt %{TIME_EPOCH}" \
"setvar:'!session.api_req_counter',\
setvar:'!session.api_req_counter__expire_timestamp'"
###################################################
###################################################
#
# If it's an API request:
# 1. Identify API requests
# 2. update counter
# 3. if session:api_req_counter__expire_timestamp is not define, define it
#
SecRule REQUEST_URI "@beginsWith /api/" \
"id:4,\
phase:1,\
pass,\
nolog,\
setvar:'tx.is_api_req=1',\
setvar:'session.api_req_counter=+1',\
expirevar:'session.api_req_counter=%{tx.api_req_counter_timeout}',\
chain"
SecRule &SESSION:API_REQ_COUNTER__EXPIRE_TIMESTAMP "@eq 0" \
"setvar:'session.api_req_counter__expire_timestamp=%{TIME_EPOCH}',\
setvar:'session.api_req_counter__expire_timestamp=+%{tx.api_req_counter_timeout}'"
#
# If max counter is reached AND it's an API request, deny it
#
SecRule SESSION:API_REQ_COUNTER "@gt %{tx.api_req_counter_max}" \
"id:5,\
deny,\
status:429,\
log,\
msg:'RATELIMITED',\
chain"
SecRule TX:IS_API_REQ "@eq 1"
Le mar. 15 sept. 2020 à 23:18, Ervin Hegedüs <ai...@gm...> a écrit :
> Hi Mikaël,
>
> On Tue, Sep 15, 2020 at 10:49:55PM +0200, Mikaël Pirio wrote:
> > Hi Ervin,
> >
> > Thank you very much. I suspected it but I wanted to have confirmation 😢
> ...
>
> sorry for bad news..
>
> > Do you know if there is a way to emulate this behavior?
>
> try to check this hack:
>
>
> https://github.com/SpiderLabs/ModSecurity/issues/1803#issuecomment-474884652
>
> but the other user wrote that it didn't worked for him (I also
> didn't checked the details...)
>
>
> https://github.com/SpiderLabs/ModSecurity/issues/1803#issuecomment-661514169
>
>
>
> a.
>
>
>
> _______________________________________________
> mod-security-users mailing list
> mod...@li...
> https://lists.sourceforge.net/lists/listinfo/mod-security-users
> Commercial ModSecurity Rules and Support from Trustwave's SpiderLabs:
> http://www.modsecurity.org/projects/commercial/rules/
> http://www.modsecurity.org/projects/commercial/support/
>
|
|
From: Ervin H. <ai...@gm...> - 2020-09-17 17:13:01
|
Hi Mikaël,
On Thu, Sep 17, 2020 at 06:38:58PM +0200, Mikaël Pirio wrote:
> @Ervin Thanks. These rules seems to work:
...
> #
> # If max counter is reached AND it's an API request, deny it
> #
> SecRule SESSION:API_REQ_COUNTER "@gt %{tx.api_req_counter_max}" \
> "id:5,\
> deny,\
> status:429,\
> log,\
> msg:'RATELIMITED',\
> chain"
> SecRule TX:IS_API_REQ "@eq 1"
>
it's good to know - thank you!
a.
|
|
From: Christian F. <chr...@ne...> - 2020-09-17 17:49:00
|
On Thu, Sep 17, 2020 at 07:12:41PM +0200, Ervin Hegedüs wrote: > it's good to know - thank you! Your recipe is one hell of a construction Airween. It would make for a good blog post somewhere. And really nice construction. Christian > > > > a. > > > > _______________________________________________ > mod-security-users mailing list > mod...@li... > https://lists.sourceforge.net/lists/listinfo/mod-security-users > Commercial ModSecurity Rules and Support from Trustwave's SpiderLabs: > http://www.modsecurity.org/projects/commercial/rules/ > http://www.modsecurity.org/projects/commercial/support/ |
|
From: Mikaël P. <mik...@bo...> - 2020-09-17 18:39:24
|
@Christian Thanks, Le jeu. 17 sept. 2020 à 19:50, Christian Folini <chr...@ne...> a écrit : > On Thu, Sep 17, 2020 at 07:12:41PM +0200, Ervin Hegedüs wrote: > > it's good to know - thank you! > > Your recipe is one hell of a construction Airween. It would make for a good > blog post somewhere. And really nice construction. > > Christian > > > > > > > > > a. > > > > > > > > _______________________________________________ > > mod-security-users mailing list > > mod...@li... > > https://lists.sourceforge.net/lists/listinfo/mod-security-users > > Commercial ModSecurity Rules and Support from Trustwave's SpiderLabs: > > http://www.modsecurity.org/projects/commercial/rules/ > > http://www.modsecurity.org/projects/commercial/support/ > > > _______________________________________________ > mod-security-users mailing list > mod...@li... > https://lists.sourceforge.net/lists/listinfo/mod-security-users > Commercial ModSecurity Rules and Support from Trustwave's SpiderLabs: > http://www.modsecurity.org/projects/commercial/rules/ > http://www.modsecurity.org/projects/commercial/support/ > |
|
From: Ervin H. <ai...@gm...> - 2020-09-18 08:07:05
|
On Thu, Sep 17, 2020 at 07:48:47PM +0200, Christian Folini wrote: > On Thu, Sep 17, 2020 at 07:12:41PM +0200, Ervin Hegedüs wrote: > > it's good to know - thank you! > > Your recipe is one hell of a construction Airween. It would make for a good > blog post somewhere. And really nice construction. just a quick note: that wasn't my recipe - it's from @theseion on the giving link. :) a. |
|
From: Christian F. <chr...@ne...> - 2020-09-18 08:12:32
|
On Fri, Sep 18, 2020 at 10:06:40AM +0200, Ervin Hegedüs wrote: > On Thu, Sep 17, 2020 at 07:48:47PM +0200, Christian Folini wrote: > > On Thu, Sep 17, 2020 at 07:12:41PM +0200, Ervin Hegedüs wrote: > > > it's good to know - thank you! > > > > Your recipe is one hell of a construction Airween. It would make for a good > > blog post somewhere. And really nice construction. > > just a quick note: that wasn't my recipe - it's from @theseion on > the giving link. :) Oh, I see. Thanks for pointing this out. Christian > > > a. > > > > _______________________________________________ > mod-security-users mailing list > mod...@li... > https://lists.sourceforge.net/lists/listinfo/mod-security-users > Commercial ModSecurity Rules and Support from Trustwave's SpiderLabs: > http://www.modsecurity.org/projects/commercial/rules/ > http://www.modsecurity.org/projects/commercial/support/ |
|
From: Mikaël P. <mik...@bo...> - 2020-09-18 13:36:01
|
@christian yes, the initial workaround about `expirevar` is from @theseion ( https://github.com/SpiderLabs/ModSecurity/issues/1803#issuecomment-474884652). In my conf, I've added a rule (see rule: 5, the second part) to init my session.api_req_counter__expire_timestamp variable once. If my recipe can help somebody, here the modsec and nginx (to add X-Limit-* headers) configuration: ModSec conf : # # Rate-limiting rules identified by PHPSESSIONID on /api requests # # Variables: # SESSION:API_REQ_COUNTER counter of API requests # TX:API_REQ_COUNTER_MAX max number of API requests which can pass in %{tx.api_req_counter_timeout} seconds # TX:API_REQ_COUNTER_TIMEOUT period in seconds a blocked PHP session id will be blocked on API requests # # As a precondition for these rules, please set the following 2 variables: # - TX:API_REQ_COUNTER_MAX # - TX:API_REQ_COUNTER_TIMEOUT # # Define TX:API_REQ_COUNTER_MAX and TX_REQ_COUNTER_TIMEOUT SecAction \ "id:1,\ phase:1,\ nolog,\ pass,\ t:none,\ setvar:tx.api_req_counter_timeout=60,\ setvar:tx.api_req_counter_max=100" # # Define SESSION # SecRule REQUEST_COOKIES:PHPSESSID "!^$" \ "id:2,\ phase:1,\ pass,\ nolog,\ setsid:%{REQUEST_COOKIES.PHPSESSID}" ################################################### # TEMPORARY WORKAROUND FOR not working `expirevar` ################################################### # Expire variables SecRule &SESSION:API_REQ_COUNTER__EXPIRE_TIMESTAMP "@eq 1" \ "id:3,\ phase:1,\ pass,\ t:none,\ nolog,\ chain" SecRule SESSION:API_REQ_COUNTER__EXPIRE_TIMESTAMP "@lt %{TIME_EPOCH}" \ "setvar:'!session.api_req_counter',\ setvar:'!session.api_req_counter__expire_timestamp'" ################################################### ################################################### # # If it's an API request: # 1. Identify API requests # 2. update counter # 3. if session:api_req_counter__expire_timestamp is not define, define it # SecRule REQUEST_URI "@beginsWith /api/" \ "id:4,\ phase:1,\ pass,\ nolog,\ setvar:'tx.is_api_req=1',\ setvar:'session.api_req_counter=+1',\ expirevar:'session.api_req_counter=%{tx.api_req_counter_timeout}',\ chain" SecRule &SESSION:API_REQ_COUNTER__EXPIRE_TIMESTAMP "@eq 0" \ "setvar:'session.api_req_counter__expire_timestamp=%{TIME_EPOCH}',\ setvar:'session.api_req_counter__expire_timestamp=+%{tx.api_req_counter_timeout}'" # # If max counter is reached AND it's an API request, deny it # SecRule SESSION:API_REQ_COUNTER "@gt %{tx.api_req_counter_max}" \ "id:5,\ deny,\ status:429,\ log,\ msg:'RATELIMITED',\ chain" SecRule TX:IS_API_REQ "@eq 1" SecRule TX:IS_API_REQ "@eq 1" \ "id:6,\ phase:1,\ pass,\ nolog,\ setenv:'ratelimit_limit=%{tx.api_req_counter_max}',\ setenv:'ratelimit_counter=%{session.api_req_counter}',\ setenv:'ratelimit_reset=%{session.api_req_counter__expire_timestamp}'" Nginx Conf (i use the module lua https://openresty.org/en/lua-nginx-module.html) : ... location /api/ { set_by_lua $ratelimit_limit 'return os.getenv("ratelimit_limit")'; set_by_lua $ratelimit_remaining 'return os.getenv("ratelimit_limit") - os.getenv("ratelimit_counter")'; set_by_lua $ratelimit_reset 'return os.getenv("ratelimit_reset")'; add_header X-RateLimit-Limit "$ratelimit_limit"; add_header X-RateLimit-Remaining "$ratelimit_remaining"; add_header X-RateLimit-Reset "$ratelimit_reset"; ... } ... |