# ------------------------------------------------------------------------
# OWASP ModSecurity Core Rule Set ver.3.3.9
# Copyright (c) 2006-2020 Trustwave and contributors. All rights reserved.
# Copyright (c) 2021-2026 Core Rule Set project. All rights reserved.
#
# The OWASP ModSecurity Core Rule Set is distributed under
# Apache Software License (ASL) version 2
# Please see the enclosed LICENSE file for full details.
#
# ------------------------------------------------------------------------

# These exclusions remedy false positives in a default Dokuwiki install.
# The exclusions are only active if crs_exclusions_dokuwiki=1 is set.
# See rule 900130 in crs-setup.conf.example for instructions.
#
# Note, if you want to relax the upload restrictions,
# see rule 900240. For Dokuwiki you can limit the exception
# to the ajax.php file:
#
# SecRule REQUEST_FILENAME "@endsWith /lib/exe/ajax.php" ...
#


SecRule &TX:crs_exclusions_dokuwiki|TX:crs_exclusions_dokuwiki "@eq 0" \
    "id:9004000,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    ver:'OWASP_CRS/3.3.9',\
    skipAfter:END-DOKUWIKI"

SecRule &TX:crs_exclusions_dokuwiki|TX:crs_exclusions_dokuwiki "@eq 0" \
    "id:9004001,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    ver:'OWASP_CRS/3.3.9',\
    skipAfter:END-DOKUWIKI"


#
# -=[ Dokuwiki Front-End ]=-
#
# Note on files specified:
# /doku.php: shows pages, saves, edits, admin
# /lib/exe/ajax.php: autosave, uploads
#
# Allow pages to be edited, and ajax to save drafts.
#
# ARGS 'wikitext', 'suffix', and 'prefix' must allow the same things,
# as the page (in part or whole) is passed via 'suffix/prefix' at times.
#  attack-protocol (921110-921160/920230): Allows odd characters on the page.
#  CRS: (still need attack-protocol specified.)
#  attack-injection-php (930000-933999): Allows code on page.
#  attack-sqli (940000-942999): Allows SQL expressions on page.
#
# Others:
#  930100-930110;REQUEST_BODY: if there's  a /../ in the text.
#
# ARGS:summary (the text in the 'summary' box on page edits.):
#  Allowing 930120-930130 lets user save summaries with
#  system file names. This should not be needed in normal
#  use. But leaving a note here of how to allow in rule below:
#    ctl:ruleRemoveTargetById=930120;ARGS:summary
#    ctl:ruleRemoveTargetById=930130;ARGS:summary
#
# Also, can't specify:
#   SecRule ARGS:do "@streq edit" \
#   SecRule REQUEST_FILENAME "@endsWith /lib/exe/ajax.php"\
# because at times the do=edit can get dropped, so if we use
# above the edit will get blocked when the page is saved.

# Hint: those using .htaccess rewrites can remove/replace
# this first 'SecRule...' line with 'SecAction \' (unsupported).

SecRule REQUEST_FILENAME "@rx (?:/doku.php|/lib/exe/ajax.php)$" \
    "id:9004100,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    ver:'OWASP_CRS/3.3.9',\
    chain"
    SecRule REQUEST_METHOD "@streq POST" \
        "t:none,\
        chain"
        SecRule REQUEST_COOKIES:/S?DW[a-f0-9]+/ "@rx ^[%a-zA-Z0-9_-]+" \
            "t:none,\
            ctl:ruleRemoveTargetByTag=attack-protocol;ARGS:wikitext,\
            ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:wikitext,\
            ctl:ruleRemoveTargetByTag=attack-protocol;ARGS:suffix,\
            ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:suffix,\
            ctl:ruleRemoveTargetByTag=attack-protocol;ARGS:prefix,\
            ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:prefix,\
            ctl:ruleRemoveTargetById=930100-930110;REQUEST_BODY"


# Allow it to upload files. But check for cookies just to make sure.

SecRule REQUEST_FILENAME "@endsWith /lib/exe/ajax.php" \
    "id:9004110,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    noauditlog,\
    ver:'OWASP_CRS/3.3.9',\
    chain"
    SecRule REQUEST_METHOD "@streq POST" \
        "t:none,\
        chain"
        SecRule REQUEST_COOKIES:/S?DW[a-f0-9]+/ "@rx ^[%a-zA-Z0-9_-]+" \
            "t:none,\
            setvar:'tx.allowed_request_content_type=%{tx.allowed_request_content_type}|application/octet-stream'"


# Show the index, even if things like "postgresql" or other things show up.

SecRule REQUEST_FILENAME "@endsWith /doku.php" \
    "id:9004130,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    noauditlog,\
    ver:'OWASP_CRS/3.3.9',\
    chain"
    SecRule ARGS:do "@streq index" \
        "t:none,\
        chain"
        SecRule &ARGS:do "@eq 1" \
            "t:none,\
            ctl:ruleRemoveById=951240,\
            ctl:ruleRemoveById=953110"


#
# [ Login form ]
#

# Turn off checks for password.

SecRule REQUEST_FILENAME "@endsWith /doku.php" \
    "id:9004200,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    noauditlog,\
    ver:'OWASP_CRS/3.3.9',\
    chain"
    SecRule ARGS:do "@streq login" \
        "t:none,\
        chain"
        SecRule &ARGS:do "@eq 1" \
            "t:none,\
            ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:p"


#
# [ Admin Area ]
#
# Skip this section for performance unless do=admin is in request

SecRule ARGS:do "!@streq admin" \
    "id:9004300,\
    phase:1,\
    pass,\
    t:none,\
    nolog,\
    ver:'OWASP_CRS/3.3.9',\
    skipAfter:END-DOKUWIKI-ADMIN"

SecRule ARGS:do "!@streq admin" \
    "id:9004310,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    ver:'OWASP_CRS/3.3.9',\
    skipAfter:END-DOKUWIKI-ADMIN"


# [ Reset password ]
#
# Turn off checks for pass1, pass1-text, pass2

SecRule REQUEST_FILENAME "@endsWith /doku.php" \
    "id:9004320,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    noauditlog,\
    ver:'OWASP_CRS/3.3.9',\
    chain"
    SecRule ARGS:do "@streq login" \
        "t:none,\
        chain"
        SecRule &ARGS:do "@eq 1" \
            "t:none,\
            ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1,\
            ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass1-text,\
            ctl:ruleRemoveTargetByTag=OWASP_CRS;ARGS:pass2"


# [ Save config ]
#
# Allow the config to be saved:
# 942200:  If the user adds "..." to tagline: ARGS:config[tagline]
# 942430:  if ARGS:config[hidepages] has pages looking like sql statements
# 942430,942440:  "--- //[[@MAIL@|@NAME@]] @DATE@//"]" in ARGS:config[signature]

SecRule REQUEST_FILENAME "@endsWith /doku.php" \
    "id:9004370,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    noauditlog,\
    ver:'OWASP_CRS/3.3.9',\
    chain"
    SecRule ARGS:page "@streq config" \
        "t:none,\
        chain"
        SecRule &ARGS:page "@eq 1" \
            "t:none,\
            chain"
            SecRule REQUEST_METHOD "@streq POST" \
                "t:none,\
                chain"
                SecRule REQUEST_COOKIES:/S?DW[a-f0-9]+/ "@rx ^[%a-zA-Z0-9_-]+" \
                    "t:none,\
                    ctl:ruleRemoveTargetById=920230;ARGS:config[dformat],\
                    ctl:ruleRemoveTargetById=942200;ARGS:config[tagline],\
                    ctl:ruleRemoveTargetById=942430;ARGS:config[hidepages],\
                    ctl:ruleRemoveTargetById=942430-942440;ARGS:config[signature]"


# When the config loads after a save, it gets blocked because
#   it has 'readdir' and lines that look like sql
# 942430,942440:  "--- //[[@MAIL@|@NAME@]] @DATE@//"]" in ARGS:config[signature]
# 951240,953110:  When the page reloads, it triggers
#   postgres and php code disclosure rules.

SecRule REQUEST_FILENAME "@endsWith /doku.php" \
    "id:9004380,\
    phase:2,\
    pass,\
    t:none,\
    nolog,\
    noauditlog,\
    ver:'OWASP_CRS/3.3.9',\
    chain"
    SecRule ARGS:page "@streq config" \
        "t:none,\
        chain"
        SecRule &ARGS:page "@eq 1" \
            "t:none,\
            chain"
            SecRule REQUEST_COOKIES:/S?DW[a-f0-9]+/ "@rx ^[%a-zA-Z0-9_-]+" \
                "t:none,\
                ctl:ruleRemoveById=951240,\
                ctl:ruleRemoveById=953110"


# End [ Admin Area ]

SecMarker "END-DOKUWIKI-ADMIN"

SecMarker "END-DOKUWIKI"
