├── .gitattributes ├── .github └── workflows │ ├── main.yml │ └── tests.yml ├── .gitignore ├── BUILD.md ├── CHANGES ├── LICENSE ├── Makefile.am ├── NOTICE ├── README.TXT ├── README_WINDOWS.TXT ├── alp2 ├── Makefile.am ├── alp2.c ├── alp2.h ├── alp2_pp.c └── alp2_pp.h ├── apache2 ├── Makefile.am ├── Makefile.win ├── acmp.c ├── acmp.h ├── ag_mdb │ ├── ag_mdb.cpp │ ├── ag_mdb_external.h │ ├── ag_mdb_internal.h │ ├── murmur3.c │ └── murmur3.h ├── apache2.h ├── apache2_config.c ├── apache2_io.c ├── apache2_util.c ├── libinjection │ ├── COPYING.txt │ ├── libinjection.h │ ├── libinjection_html5.c │ ├── libinjection_html5.h │ ├── libinjection_sqli.c │ ├── libinjection_sqli.h │ ├── libinjection_sqli_data.h │ ├── libinjection_xss.c │ └── libinjection_xss.h ├── mod_security2.c ├── mod_security2_config.hw ├── modsecurity.c ├── modsecurity.h ├── modsecurity_config.h ├── modules.mk ├── msc_crypt.c ├── msc_crypt.h ├── msc_geo.c ├── msc_geo.h ├── msc_gsb.c ├── msc_gsb.h ├── msc_json.c ├── msc_json.h ├── msc_logging.c ├── msc_logging.h ├── msc_logging_json.h ├── msc_lua.c ├── msc_lua.h ├── msc_multipart.c ├── msc_multipart.h ├── msc_parsers.c ├── msc_parsers.h ├── msc_pcre.c ├── msc_pcre.h ├── msc_release.c ├── msc_release.h ├── msc_remote_rules.c ├── msc_remote_rules.h ├── msc_reqbody.c ├── msc_status_engine.c ├── msc_status_engine.h ├── msc_tree.c ├── msc_tree.h ├── msc_unicode.c ├── msc_unicode.h ├── msc_util.c ├── msc_util.h ├── msc_xml.c ├── msc_xml.h ├── persist_dbm.c ├── persist_dbm.h ├── re.c ├── re.h ├── re_actions.c ├── re_operators.c ├── re_tfns.c ├── re_variables.c ├── utf8tables.h ├── waf_lock │ ├── waf_lock.cpp │ ├── waf_lock_external.h │ └── waf_lock_internal.h └── waf_logging │ ├── waf_log_util.cc │ └── waf_log_util.h ├── authors.txt ├── autogen.sh ├── build ├── apxs-wrapper.in ├── find_apr.m4 ├── find_apu.m4 ├── find_curl.m4 ├── find_lua.m4 ├── find_pcre.m4 ├── find_ssdeep.m4 ├── find_xml.m4 └── find_yajl.m4 ├── configure.ac ├── doc ├── Makefile.am ├── README.txt ├── doxygen-apache.in ├── doxygen-iis.in ├── doxygen-logo.png ├── doxygen-nginx.in └── doxygen-standalone.in ├── docker-compose.yaml ├── docker └── Dockerfile ├── ext ├── Makefile.am ├── README ├── mod_op_strstr.c ├── mod_reqbody_example.c ├── mod_tfn_reverse.c └── mod_var_remote_addr_port.c ├── iis ├── Makefile.win ├── ModSecurity.xml ├── ModSecurityIIS.sln ├── ModSecurityIIS.vcxproj ├── ModSecurityIIS.vcxproj.filters ├── build_dependencies.bat ├── build_modsecurity.bat ├── build_msi.bat ├── build_release.bat ├── build_release_amd64.bat ├── curl-ca-bundle.crt ├── dependencies │ ├── build_apache.bat │ ├── build_cmake.bat │ ├── build_curl.bat │ ├── build_libxml2.bat │ ├── build_lua.bat │ ├── build_pcre.bat │ ├── build_ssdeep.bat │ ├── build_yajl.bat │ ├── build_zlib.bat │ └── howto.txt ├── dependencies_bin │ ├── cmake-3.8.2-win32-x86.zip │ ├── curl-7.54.1.zip │ ├── httpd-2.4.27-win32-VC11.zip │ ├── httpd-2.4.27-win64-VC11.zip │ ├── httpd-2.4.27.tar.gz │ ├── libxml2-2.9.4.tar.gz │ ├── lua-5.3.4.tar.gz │ ├── pcre-8.40.zip │ ├── ssdeep-2.13.tar.gz │ ├── ssdeep-2.13.zip │ ├── yajl-2.1.0.zip │ └── zlib-1.2.11.tar.gz ├── download_files.bat ├── getModSecurityPkgs.ps1 ├── installer.wxs ├── main.cpp ├── mlogc.vcxproj ├── mlogc.vcxproj.filters ├── moduleconfig.cpp ├── moduleconfig.h ├── mymodule.cpp ├── mymodule.def ├── mymodule.h ├── mymodulefactory.h └── wix │ ├── EULA.rtf │ ├── Microsoft_VC110_CRT_x64.msm │ ├── Microsoft_VC110_CRT_x86.msm │ ├── Microsoft_VC120_CRT_x64.msm │ ├── Microsoft_VC120_CRT_x86.msm │ ├── README.TXT │ ├── banner.jpg │ ├── dialog.jpg │ ├── list_dependencies.bat │ ├── modsecurity.conf │ └── modsecurity_iis.conf ├── mlogc ├── INSTALL ├── Makefile.am ├── Makefile.win ├── mlogc-batch-load.pl.in ├── mlogc-default.conf └── mlogc.c ├── modsecurity.conf-recommended ├── nginx ├── TODO └── modsecurity │ ├── apr_bucket_nginx.c │ ├── apr_bucket_nginx.h │ ├── config.in │ ├── ngx_http_modsecurity.c │ ├── ngx_http_modsecurity_config_cache.c │ └── ngx_http_modsecurity_config_cache.h ├── stamp-h1 ├── standalone ├── Makefile.am ├── api.c ├── api.h ├── buckets.c ├── config.c ├── filters.c ├── hooks.c ├── hooks.h ├── main.cpp ├── modules.mk ├── regex.c ├── server.c ├── standalone.sln ├── standalone.vcxproj ├── standalone.vcxproj.filters └── standalone.vcxproj.user ├── tests ├── CRS_Tests_modsec_dbg.py ├── Makefile.am ├── Parse_test_res.py ├── action │ └── .empty ├── config.py ├── csv_rx-pm.pl.in ├── gen_rx-pm.pl.in ├── msc_test.c ├── op │ ├── beginsWith.t │ ├── contains.t │ ├── containsWord.t │ ├── detectSQLi.t │ ├── detectXSS.t │ ├── endsWith.t │ ├── eq.t │ ├── ge.t │ ├── geoLookup.t │ ├── gt.t │ ├── inspectFile.t │ ├── ipMatch.t │ ├── le.t │ ├── lt.t │ ├── noMatch.t │ ├── pm.t │ ├── pmFromFile-01.dat │ ├── pmFromFile.t │ ├── rbl.t │ ├── rx.t │ ├── streq.t │ ├── strmatch.t │ ├── unconditionalMatch.t │ ├── validateByteRange.t │ ├── validateDTD.t │ ├── validateSchema.t │ ├── validateUrlEncoding.t │ ├── validateUtf8Encoding.t │ ├── verifyCC.t │ └── within.t ├── regression │ ├── action │ │ ├── 00-disruptive-actions.t │ │ ├── 00-meta.t │ │ ├── 00-misc.t │ │ ├── 00-transformations.t │ │ ├── 10-append-prepend.t │ │ ├── 10-ctl.t │ │ ├── 10-detectiononly-actions.t │ │ └── 10-logging.t │ ├── config │ │ ├── 00-load-modsec.t │ │ ├── 10-audit-directives.t │ │ ├── 10-debug-directives.t │ │ ├── 10-misc-directives.t │ │ ├── 10-request-directives.t │ │ ├── 10-response-directives.t │ │ └── 20-chroot.t │ ├── misc │ │ ├── 00-multipart-parser.t │ │ ├── 00-phases.t │ │ ├── 10-pcre.t │ │ ├── 10-tfn-cache.t │ │ ├── 20-status-engine.t │ │ ├── 25-libinjection.t │ │ ├── 30-fuzzyHash.t │ │ ├── 40-secRemoteRules.t.in │ │ ├── 50-ipmatchfromfile-external.t.in │ │ └── 60-pmfromfile-external.t.in │ ├── nginx │ │ └── conf │ │ │ ├── SoapEnvelope-bad.dtd │ │ │ ├── SoapEnvelope-bad.xsd │ │ │ ├── SoapEnvelope.dtd │ │ │ ├── SoapEnvelope.xsd │ │ │ ├── empty.conf │ │ │ ├── match.lua │ │ │ ├── nginx.conf.template │ │ │ ├── ssdeep.txt │ │ │ └── test.lua │ ├── rule │ │ ├── 00-basics.t │ │ ├── 00-inheritance.t │ │ ├── 00-script.t │ │ ├── 10-xml.t │ │ ├── 15-json.t │ │ └── 20-exceptions.t │ ├── server_root │ │ ├── conf │ │ │ ├── SoapEnvelope-bad.dtd │ │ │ ├── SoapEnvelope-bad.xsd │ │ │ ├── SoapEnvelope.dtd │ │ │ ├── SoapEnvelope.xsd │ │ │ ├── httpd.conf.in │ │ │ ├── match.lua │ │ │ ├── ssdeep.txt │ │ │ └── test.lua │ │ ├── data │ │ │ ├── .empty │ │ │ └── ip.dir │ │ ├── htdocs │ │ │ ├── 8k.txt │ │ │ ├── index.html │ │ │ ├── test.pdf │ │ │ ├── test.txt │ │ │ └── test2.txt │ │ ├── logs │ │ │ ├── audit │ │ │ │ └── .empty │ │ │ └── subdir │ │ │ │ └── .empty │ │ ├── tmp │ │ │ └── .empty │ │ └── upload │ │ │ └── .empty │ └── target │ │ └── 00-targets.t ├── run-regression-tests-nginx.pl ├── run-regression-tests.pl.in ├── run-unit-tests.pl.in └── tfn │ ├── base64Decode.t │ ├── base64Encode.t │ ├── compressWhitespace.t │ ├── cssDecode.t │ ├── escapeSeqDecode.t │ ├── hexDecode.t │ ├── hexEncode.t │ ├── htmlEntityDecode.t │ ├── jsDecode.t │ ├── length.t │ ├── lowercase.t │ ├── md5.t │ ├── normalisePath.t │ ├── normalisePathWin.t │ ├── parityEven7bit.t │ ├── parityOdd7bit.t │ ├── parityZero7bit.t │ ├── removeNulls.t │ ├── removeWhitespace.t │ ├── replaceComments.t │ ├── replaceNulls.t │ ├── sha1.t │ ├── trim.t │ ├── trimLeft.t │ ├── trimRight.t │ ├── urlDecode.t │ ├── urlDecodeUni.t │ ├── urlEncode.t │ └── utf8toUnicode.t ├── tools ├── Makefile.am ├── README ├── parse_modsec.pl ├── rules-updater-example.conf └── rules-updater.pl.in ├── unicode.mapping └── validator ├── Makefile.am └── main.c /.gitattributes: -------------------------------------------------------------------------------- 1 | # Build 2 | *.sh text eol=lf 3 | *.ac text eol=lf 4 | *.am text eol=lf 5 | Makefile text eol=lf 6 | CMakelists.txt text eol=lf 7 | 8 | # Code 9 | *.c text eol=lf 10 | *.h text eol=lf 11 | *.cpp text eol=lf 12 | *.cc text eol=lf 13 | *.hh text eol=lf -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | # Workflow token permissions. Needed for az acr login. 4 | permissions: 5 | id-token: write 6 | contents: read 7 | 8 | # Controls when the workflow will run 9 | on: 10 | # Triggers the workflow on push or pull request events but only for the waf_nginx branch 11 | push: 12 | branches: [ waf_nginx ] 13 | pull_request: 14 | branches: [ waf_nginx ] 15 | 16 | # Allows you to run this workflow manually from the Actions tab 17 | workflow_dispatch: 18 | 19 | jobs: 20 | build: 21 | runs-on: ubuntu-latest 22 | environment: ci 23 | 24 | steps: 25 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 26 | - uses: actions/checkout@v2 27 | 28 | # Logs into Azure. Can't use other alternatives because they lack security features. 29 | - name: Azure Login 30 | uses: Azure/login@v2 31 | with: 32 | client-id: ${{ secrets.AZURE_CLIENT_ID }} 33 | tenant-id: ${{ secrets.AZURE_TENANT_ID }} 34 | subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} 35 | 36 | # Pull docker image and compile the code. 37 | - name: Pull Image and Compile 38 | env: 39 | REGISTRY_NAME: ${{ secrets.REGISTRY_NAME }} 40 | run: | 41 | az acr login --name $REGISTRY_NAME 42 | 43 | docker pull ${REGISTRY_NAME}.azurecr.io/modsecurity:latest 44 | docker-compose run --rm autoconf 45 | docker-compose run --rm configure 46 | docker-compose run --rm make 47 | docker logout ${REGISTRY_NAME}.azurecr.io 48 | 49 | # Reset credentials stored by az acr login if the previous step failed midway. 50 | - name: Cleanup on failure 51 | if: failure() 52 | env: 53 | REGISTRY_NAME: ${{ secrets.REGISTRY_NAME }} 54 | run: | 55 | docker logout ${REGISTRY_NAME}.azurecr.io 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | *.swp 3 | *.stackdump 4 | *.obj 5 | *.tlog 6 | *.log 7 | *.pdb 8 | *.dll 9 | *.exp 10 | *.ilk 11 | *.lib 12 | *.exe 13 | *.suo 14 | *.sdf 15 | *.opensdf 16 | *.so 17 | *.o 18 | *.Po 19 | *.Plo 20 | *.lo 21 | *.un~ 22 | 23 | # Windows artifacts 24 | iis/release/* 25 | iis/dependencies/build_dir/* 26 | iis/dependencies/release_files/* 27 | apache2/.deps/* 28 | apache2/.libs/* 29 | apache2/libinjection/.deps/* 30 | apache2/libinjection/.libs/* 31 | iis/.vs/* 32 | iis/ModSecurityIIS.dll.Manifest 33 | iis/*.obj 34 | 35 | # Linux build artifacts 36 | Makefile 37 | Makefile.in 38 | aclocal.m4 39 | alp2/Makefile.in 40 | apache2/.dirstamp 41 | apache2/Makefile 42 | apache2/Makefile.in 43 | apache2/ag_mdb/.deps/ 44 | apache2/ag_mdb/.dirstamp 45 | apache2/libinjection/.dirstamp 46 | apache2/mod_security2.la 47 | apache2/modsecurity_config_auto.h 48 | apache2/modsecurity_config_auto.h.in 49 | apache2/stamp-h1 50 | apache2/waf_lock/.deps/ 51 | apache2/waf_lock/.dirstamp 52 | apache2/waf_logging/.deps/ 53 | apache2/waf_logging/.dirstamp 54 | apache2/waf_logging/waf_format.pb.h 55 | 56 | apache2/waf_logging/waf_format.pb.cc 57 | autom4te.cache/ 58 | build/apxs-wrapper 59 | build/ar-lib 60 | build/config.guess 61 | build/config.sub 62 | build/depcomp 63 | build/install-sh 64 | build/libtool.m4 65 | build/ltmain.sh 66 | build/ltoptions.m4 67 | build/ltsugar.m4 68 | build/ltversion.m4 69 | build/lt~obsolete.m4 70 | build/missing 71 | build/test-driver 72 | build/compile 73 | config.status 74 | configure 75 | doc/Makefile.in 76 | ext/Makefile.in 77 | libtool 78 | mlogc/Makefile.in 79 | standalone/.libs/ 80 | standalone/Makefile 81 | standalone/Makefile.in 82 | standalone/standalone.la 83 | standalone/.deps/ 84 | standalone/.dirstamp 85 | tests/Makefile 86 | tests/Makefile.in 87 | tests/csv_rx-pm.pl 88 | tests/gen_rx-pm.pl 89 | tests/regression/server_root/conf/httpd.conf 90 | tests/run-regression-tests.pl 91 | tests/run-unit-tests.pl 92 | tools/Makefile 93 | tools/Makefile.in 94 | tools/rules-updater.pl 95 | validator/validator 96 | nginx/modsecurity/config 97 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | ACLOCAL_AMFLAGS = -I build 2 | SUBDIRS = @TOPLEVEL_SUBDIRS@ tests 3 | 4 | CLEANFILES = 5 | MAINTAINERCLEANFILES = 6 | 7 | CLEANFILES += tests/regression/server_root/conf/*.t_*.conf \ 8 | tests/regression/server_root/logs/*.log 9 | 10 | MAINTAINERCLEANFILES += $(CLEANFILES) \ 11 | aclocal.m4 \ 12 | alp2/Makefile.in \ 13 | apache2/Makefile.in \ 14 | build/config.guess \ 15 | build/config.sub \ 16 | build/depcomp \ 17 | build/libtool.m4 \ 18 | build/ltmain.sh \ 19 | build/lt~obsolete.m4 \ 20 | build/ltoptions.m4 \ 21 | build/ltsugar.m4 \ 22 | build/ltversion.m4 \ 23 | build/missing \ 24 | config.log \ 25 | config.status \ 26 | configure \ 27 | ext/Makefile.in \ 28 | Makefile \ 29 | Makefile.in \ 30 | mlogc/Makefile.in \ 31 | modsecurity_config_auto.h.in~ 32 | 33 | test: check 34 | 35 | test-regression: 36 | (cd tests && $(MAKE) test-regression) 37 | 38 | test-regression-nginx: 39 | (cd tests && $(MAKE) test-regression-nginx) 40 | 41 | 42 | cppcheck: 43 | cppcheck . --enable=all --force 2>&1 | sed 's/^/warning: /g' 1>&2; 44 | 45 | check-coding-style: 46 | for i in `(find . -iname "*.c" ; find . -iname "*.h")`; \ 47 | do echo $$i...; \ 48 | vera++ -rule L004 -param max-line-length=80 $$i 2>&1 | sed 's/^/warning: /g' 1>&2; \ 49 | vera++ -rule L001 $$i 2>&1 | sed 's/^/warning: /g' 1>&2; \ 50 | done; 51 | 52 | .PHONY: test 53 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | ModSecurity (www.modsecurity.org) 2 |     Copyright [2004-2013] Trustwave Holdings, Inc 3 | 4 |     This product includes software developed at 5 |     Trustwave Holdings, Inc (http://www.trustwave.com/). 6 | -------------------------------------------------------------------------------- /alp2/Makefile.am: -------------------------------------------------------------------------------- 1 | lib_LTLIBRARIES = libalp2.la 2 | 3 | include_HEADERS = alp2.h \ 4 | alp2_pp.h 5 | 6 | libalp2_la_SOURCES = alp2.c \ 7 | alp2_pp.c 8 | 9 | libalp2_la_CFLAGS = @APR_CFLAGS@ \ 10 | @APU_CFLAGS@ 11 | 12 | libalp2_la_LDFLAGS = @APR_LDFLAGS@ \ 13 | @APU_LDFLAGS@ 14 | -------------------------------------------------------------------------------- /apache2/ag_mdb/murmur3.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) Microsoft Corporation. All rights reserved. 2 | Licensed under the MIT License. */ 3 | //----------------------------------------------------------------------------- 4 | // MurmurHash3 was written by Austin Appleby, and is placed in the 5 | // public domain. The author hereby disclaims copyright to this source 6 | // code. 7 | 8 | #ifndef _MURMURHASH3_H_ 9 | #define _MURMURHASH3_H_ 10 | 11 | #include 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | //----------------------------------------------------------------------------- 18 | 19 | void MurmurHash3_x86_32 (const void *key, int len, uint32_t seed, void *out); 20 | 21 | void MurmurHash3_x86_128(const void *key, int len, uint32_t seed, void *out); 22 | 23 | void MurmurHash3_x64_128(const void *key, int len, uint32_t seed, void *out); 24 | 25 | //----------------------------------------------------------------------------- 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif // _MURMURHASH3_H_ 32 | -------------------------------------------------------------------------------- /apache2/libinjection/COPYING.txt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012, 2013 3 | * Nick Galbreath -- nickg [at] client9 [dot] com 4 | * http://www.client9.com/projects/libinjection/ 5 | * 6 | * All rights reserved. 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions are 10 | * met: 11 | * 12 | * Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 15 | * Redistributions in binary form must reproduce the above copyright 16 | * notice, this list of conditions and the following disclaimer in the 17 | * documentation and/or other materials provided with the distribution. 18 | * 19 | * Neither the name of libinjection nor the names of its 20 | * contributors may be used to endorse or promote products derived from 21 | * this software without specific prior written permission. 22 | * 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 29 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 30 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 31 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 33 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 | * 35 | * This is the standard "new" BSD license: 36 | * http://www.opensource.org/licenses/bsd-license.php 37 | */ 38 | -------------------------------------------------------------------------------- /apache2/libinjection/libinjection.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012-2016 Nick Galbreath 3 | * nickg@client9.com 4 | * BSD License -- see COPYING.txt for details 5 | * 6 | * https://libinjection.client9.com/ 7 | * 8 | */ 9 | 10 | #ifndef LIBINJECTION_H 11 | #define LIBINJECTION_H 12 | 13 | #ifdef __cplusplus 14 | # define LIBINJECTION_BEGIN_DECLS extern "C" { 15 | # define LIBINJECTION_END_DECLS } 16 | #else 17 | # define LIBINJECTION_BEGIN_DECLS 18 | # define LIBINJECTION_END_DECLS 19 | #endif 20 | 21 | LIBINJECTION_BEGIN_DECLS 22 | 23 | /* 24 | * Pull in size_t 25 | */ 26 | #include 27 | 28 | /* 29 | * Version info. 30 | * 31 | * This is moved into a function to allow SWIG and other auto-generated 32 | * binding to not be modified during minor release changes. We change 33 | * change the version number in the c source file, and not regenerated 34 | * the binding 35 | * 36 | * See python's normalized version 37 | * http://www.python.org/dev/peps/pep-0386/#normalizedversion 38 | */ 39 | const char* libinjection_version(void); 40 | 41 | /** 42 | * Simple API for SQLi detection - returns a SQLi fingerprint or NULL 43 | * is benign input 44 | * 45 | * \param[in] s input string, may contain nulls, does not need to be null-terminated 46 | * \param[in] slen input string length 47 | * \param[out] fingerprint buffer of 8+ characters. c-string, 48 | * \return 1 if SQLi, 0 if benign. fingerprint will be set or set to empty string. 49 | */ 50 | int libinjection_sqli(const char* s, size_t slen, char fingerprint[]); 51 | 52 | /** ALPHA version of xss detector. 53 | * 54 | * NOT DONE. 55 | * 56 | * \param[in] s input string, may contain nulls, does not need to be null-terminated 57 | * \param[in] slen input string length 58 | * \return 1 if XSS found, 0 if benign 59 | * 60 | */ 61 | int libinjection_xss(const char* s, size_t slen); 62 | 63 | LIBINJECTION_END_DECLS 64 | 65 | #endif /* LIBINJECTION_H */ 66 | -------------------------------------------------------------------------------- /apache2/libinjection/libinjection_html5.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBINJECTION_HTML5 2 | #define LIBINJECTION_HTML5 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | /* pull in size_t */ 9 | 10 | #include 11 | 12 | enum html5_type { 13 | DATA_TEXT 14 | , TAG_NAME_OPEN 15 | , TAG_NAME_CLOSE 16 | , TAG_NAME_SELFCLOSE 17 | , TAG_DATA 18 | , TAG_CLOSE 19 | , ATTR_NAME 20 | , ATTR_VALUE 21 | , TAG_COMMENT 22 | , DOCTYPE 23 | }; 24 | 25 | enum html5_flags { 26 | DATA_STATE 27 | , VALUE_NO_QUOTE 28 | , VALUE_SINGLE_QUOTE 29 | , VALUE_DOUBLE_QUOTE 30 | , VALUE_BACK_QUOTE 31 | }; 32 | 33 | struct h5_state; 34 | typedef int (*ptr_html5_state)(struct h5_state*); 35 | 36 | typedef struct h5_state { 37 | const char* s; 38 | size_t len; 39 | size_t pos; 40 | int is_close; 41 | ptr_html5_state state; 42 | const char* token_start; 43 | size_t token_len; 44 | enum html5_type token_type; 45 | } h5_state_t; 46 | 47 | 48 | void libinjection_h5_init(h5_state_t* hs, const char* s, size_t len, enum html5_flags); 49 | int libinjection_h5_next(h5_state_t* hs); 50 | 51 | #ifdef __cplusplus 52 | } 53 | #endif 54 | #endif 55 | -------------------------------------------------------------------------------- /apache2/libinjection/libinjection_xss.h: -------------------------------------------------------------------------------- 1 | #ifndef LIBINJECTION_XSS 2 | #define LIBINJECTION_XSS 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | /** 9 | * HEY THIS ISN'T DONE 10 | */ 11 | 12 | /* pull in size_t */ 13 | 14 | #include 15 | 16 | int libinjection_is_xss(const char* s, size_t len, int flags); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | #endif 22 | -------------------------------------------------------------------------------- /apache2/mod_security2_config.hw: -------------------------------------------------------------------------------- 1 | /* This file is left empty for building on Windows. */ 2 | -------------------------------------------------------------------------------- /apache2/modsecurity_config.h: -------------------------------------------------------------------------------- 1 | /* Some APR files define PACKAGE* constants, which may conflict 2 | * so this is here to prevent that by removing them. 3 | */ 4 | 5 | #ifndef WIN32 6 | 7 | /* Undefine all these so there are no conflicts */ 8 | #undef PACKAGE 9 | #undef PACKAGE_BUGREPORT 10 | #undef PACKAGE_NAME 11 | #undef PACKAGE_STRING 12 | #undef PACKAGE_TARNAME 13 | #undef PACKAGE_URL 14 | #undef PACKAGE_VERSION 15 | 16 | /* Include the real autoconf header */ 17 | #include "modsecurity_config_auto.h" 18 | 19 | /* Undefine all these (again) so there are no conflicts */ 20 | #undef PACKAGE 21 | #undef PACKAGE_BUGREPORT 22 | #undef PACKAGE_NAME 23 | #undef PACKAGE_STRING 24 | #undef PACKAGE_TARNAME 25 | #undef PACKAGE_URL 26 | #undef PACKAGE_VERSION 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /apache2/modules.mk: -------------------------------------------------------------------------------- 1 | MOD_SECURITY2 = mod_security2 apache2_config apache2_io apache2_util \ 2 | re re_operators re_actions re_tfns re_variables msc_json \ 3 | msc_logging msc_xml msc_multipart modsecurity msc_parsers msc_util msc_pcre \ 4 | persist_dbm msc_reqbody pdf_protect msc_geo msc_gsb msc_crypt msc_tree msc_unicode acmp msc_lua 5 | 6 | H = re.h modsecurity.h msc_logging.h msc_multipart.h msc_parsers.h msc_json.h \ 7 | msc_pcre.h msc_util.h msc_xml.h persist_dbm.h apache2.h pdf_protect.h \ 8 | msc_geo.h msc_gsb.h msc_crypt.h msc_tree.h msc_unicode.h acmp.h utf8tables.h msc_lua.h 9 | 10 | ${MOD_SECURITY2:=.slo}: ${H} 11 | ${MOD_SECURITY2:=.lo}: ${H} 12 | ${MOD_SECURITY2:=.o}: ${H} 13 | 14 | mod_security2.la: ${MOD_SECURITY2:=.slo} 15 | $(SH_LINK) -rpath $(libexecdir) -module -avoid-version ${MOD_SECURITY2:=.lo} 16 | 17 | DISTCLEAN_TARGETS = modules.mk 18 | 19 | shared = mod_security2.la 20 | -------------------------------------------------------------------------------- /apache2/msc_crypt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _MSC_CRYPT_H_ 16 | #define _MSC_CRYPT_H_ 17 | 18 | #include "modsecurity.h" 19 | #include 20 | #include 21 | 22 | #define HMAC_PAD_SIZE 65 23 | #define HASH_ONLY 0 24 | #define FULL_LINK 1 25 | 26 | #ifndef INT32_MAX 27 | #define INT32_MAX (2147483647) 28 | #endif 29 | 30 | char DSOLOCAL *hmac(modsec_rec *msr, const char *key, int key_len, 31 | unsigned char *msg, int msglen); 32 | char DSOLOCAL *do_hash_link(modsec_rec *msr, char *link, 33 | int type); 34 | char DSOLOCAL *getkey(apr_pool_t *mp); 35 | 36 | int DSOLOCAL init_response_body_html_parser(modsec_rec *msr); 37 | int DSOLOCAL hash_response_body_links(modsec_rec *msr); 38 | int DSOLOCAL inject_hashed_response_body(modsec_rec *msr, int elts); 39 | int DSOLOCAL do_hash_method(modsec_rec *msr, char *link, int type); 40 | int DSOLOCAL modify_response_header(modsec_rec *msr); 41 | char DSOLOCAL *normalize_path(modsec_rec *msr, char *input); 42 | #endif 43 | -------------------------------------------------------------------------------- /apache2/msc_geo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _MSC_GEO_H_ 16 | #define _MSC_GEO_H_ 17 | 18 | #define GEO_STRUCT_INFO_MAX_SIZE 20 19 | #define GEO_DB_INFO_MAX_SIZE 100 20 | #define GEO_COUNTRY_OFFSET 0xffff00 21 | #define GEO_MAX_RECORD_LEN 4 22 | #define GEO_COUNTRY_UNKNOWN "Unknown" 23 | #define GEO_CITY_UNKNOWN "Unknown" 24 | #define GEO_CITY_RECORD_LEN 50 25 | #define GEO_COUNTRY_DATABASE 1 26 | #define GEO_CITY_DATABASE_0 6 27 | #define GEO_CITY_DATABASE_1 2 28 | #define GEO_COUNTRY_LAST 250 29 | #define GEO_SEGMENT_RECORD_LENGTH 3 30 | #define GEO_STATE_BEGIN_REV0 16700000 31 | #define GEO_STATE_BEGIN_REV1 16000000 32 | #define GEO_COUNTRY_BEGIN 16776960 33 | 34 | 35 | typedef struct geo_rec geo_rec; 36 | typedef struct geo_db geo_db; 37 | 38 | #include 39 | #include "modsecurity.h" 40 | 41 | /* Structures */ 42 | 43 | struct geo_rec { 44 | const char *country_code; 45 | const char *country_code3; 46 | const char *country_name; 47 | const char *country_continent; 48 | const char *region; 49 | const char *city; 50 | const char *postal_code; 51 | float latitude; 52 | float longitude; 53 | int dma_code; 54 | int area_code; 55 | }; 56 | 57 | struct geo_db { 58 | apr_file_t *db; 59 | const char *dbfn; 60 | int dbtype; 61 | unsigned int ctry_offset; 62 | }; 63 | 64 | /* Functions */ 65 | 66 | int DSOLOCAL geo_init(directory_config *dcfg, const char *dbfn, char **error_msg); 67 | 68 | int DSOLOCAL geo_lookup(modsec_rec *msr, geo_rec *rec, const char *target, char **error_msg); 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /apache2/msc_gsb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _MSC_GSB_H_ 16 | #define _MSC_GSB_H_ 17 | 18 | typedef struct gsb_db gsb_db; 19 | 20 | #include 21 | #include "modsecurity.h" 22 | #include "apr_hash.h" 23 | 24 | struct gsb_db { 25 | apr_file_t *db; 26 | const char *dbfn; 27 | apr_hash_t *gsb_table; 28 | }; 29 | 30 | int DSOLOCAL gsb_db_init(directory_config *dcfg, const char *dbfn, char **error_msg); 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /apache2/msc_json.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2011 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _MSC_JSON_H_ 16 | #define _MSC_JSON_H_ 17 | #ifdef WITH_YAJL 18 | 19 | typedef struct json_data json_data; 20 | 21 | 22 | #include "modsecurity.h" 23 | 24 | #include 25 | //#ifdef WITH_YAJL 26 | //#else 27 | 28 | 29 | #include "modsecurity.h" 30 | 31 | /* Structures */ 32 | struct json_data { 33 | /* yajl configuration and parser state */ 34 | yajl_handle handle; 35 | yajl_status status; 36 | 37 | /* error reporting and JSON array flag */ 38 | unsigned char *yajl_error; 39 | 40 | /* prefix is used to create data hierarchy (i.e., 'parent.child.value') */ 41 | unsigned char *prefix; 42 | unsigned char *current_key; 43 | }; 44 | 45 | /* Functions */ 46 | 47 | int DSOLOCAL json_init(modsec_rec *msr, char **error_msg); 48 | 49 | int DSOLOCAL json_process(modsec_rec *msr, const char *buf, 50 | unsigned int size, char **error_msg); 51 | 52 | int DSOLOCAL json_complete(modsec_rec *msr, char **error_msg); 53 | 54 | apr_status_t DSOLOCAL json_cleanup(modsec_rec *msr); 55 | 56 | int DSOLOCAL json_process_chunk(modsec_rec *msr, const char *buf, 57 | unsigned int size, char **error_msg); 58 | 59 | void DSOLOCAL json_free_error(modsec_rec *msr, char **error_msg); 60 | 61 | #endif 62 | #endif 63 | -------------------------------------------------------------------------------- /apache2/msc_logging.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _MSC_LOGGING_H_ 16 | #define _MSC_LOGGING_H_ 17 | 18 | #define AUDITLOG_OFF 0 19 | #define AUDITLOG_ON 1 20 | #define AUDITLOG_RELEVANT 2 21 | 22 | #define AUDITLOG_SERIAL 0 23 | #define AUDITLOG_CONCURRENT 1 24 | 25 | #ifdef WITH_YAJL 26 | #define AUDITLOGFORMAT_JSON 0 27 | #define AUDITLOGFORMAT_NATIVE 1 28 | #endif 29 | 30 | #define AUDITLOG_PART_FIRST 'A' 31 | #define AUDITLOG_PART_HEADER 'A' 32 | #define AUDITLOG_PART_REQUEST_HEADERS 'B' 33 | #define AUDITLOG_PART_REQUEST_BODY 'C' 34 | #define AUDITLOG_PART_RESPONSE_HEADERS 'D' 35 | #define AUDITLOG_PART_RESPONSE_BODY 'E' 36 | #define AUDITLOG_PART_A_RESPONSE_HEADERS 'F' 37 | #define AUDITLOG_PART_A_RESPONSE_BODY 'G' 38 | #define AUDITLOG_PART_TRAILER 'H' 39 | #define AUDITLOG_PART_FAKE_REQUEST_BODY 'I' 40 | #define AUDITLOG_PART_UPLOADS 'J' 41 | #define AUDITLOG_PART_MATCHEDRULES 'K' 42 | #define AUDITLOG_PART_LAST 'K' 43 | #define AUDITLOG_PART_ENDMARKER 'Z' 44 | 45 | #include "modsecurity.h" 46 | #include "apr_pools.h" 47 | 48 | int DSOLOCAL is_valid_parts_specification(char *p); 49 | 50 | char DSOLOCAL *construct_log_vcombinedus_limited(modsec_rec *msr, int _limit, int *was_limited); 51 | 52 | void DSOLOCAL sec_audit_logger(modsec_rec *msr); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /apache2/msc_logging_json.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #define yajl_string(g, s) yajl_gen_string(g, (const unsigned char *)s, strlen(s)) 6 | 7 | #define yajl_kv_null(g, k) yajl_string(g, k); yajl_gen_null(g) 8 | 9 | #define yajl_kv_int(g, k, v) yajl_string(g, k); yajl_gen_integer(g, v) 10 | 11 | #define yajl_kv_string(g, k, v) yajl_string(g, k); yajl_string(g, v) 12 | 13 | #define yajl_kv_bool(g, k, v) yajl_string(g, k); yajl_gen_bool(g, v) 14 | -------------------------------------------------------------------------------- /apache2/msc_lua.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #if defined(WITH_LUA) 16 | 17 | #ifndef _MSC_LUA_H_ 18 | #define _MSC_LUA_H_ 19 | 20 | typedef struct msc_script msc_script; 21 | typedef struct msc_script_part msc_script_part; 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include "apr_general.h" 28 | #include "apr_tables.h" 29 | #include "modsecurity.h" 30 | 31 | struct msc_script { 32 | const char *name; 33 | apr_array_header_t *parts; 34 | }; 35 | 36 | struct msc_script_part { 37 | const void *data; 38 | size_t len; 39 | }; 40 | 41 | char DSOLOCAL *lua_compile(msc_script **script, const char *filename, apr_pool_t *pool); 42 | 43 | int DSOLOCAL lua_execute(msc_script *script, char *param, modsec_rec *msr, msre_rule *rule, char **error_msg); 44 | 45 | apr_status_t DSOLOCAL msre_action_setvar_execute(modsec_rec *r, apr_pool_t *, msre_rule *, char *, char *); 46 | 47 | #endif 48 | 49 | #endif /* WITH_LUA */ 50 | -------------------------------------------------------------------------------- /apache2/msc_parsers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _MSC_PARSERS_H_ 16 | #define _MSC_PARSERS_H_ 17 | 18 | #include "modsecurity.h" 19 | 20 | int DSOLOCAL parse_cookies_v0(modsec_rec *msr, char *_cookie_header, apr_table_t *cookies, 21 | const char *delim); 22 | 23 | int DSOLOCAL parse_cookies_v1(modsec_rec *msr, char *_cookie_header, apr_table_t *cookies); 24 | 25 | int DSOLOCAL parse_arguments(modsec_rec *msr, const char *s, apr_size_t inputlength, 26 | int argument_separator, const char *origin, apr_table_t *arguments, int *invalid_count); 27 | 28 | void DSOLOCAL add_argument(modsec_rec *msr, apr_table_t *arguments, msc_arg *arg); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /apache2/msc_pcre.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _MSC_PCRE_H_ 16 | #define _MSC_PCRE_H_ 17 | 18 | typedef struct msc_regex_t msc_regex_t; 19 | 20 | #include "pcre.h" 21 | 22 | #ifndef PCRE_ERROR_MATCHLIMIT 23 | /* Define for compile, but not valid in this version of PCRE. */ 24 | #define PCRE_ERROR_MATCHLIMIT (-8) 25 | #endif /* PCRE_ERROR_MATCHLIMIT */ 26 | 27 | #ifndef PCRE_ERROR_RECURSIONLIMIT 28 | /* Define for compile, but not valid in this version of PCRE. */ 29 | #define PCRE_ERROR_RECURSIONLIMIT (-21) 30 | #endif /* PCRE_ERROR_RECURSIONLIMIT */ 31 | 32 | #include "apr_general.h" 33 | #include "modsecurity.h" 34 | 35 | struct msc_regex_t { 36 | void *re; 37 | void *pe; 38 | const char *pattern; 39 | }; 40 | 41 | void DSOLOCAL *msc_pregcomp_ex(apr_pool_t *pool, const char *pattern, int options, 42 | const char **_errptr, int *_erroffset, 43 | int match_limit, int match_limit_recursion); 44 | 45 | void DSOLOCAL *msc_pregcomp(apr_pool_t *pool, const char *pattern, int options, 46 | const char **_errptr, int *_erroffset); 47 | 48 | int DSOLOCAL msc_regexec_ex(msc_regex_t *regex, const char *s, 49 | unsigned int slen, int startoffset, int options, 50 | int *ovector, int ovecsize, char **error_msg); 51 | 52 | int DSOLOCAL msc_regexec_capture(msc_regex_t *regex, const char *s, 53 | unsigned int slen, int *ovector, 54 | int ovecsize, char **error_msg); 55 | 56 | int DSOLOCAL msc_regexec(msc_regex_t *regex, const char *s, 57 | unsigned int slen, char **error_msg); 58 | 59 | int DSOLOCAL msc_fullinfo(msc_regex_t *regex, int what, void *where); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /apache2/msc_release.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #include "msc_release.h" 16 | 17 | static const struct modsec_build_type_rec { 18 | char name[12]; /* pads at 16 bytes with val */ 19 | int val; 20 | } modsec_build_type[] = { 21 | { "-dev", 1 }, /* Development build */ 22 | { "-rc", 3 }, /* Release Candidate build */ 23 | { "", 9 }, /* Production build */ 24 | { "-tw", 9 }, /* Truswave Holdings build */ 25 | { "-trunk", 9 } /* Trunk build */ 26 | }; 27 | 28 | int get_modsec_build_type(const char *name) 29 | { 30 | size_t i; 31 | 32 | for (i = 0; i < sizeof(modsec_build_type)/sizeof(modsec_build_type[0]); i++) { 33 | if (strcmp(((name == NULL) ? MODSEC_VERSION_TYPE : name), modsec_build_type[i].name) == 0) { 34 | return modsec_build_type[i].val; 35 | } 36 | } 37 | 38 | return 9; /* so no warning */ 39 | } 40 | -------------------------------------------------------------------------------- /apache2/msc_release.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _MSC_RELEASE_H_ 16 | #define _MSC_RELEASE_H_ 17 | 18 | #include 19 | #include 20 | 21 | /* ENH: Clean this mess up by detecting this is possible */ 22 | #if !(defined(_AIX) || defined(WIN32) || defined(CYGWIN) || defined(NETWARE) || defined(SOLARIS2) || defined(OSF1)) 23 | #define DSOLOCAL __attribute__((visibility("hidden"))) 24 | #else 25 | #define DSOLOCAL 26 | #endif 27 | 28 | #if defined(DEBUG_MEM) 29 | /* Nothing Yet */ 30 | #endif 31 | 32 | /* For GNU C, tell the compiler to check printf like formatters */ 33 | #if (defined(__GNUC__) && !defined(SOLARIS2)) 34 | #define PRINTF_ATTRIBUTE(a,b) __attribute__((format (printf, a, b))) 35 | #else 36 | #define PRINTF_ATTRIBUTE(a,b) 37 | #endif 38 | 39 | #define MODSEC_VERSION_MAJOR "2" 40 | #define MODSEC_VERSION_MINOR "9" 41 | #define MODSEC_VERSION_MAINT "2" 42 | #define MODSEC_VERSION_TYPE "" 43 | #define MODSEC_VERSION_RELEASE "" 44 | 45 | #define MODSEC_VERSION_SUFFIX MODSEC_VERSION_TYPE MODSEC_VERSION_RELEASE 46 | 47 | #define MODSEC_VERSION \ 48 | MODSEC_VERSION_MAJOR "." MODSEC_VERSION_MINOR "." MODSEC_VERSION_MAINT \ 49 | MODSEC_VERSION_SUFFIX 50 | 51 | /* Apache Module Defines */ 52 | #ifdef VERSION_IIS 53 | #define MODSEC_MODULE_NAME "ModSecurity for IIS (STABLE)" 54 | #else 55 | #ifdef VERSION_NGINX 56 | #define MODSEC_MODULE_NAME "ModSecurity for nginx (STABLE)" 57 | #else 58 | #ifdef VERSION_STANDALONE 59 | #define MODSEC_MODULE_NAME "ModSecurity Standalone (STABLE)" 60 | #else 61 | #define MODSEC_MODULE_NAME "ModSecurity for Apache" 62 | #endif 63 | #endif 64 | #endif 65 | #define MODSEC_MODULE_VERSION MODSEC_VERSION 66 | #define MODSEC_MODULE_NAME_FULL MODSEC_MODULE_NAME "/" MODSEC_MODULE_VERSION " (http://www.modsecurity.org/)" 67 | 68 | int DSOLOCAL get_modsec_build_type(const char *name); 69 | 70 | #endif /* _MSC_RELEASE_H_ */ 71 | -------------------------------------------------------------------------------- /apache2/msc_remote_rules.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef MSC_REMOTE_RULES_H 16 | #define MSC_REMOTE_RULES_H 17 | 18 | /* forward declarations */ 19 | typedef struct msc_remote_rules_server msc_remote_rules_server; 20 | struct msc_curl_memory_buffer_t; 21 | 22 | #include "modsecurity.h" 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include "http_core.h" 30 | #include "http_config.h" 31 | 32 | #ifdef WITH_APU_CRYPTO 33 | #include 34 | #endif 35 | 36 | struct msc_remote_rules_server { 37 | directory_config *context; 38 | const char *context_label; 39 | const char *uri; 40 | const char *key; 41 | int amount_of_rules; 42 | int crypto; 43 | }; 44 | 45 | const char *msc_remote_invoke_cmd(const command_rec *cmd, cmd_parms *parms, 46 | void *mconfig, const char *args); 47 | 48 | int msc_remote_download_content(apr_pool_t *mp, const char *uri, const char *key, 49 | struct msc_curl_memory_buffer_t *chunk, char **error_msg); 50 | 51 | #ifdef WITH_APU_CRYPTO 52 | int msc_remote_enc_key_setup(apr_pool_t *pool, 53 | const char *key, 54 | apr_crypto_key_t **apr_key, 55 | apr_crypto_t *f, 56 | unsigned char *salt, 57 | char **error_msg); 58 | 59 | int msc_remote_decrypt(apr_pool_t *pool, 60 | const char *key, 61 | struct msc_curl_memory_buffer_t *chunk, 62 | unsigned char **plain_text, 63 | apr_size_t *plain_text_len, 64 | char **error_msg); 65 | #endif 66 | 67 | int msc_remote_add_rules_from_uri(cmd_parms *orig_parms, 68 | msc_remote_rules_server *remote_rules_server, 69 | char **error_msg); 70 | 71 | int msc_remote_clean_chunk(struct msc_curl_memory_buffer_t *chunk); 72 | 73 | #endif 74 | 75 | -------------------------------------------------------------------------------- /apache2/msc_status_engine.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef MSC_STATUS_ENGINE_H 16 | #define MSC_STATUS_ENGINE_H 17 | 18 | #include "apr.h" 19 | #include "apr_pools.h" 20 | #include "apr_version.h" 21 | #include "apr_optional.h" 22 | #include "msc_pcre.h" 23 | 24 | #ifndef WIN32 25 | #define STATUS_ENGINE_DNS_IN_BETWEEN_DOTS 32 26 | #else 27 | #define STATUS_ENGINE_DNS_IN_BETWEEN_DOTS 30 28 | #endif 29 | 30 | #define STATUS_ENGINE_DNS_SUFFIX "status.modsecurity.org" 31 | 32 | #define MAX_MACHINE_NAME_SIZE 100 33 | 34 | #define MAC_ADDRESS_SIZE 20 35 | 36 | static const char msc_status_engine_basis_32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; 37 | 38 | int msc_status_engine_call(void); 39 | 40 | int DSOLOCAL msc_status_engine_unique_id (unsigned char *digest); 41 | 42 | int DSOLOCAL msc_beacon_string (char *beacon_string, int beacon_string_max_len); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /apache2/msc_tree.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef __MSC_TREE_H__ 16 | #define __MSC_TREE_H__ 17 | 18 | #include "modsecurity.h" 19 | 20 | typedef struct CPTData CPTData; 21 | typedef struct TreePrefix TreePrefix; 22 | typedef struct TreeNode TreeNode; 23 | typedef struct CPTTree CPTTree; 24 | typedef struct TreeRoot TreeRoot; 25 | 26 | #define IPV4_TREE 0x1 27 | #define IPV6_TREE 0x2 28 | 29 | #define IPV4_LEN 0x20 30 | #define IPV6_LEN 0x80 31 | 32 | #define TREE_CHECK(x, y) ((x) & (y)) 33 | #define MASK_BITS(x) ((x + 1) * 8) 34 | #define SHIFT_LEFT_MASK(x) ((-1) << (x)) 35 | #define SHIFT_RIGHT_MASK(x,y) ((x) >> (y)) 36 | 37 | #define NETMASK_256 0x100 38 | #define NETMASK_128 0x80 39 | #define NETMASK_64 0x40 40 | #define NETMASK_32 0x20 41 | #define NETMASK_16 0x10 42 | #define NETMASK_8 0x8 43 | #define NETMASK_4 0x4 44 | #define NETMASK_2 0x2 45 | 46 | struct CPTData { 47 | unsigned char netmask; 48 | struct CPTData *next; 49 | }; 50 | 51 | struct TreePrefix { 52 | unsigned char *buffer; 53 | unsigned int bitlen; 54 | CPTData *prefix_data; 55 | }; 56 | 57 | struct TreeNode { 58 | unsigned int bit; 59 | int count; 60 | unsigned char *netmasks; 61 | TreePrefix *prefix; 62 | struct TreeNode *left, *right; 63 | struct TreeNode *parent; 64 | }; 65 | 66 | struct CPTTree { 67 | int count; 68 | apr_pool_t *pool; 69 | TreeNode *head; 70 | }; 71 | 72 | struct TreeRoot { 73 | CPTTree *ipv4_tree; 74 | CPTTree *ipv6_tree; 75 | }; 76 | 77 | CPTTree DSOLOCAL *CPTCreateRadixTree(apr_pool_t *pool); 78 | TreeNode DSOLOCAL *CPTIpMatch(modsec_rec *msr, unsigned char *ipdata, CPTTree *tree, int type); 79 | TreeNode DSOLOCAL *TreeAddIP(const char *buffer, CPTTree *tree, int type); 80 | 81 | #endif /*__MSC_TREE_H__ */ 82 | -------------------------------------------------------------------------------- /apache2/msc_unicode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _MSC_UNICODE_H_ 16 | #define _MSC_UNICODE_H_ 17 | 18 | typedef struct unicode_map unicode_map; 19 | 20 | #include 21 | #include "modsecurity.h" 22 | #include "apr_hash.h" 23 | 24 | struct unicode_map { 25 | apr_file_t *map; 26 | const char *mapfn; 27 | }; 28 | 29 | int DSOLOCAL unicode_map_init(directory_config *dcfg, const char *mapfn, char **error_msg); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /apache2/msc_xml.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _MSC_XML_H_ 16 | #define _MSC_XML_H_ 17 | 18 | typedef struct xml_data xml_data; 19 | 20 | #include "modsecurity.h" 21 | #include 22 | #include 23 | 24 | /* Structures */ 25 | 26 | struct xml_data { 27 | xmlSAXHandler *sax_handler; 28 | xmlParserCtxtPtr parsing_ctx; 29 | xmlDocPtr doc; 30 | 31 | unsigned int well_formed; 32 | }; 33 | 34 | /* Functions */ 35 | 36 | int DSOLOCAL xml_init(modsec_rec *msr, char **error_msg); 37 | 38 | int DSOLOCAL xml_process_chunk(modsec_rec *msr, const char *buf, 39 | unsigned int size, char **error_msg); 40 | 41 | int DSOLOCAL xml_complete(modsec_rec *msr, char **error_msg); 42 | 43 | apr_status_t DSOLOCAL xml_cleanup(modsec_rec *msr); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /apache2/persist_dbm.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _PERSIST_DBM_H_ 16 | #define _PERSIST_DBM_H_ 17 | 18 | #include "apr_general.h" 19 | #include "modsecurity.h" 20 | 21 | /* The DB Option Definition */ 22 | #define DB_OPT_ORIGIN 0 23 | #ifdef MEMORY_DATABASE_ENABLE 24 | #define DB_OPT_AGMDB 1 25 | 26 | /* 27 | * The maximum number of entries that database can support. 28 | * The database will refuse the new entry injection if the total entry number is larger than MAXIMUM_AGMDB_ENTRY_NUM 29 | * TODO: add as a configuration parameter 30 | */ 31 | #define MAXIMUM_AGMDB_ENTRY_NUM 200000 32 | 33 | struct agmdb_handle_entry{ 34 | const char* col_name; 35 | void* handle; 36 | struct agmdb_handle_entry *next; 37 | }; 38 | #endif 39 | apr_table_t DSOLOCAL *collection_retrieve(modsec_rec *msr, const char *col_name, 40 | const char *col_value, int col_value_length); 41 | 42 | int DSOLOCAL collection_store(modsec_rec *msr, apr_table_t *collection); 43 | 44 | int DSOLOCAL collections_remove_stale(modsec_rec *msr, const char *col_name); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /apache2/waf_logging/waf_log_util.h: -------------------------------------------------------------------------------- 1 | #ifndef _WAF_LOG_UTIL_EXTERNAL_HEADER 2 | #define _WAF_LOG_UTIL_EXTERNAL_HEADER 3 | 4 | #define WAF_LOG_UTIL_FAILED -1 5 | #define WAF_LOG_UTIL_SUCCESS 0 6 | #define MODSEC_MODE_DETECT 1 7 | #define MODSEC_MODE_PREVENT 2 8 | 9 | // ACTION_ALLOW/ACTION_ALLOW_REQUEST/ACTION_ALLOW_PHASE are defined in the modsecurity.h and copied here 10 | #define ACTION_ALLOW 5 11 | #define ACTION_ALLOW_REQUEST 6 12 | #define ACTION_ALLOW_PHASE 7 13 | 14 | #define WAF_RULESET_PREFIX "/RuleSets/" 15 | #define WAF_LOG_UTIL_FILE "waf_json.log" 16 | #define WAF_LOG_UTIL_OPERATION_NAME "ApplicationGatewayFirewall" 17 | #define WAF_LOG_UTIL_CATEGORY "ApplicationGatewayFirewallLog" 18 | 19 | // WAF log values passed with request 20 | #define WAF_POLICY_SCOPE "WafPolicyScope" 21 | #define WAF_POLICY_SCOPE_NAME "WafPolicyScopeName" 22 | 23 | #define RULE_TYPE_OWASP_CRS "OWASP_CRS" 24 | 25 | #define RULE_HASH_SIZE 499 26 | 27 | enum ERROR_ENUM { 28 | none, pcre_limit_error, 29 | }; 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | char* generate_json(const char* timestamp, const char* resourceId, const char* operationName, const char* category, const char* instanceId, const char* clientIP, const char* clientPort, const char* requestUri, const char* ruleSetType, const char* ruleSetVersion, const char* ruleId, const char* messages, const int action, const int site, const char* details_messages, const char* details_data, const char* details_file, const char* details_line, const char* hostname, const char* waf_unique_id, 35 | const char* waf_policy_id, const char* waf_policy_scope, const char* waf_policy_scope_name); 36 | void free_json(char* str); 37 | // Returns 0 if succeeded, non-zero code otherwise 38 | int init_appgw_rules_id_hash(); 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /authors.txt: -------------------------------------------------------------------------------- 1 | b1v1r = Brian Rectanus 2 | brectanu = Brian Rectanus 3 | brectanus = Brian Rectanus 4 | ivanr = Ivan Ristić 5 | rbarnett = Ryan C. Barnett 6 | [anonymous] = Brian Rectanus 7 | (no author) = Brian Rectanus 8 | brenosilva = Breno Silva 9 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | #rm -rf autom4te.cache 4 | #automake --add-missing --copy --foreign 5 | #autoreconf --install 6 | #autoheader 7 | 8 | rm -rf autom4te.cache 9 | rm -f aclocal.m4 10 | case `uname` in Darwin*) glibtoolize --force --copy ;; 11 | *) libtoolize --force --copy ;; esac 12 | autoreconf --install 13 | autoheader 14 | automake --add-missing --foreign --copy --force-missing 15 | autoconf --force 16 | rm -rf autom4te.cache 17 | 18 | -------------------------------------------------------------------------------- /build/apxs-wrapper.in: -------------------------------------------------------------------------------- 1 | #!@SHELL@ 2 | 3 | WRAPPED_OPTS="" 4 | for opt in "$@"; do 5 | case "$opt" in 6 | # Fix for -R not working w/apxs 7 | -R*) WRAPPED_OPTS="$WRAPPED_OPTS -Wl,$opt" ;; 8 | # OSF1 compiler option 9 | -pthread) WRAPPED_OPTS="$WRAPPED_OPTS -Wc,$opt" ;; 10 | # Unwrapped 11 | *) WRAPPED_OPTS="$WRAPPED_OPTS $opt" ;; 12 | esac 13 | done 14 | 15 | exec @APXS@ $WRAPPED_OPTS 16 | -------------------------------------------------------------------------------- /build/find_apr.m4: -------------------------------------------------------------------------------- 1 | dnl Check for APR Libraries 2 | dnl CHECK_APR(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) 3 | dnl Sets: 4 | dnl APR_CFLAGS 5 | dnl APR_LDFLAGS 6 | dnl APR_LIBS 7 | dnl APR_LINK_LD 8 | 9 | APR_CONFIG="" 10 | APR_CFLAGS="" 11 | APR_CPPFLAGS="" 12 | APR_LDFLAGS="" 13 | APR_LDADD="" 14 | APR_INCLUDEDIR="" 15 | APR_LINKLD="" 16 | AC_DEFUN([CHECK_APR], 17 | [dnl 18 | 19 | AC_ARG_WITH( 20 | apr, 21 | [AC_HELP_STRING([--with-apr=PATH],[Path to apr prefix or config script])], 22 | [test_paths="${with_apr}"], 23 | [test_paths="/usr/local/libapr /usr/local/apr /usr/local /opt/libapr /opt/apr /opt /usr"]) 24 | 25 | AC_MSG_CHECKING([for libapr config script]) 26 | 27 | for x in ${test_paths}; do 28 | dnl # Determine if the script was specified and use it directly 29 | if test ! -d "$x" -a -e "$x"; then 30 | APR_CONFIG=$x 31 | apr_path=no 32 | break 33 | fi 34 | 35 | dnl # Try known config script names/locations 36 | for APR_CONFIG in apr-1-mt-config apr-1-config apr-config-1 apr-mt-config-1 apr-mt-config apr-config; do 37 | if test -e "${x}/bin/${APR_CONFIG}"; then 38 | apr_path="${x}/bin" 39 | break 40 | elif test -e "${x}/${APR_CONFIG}"; then 41 | apr_path="${x}" 42 | break 43 | else 44 | apr_path="" 45 | fi 46 | done 47 | if test -n "$apr_path"; then 48 | break 49 | fi 50 | done 51 | 52 | if test -n "${apr_path}"; then 53 | if test "${apr_path}" != "no"; then 54 | APR_CONFIG="${apr_path}/${APR_CONFIG}" 55 | fi 56 | AC_MSG_RESULT([${APR_CONFIG}]) 57 | APR_VERSION="`${APR_CONFIG} --version`" 58 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr VERSION: $APR_VERSION); fi 59 | APR_CFLAGS="`${APR_CONFIG} --includes`" 60 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr CFLAGS: $APR_CFLAGS); fi 61 | APR_CPPFLAGS="`${APR_CONFIG} --cppflags`" 62 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr CPPFLAGS: $APR_CPPFLAGS); fi 63 | APR_LDFLAGS="`${APR_CONFIG} --libs`" 64 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr LDFLAGS: $APR_LDFLAGS); fi 65 | APR_LDADD="`${APR_CONFIG} --link-libtool`" 66 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr LDADD: $APR_LDADD); fi 67 | APR_INCLUDEDIR="`${APR_CONFIG} --includedir`" 68 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr INCLUDEDIR: $APR_INCLUDEDIR); fi 69 | APR_LINKLD="`${APR_CONFIG} --link-ld`" 70 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apr LINKLD: $APR_LINKLD); fi 71 | else 72 | AC_MSG_RESULT([no]) 73 | fi 74 | 75 | AC_SUBST(APR_CONFIG) 76 | AC_SUBST(APR_VERSION) 77 | AC_SUBST(APR_CFLAGS) 78 | AC_SUBST(APR_CPPFLAGS) 79 | AC_SUBST(APR_LDFLAGS) 80 | AC_SUBST(APR_LDADD) 81 | AC_SUBST(APR_INCLUDEDIR) 82 | AC_SUBST(APR_LINKLD) 83 | 84 | if test -z "${APR_VERSION}"; then 85 | AC_MSG_NOTICE([*** apr library not found.]) 86 | ifelse([$2], , AC_MSG_ERROR([apr library is required]), $2) 87 | else 88 | AC_MSG_NOTICE([using apr v${APR_VERSION}]) 89 | ifelse([$1], , , $1) 90 | fi 91 | ]) 92 | -------------------------------------------------------------------------------- /build/find_apu.m4: -------------------------------------------------------------------------------- 1 | dnl Check for APU Libraries 2 | dnl CHECK_APU(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) 3 | dnl Sets: 4 | dnl APU_CFLAGS 5 | dnl APU_LDFLAGS 6 | dnl APU_LIBS 7 | dnl APU_LINK_LD 8 | 9 | APU_CONFIG="" 10 | APU_CFLAGS="" 11 | APU_LDFLAGS="" 12 | APU_LDADD="" 13 | APU_INCLUDEDIR="" 14 | APU_LINKLD="" 15 | 16 | AC_DEFUN([CHECK_APU], 17 | [dnl 18 | 19 | AC_ARG_WITH( 20 | apu, 21 | [AC_HELP_STRING([--with-apu=PATH],[Path to apu prefix or config script])], 22 | [test_paths="${with_apu}"], 23 | [test_paths="/usr/local/libapr-util /usr/local/apr-util /usr/local/libapu /usr/local/apu /usr/local/apr /usr/local /opt/libapr-util /opt/apr-util /opt/libapu /opt/apu /opt /usr"]) 24 | 25 | AC_MSG_CHECKING([for libapu config script]) 26 | 27 | for x in ${test_paths}; do 28 | dnl # Determine if the script was specified and use it directly 29 | if test ! -d "$x" -a -e "$x"; then 30 | APU_CONFIG=$x 31 | apu_path="no" 32 | break 33 | fi 34 | 35 | dnl # Try known config script names/locations 36 | for APU_CONFIG in apu-1-mt-config apu-1-config apu-config-1 apu-mt-config-1 apu-mt-config apu-config; do 37 | if test -e "${x}/bin/${APU_CONFIG}"; then 38 | apu_path="${x}/bin" 39 | break 40 | elif test -e "${x}/${APU_CONFIG}"; then 41 | apu_path="${x}" 42 | break 43 | else 44 | apu_path="" 45 | fi 46 | done 47 | if test -n "$apu_path"; then 48 | break 49 | fi 50 | done 51 | 52 | if test -n "${apu_path}"; then 53 | if test "${apu_path}" != "no"; then 54 | APU_CONFIG="${apu_path}/${APU_CONFIG}" 55 | fi 56 | AC_MSG_RESULT([${APU_CONFIG}]) 57 | APU_VERSION="`${APU_CONFIG} --version`" 58 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu VERSION: $APU_VERSION); fi 59 | APU_CFLAGS="`${APU_CONFIG} --includes`" 60 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu CFLAGS: $APU_CFLAGS); fi 61 | APU_LDFLAGS="`${APU_CONFIG} --ldflags`" 62 | APU_LDFLAGS="$APU_LDFLAGS `${APU_CONFIG} --libs`" 63 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu LDFLAGS: $APU_LDFLAGS); fi 64 | APU_LDADD="`${APU_CONFIG} --link-libtool`" 65 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu LDADD: $APU_LDADD); fi 66 | APU_INCLUDEDIR="`${APU_CONFIG} --includedir`" 67 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu INCLUDEDIR: $APU_INCLUDEDIR); fi 68 | APU_LINKLD="`${APU_CONFIG} --link-ld`" 69 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(apu LINKLD: $APU_LINKLD); fi 70 | else 71 | AC_MSG_RESULT([no]) 72 | fi 73 | 74 | AC_SUBST(APU_CONFIG) 75 | AC_SUBST(APU_VERSION) 76 | AC_SUBST(APU_CFLAGS) 77 | AC_SUBST(APU_LDFLAGS) 78 | AC_SUBST(APU_LDADD) 79 | AC_SUBST(APU_INCLUDEDIR) 80 | AC_SUBST(APU_LINKLD) 81 | 82 | if test -z "${APU_VERSION}"; then 83 | AC_MSG_NOTICE([*** apu library not found.]) 84 | ifelse([$2], , AC_MSG_ERROR([apu library is required]), $2) 85 | else 86 | AC_MSG_NOTICE([using apu v${APU_VERSION}]) 87 | ifelse([$1], , , $1) 88 | fi 89 | ]) 90 | -------------------------------------------------------------------------------- /build/find_pcre.m4: -------------------------------------------------------------------------------- 1 | dnl Check for PCRE Libraries 2 | dnl CHECK_PCRE(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) 3 | dnl Sets: 4 | dnl PCRE_CFLAGS 5 | dnl PCRE_LIBS 6 | 7 | PCRE_CONFIG="" 8 | PCRE_VERSION="" 9 | PCRE_CPPFLAGS="" 10 | PCRE_CFLAGS="" 11 | PCRE_LDFLAGS="" 12 | PCRE_LDADD="" 13 | PCRE_LD_PATH="" 14 | 15 | AC_DEFUN([CHECK_PCRE], 16 | [dnl 17 | 18 | AC_ARG_WITH( 19 | pcre, 20 | [AC_HELP_STRING([--with-pcre=PATH],[Path to pcre prefix or config script])], 21 | [test_paths="${with_pcre}"], 22 | [test_paths="/usr/local/libpcre /usr/local/pcre /usr/local /opt/libpcre /opt/pcre /opt /usr"]) 23 | 24 | AC_MSG_CHECKING([for libpcre config script]) 25 | 26 | dnl # Determine pcre lib directory 27 | if test -z "${with_pcre}"; then 28 | test_paths="/usr/local/pcre /usr/local /usr" 29 | else 30 | test_paths="${with_pcre}" 31 | fi 32 | 33 | for x in ${test_paths}; do 34 | dnl # Determine if the script was specified and use it directly 35 | if test ! -d "$x" -a -e "$x"; then 36 | PCRE_CONFIG=$x 37 | pcre_path="no" 38 | break 39 | fi 40 | 41 | dnl # Try known config script names/locations 42 | for PCRE_CONFIG in pcre-config; do 43 | if test -e "${x}/bin/${PCRE_CONFIG}"; then 44 | pcre_path="${x}/bin" 45 | break 46 | elif test -e "${x}/${PCRE_CONFIG}"; then 47 | pcre_path="${x}" 48 | break 49 | else 50 | pcre_path="" 51 | fi 52 | done 53 | if test -n "$pcre_path"; then 54 | break 55 | fi 56 | done 57 | 58 | if test -n "${pcre_path}"; then 59 | if test "${pcre_path}" != "no"; then 60 | PCRE_CONFIG="${pcre_path}/${PCRE_CONFIG}" 61 | fi 62 | AC_MSG_RESULT([${PCRE_CONFIG}]) 63 | PCRE_VERSION="`${PCRE_CONFIG} --version`" 64 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(pcre VERSION: $PCRE_VERSION); fi 65 | PCRE_CFLAGS="`${PCRE_CONFIG} --cflags`" 66 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(pcre CFLAGS: $PCRE_CFLAGS); fi 67 | PCRE_LDADD="`${PCRE_CONFIG} --libs`" 68 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(pcre LDADD: $PCRE_LDADD); fi 69 | PCRE_LD_PATH="/`${PCRE_CONFIG} --libs | cut -d'/' -f2,3,4,5,6 | cut -d ' ' -f1`" 70 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(pcre PCRE_LD_PATH: $PCRE_LD_PATH); fi 71 | else 72 | AC_MSG_RESULT([no]) 73 | fi 74 | 75 | AC_SUBST(PCRE_CONFIG) 76 | AC_SUBST(PCRE_VERSION) 77 | AC_SUBST(PCRE_CPPFLAGS) 78 | AC_SUBST(PCRE_CFLAGS) 79 | AC_SUBST(PCRE_LDFLAGS) 80 | AC_SUBST(PCRE_LDADD) 81 | AC_SUBST(PCRE_LD_PATH) 82 | 83 | if test -z "${PCRE_VERSION}"; then 84 | AC_MSG_NOTICE([*** pcre library not found.]) 85 | ifelse([$2], , AC_MSG_ERROR([pcre library is required]), $2) 86 | else 87 | AC_MSG_NOTICE([using pcre v${PCRE_VERSION}]) 88 | ifelse([$1], , , $1) 89 | fi 90 | ]) 91 | -------------------------------------------------------------------------------- /build/find_ssdeep.m4: -------------------------------------------------------------------------------- 1 | dnl Check for SSDEEP Libraries 2 | dnl CHECK_SSDEEP(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) 3 | dnl Sets: 4 | dnl SSDEEP_CFLAGS 5 | dnl SSDEEP_LDFLAGS 6 | 7 | AC_DEFUN([CHECK_SSDEEP], 8 | [dnl 9 | 10 | SSDEEP_CFLAGS="" 11 | SSDEEP_LDFLAGS="" 12 | SSDEEP_LDADD="" 13 | 14 | AC_ARG_WITH( 15 | ssdeep, 16 | [AC_HELP_STRING([--with-ssdeep=PATH],[Path to ssdeep prefix])] 17 | ,, with_ssdeep=yes) 18 | 19 | AS_CASE(["${with_ssdeep}"], 20 | [no], [test_paths=], 21 | [yes], [test_paths="/usr/ /usr/local/ /usr/local/libfuzzy /usr/local/fuzzy /opt/libfuzzy /opt/fuzzy /opt /opt/local"], 22 | [test_paths="${with_ssdeep}"]) 23 | 24 | AS_IF([test "x${test_paths}" != "x"], [ 25 | AC_MSG_CHECKING([for ssdeep path]) 26 | 27 | SSDEEP_LIB_NAME="fuzzy" 28 | ssdeep_dir= 29 | 30 | if test -z "$withssdeep" -o "$withssdeep" = "yes"; then 31 | for i in ${test_paths}; do 32 | if test -f "$i/include/fuzzy.h"; then 33 | SSDEEP_CFLAGS="-I$i/include" 34 | ssdeep_dir=$i 35 | fi 36 | done 37 | else 38 | if test -f "$withssdeep/include/fuzzy.h"; then 39 | SSDEEP_CFLAGS="-I$withssdeep/include" 40 | ssdeep_dir=$withssdeep 41 | fi 42 | fi 43 | 44 | SSDEEP_LDFLAGS="-L$ssdeep_dir/lib -lfuzzy" 45 | SSDEEP_LDADD="-lfuzzy" 46 | 47 | ]) 48 | 49 | if test -z "${SSDEEP_CFLAGS}"; then 50 | AC_MSG_RESULT([no]) 51 | SSDEEP_LDFLAGS="" 52 | SSDEEP_LDADD="" 53 | AC_MSG_NOTICE([optional ssdeep library not found]) 54 | else 55 | SSDEEP_CFLAGS="-DWITH_SSDEEP ${SSDEEP_CFLAGS}" 56 | AC_MSG_RESULT([${SSDEEP_LDFLAGS} ${SSDEEP_CFLAGS}]) 57 | fi 58 | 59 | AC_SUBST(SSDEEP_LDFLAGS) 60 | AC_SUBST(SSDEEP_LDADD) 61 | AC_SUBST(SSDEEP_CFLAGS) 62 | 63 | 64 | ]) 65 | -------------------------------------------------------------------------------- /build/find_xml.m4: -------------------------------------------------------------------------------- 1 | dnl Check for LIBXML2 Libraries 2 | dnl CHECK_LIBXML2(ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]) 3 | dnl Sets: 4 | dnl LIBXML2_CFLAGS 5 | dnl LIBXML2_LIBS 6 | 7 | LIBXML2_CONFIG="" 8 | LIBXML2_VERSION="" 9 | LIBXML2_CFLAGS="" 10 | LIBXML2_CPPFLAGS="" 11 | LIBXML2_LDADD="" 12 | LIBXML2_LDFLAGS="" 13 | 14 | AC_DEFUN([CHECK_LIBXML2], 15 | [dnl 16 | 17 | AC_ARG_WITH( 18 | libxml, 19 | [AC_HELP_STRING([--with-libxml=PATH],[Path to libxml2 prefix or config script])], 20 | [test_paths="${with_libxml}"], 21 | [test_paths="/usr/local/libxml2 /usr/local/xml2 /usr/local/xml /usr/local /opt/libxml2 /opt/libxml /opt/xml2 /opt/xml /opt /usr"]) 22 | 23 | AC_MSG_CHECKING([for libxml2 config script]) 24 | 25 | for x in ${test_paths}; do 26 | dnl # Determine if the script was specified and use it directly 27 | if test ! -d "$x" -a -e "$x"; then 28 | LIBXML2_CONFIG=$x 29 | libxml2_path="no" 30 | break 31 | fi 32 | 33 | dnl # Try known config script names/locations 34 | for LIBXML2_CONFIG in xml2-config xml-2-config xml-config; do 35 | if test -e "${x}/bin/${LIBXML2_CONFIG}"; then 36 | libxml2_path="${x}/bin" 37 | break 38 | elif test -e "${x}/${LIBXML2_CONFIG}"; then 39 | libxml2_path="${x}" 40 | break 41 | else 42 | libxml2_path="" 43 | fi 44 | done 45 | if test -n "$libxml2_path"; then 46 | break 47 | fi 48 | done 49 | 50 | if test -n "${libxml2_path}"; then 51 | if test "${libxml2_path}" != "no"; then 52 | LIBXML2_CONFIG="${libxml2_path}/${LIBXML2_CONFIG}" 53 | fi 54 | AC_MSG_RESULT([${LIBXML2_CONFIG}]) 55 | LIBXML2_VERSION=`${LIBXML2_CONFIG} --version | sed 's/^[[^0-9]][[^[:space:]]][[^[:space:]]]*[[[:space:]]]*//'` 56 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(xml VERSION: $LIBXML2_VERSION); fi 57 | LIBXML2_CFLAGS="`${LIBXML2_CONFIG} --cflags`" 58 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(xml CFLAGS: $LIBXML2_CFLAGS); fi 59 | LIBXML2_LDADD="`${LIBXML2_CONFIG} --libs`" 60 | if test "$verbose_output" -eq 1; then AC_MSG_NOTICE(xml LDADD: $LIBXML2_LDADD); fi 61 | 62 | AC_MSG_CHECKING([if libxml2 is at least v2.6.29]) 63 | libxml2_min_ver=`echo 2.6.29 | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` 64 | libxml2_ver=`echo ${LIBXML2_VERSION} | awk -F. '{print (\$ 1 * 1000000) + (\$ 2 * 1000) + \$ 3}'` 65 | if test "$libxml2_ver" -ge "$libxml2_min_ver"; then 66 | AC_MSG_RESULT([yes, $LIBXML2_VERSION]) 67 | else 68 | AC_MSG_RESULT([no, $LIBXML2_VERSION]) 69 | AC_MSG_ERROR([NOTE: libxml2 library must be at least 2.6.29]) 70 | fi 71 | 72 | else 73 | AC_MSG_RESULT([no]) 74 | fi 75 | 76 | AC_SUBST(LIBXML2_CONFIG) 77 | AC_SUBST(LIBXML2_VERSION) 78 | AC_SUBST(LIBXML2_CFLAGS) 79 | AC_SUBST(LIBXML2_CPPFLAGS) 80 | AC_SUBST(LIBXML2_LDADD) 81 | AC_SUBST(LIBXML2_LDFLAGS) 82 | 83 | if test -z "${LIBXML2_VERSION}"; then 84 | AC_MSG_NOTICE([*** xml library not found.]) 85 | ifelse([$2], , AC_MSG_ERROR([libxml2 is required]), $2) 86 | else 87 | AC_MSG_NOTICE([using libxml2 v${LIBXML2_VERSION}]) 88 | ifelse([$1], , , $1) 89 | fi 90 | ]) 91 | -------------------------------------------------------------------------------- /doc/Makefile.am: -------------------------------------------------------------------------------- 1 | apache: 2 | $(DOXYGEN) doxygen-apache 3 | touch apache.stamp 4 | 5 | iis: 6 | $(DOXYGEN) doxygen-iis 7 | touch iis.stamp 8 | 9 | nginx: 10 | $(DOXYGEN) doxygen-nginx 11 | touch nginx.stamp 12 | 13 | standalone: 14 | $(DOXYGEN) doxygen-standalone 15 | touch standalone.stamp 16 | 17 | 18 | if BUILD_APACHE2_MODULE 19 | all-local: apache 20 | endif 21 | 22 | if BUILD_STANDALONE_MODULE 23 | all-local: iis nginx standalone 24 | endif 25 | 26 | clean-local: 27 | rm -rf apache iis nginx standalone 28 | -------------------------------------------------------------------------------- /doc/README.txt: -------------------------------------------------------------------------------- 1 | Please access the ModSecurity Github space to access the below documentation. 2 | 3 | * ModSecurity 2 Data Formats 4 | * ModSecurity Frequently Asked Questions (FAQ) 5 | * ModSecurity Migration Matrix 6 | * ModSecurity Rules Language Porting Specification 7 | * ModSecurity Wiki 8 | * Reference Manual 9 | * RoadMap 10 | 11 | https://github.com/SpiderLabs/ModSecurity/wiki/ 12 | -------------------------------------------------------------------------------- /doc/doxygen-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/doc/doxygen-logo.png -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | autoconf: 5 | image: appgwreg.azurecr.io/modsecurity:latest 6 | build: 7 | dockerfile: docker/Dockerfile 8 | context: . 9 | volumes: 10 | - ./:/microsoft/modsecurity 11 | working_dir: /microsoft/modsecurity 12 | entrypoint: ./autogen.sh 13 | 14 | configure: 15 | image: appgwreg.azurecr.io/modsecurity:latest 16 | build: 17 | dockerfile: docker/Dockerfile 18 | context: . 19 | volumes: 20 | - ./:/microsoft/modsecurity 21 | working_dir: /microsoft/modsecurity 22 | entrypoint: 23 | - ./configure 24 | - CXXFLAGS=-std=c++14 25 | - CFLAGS=-fPIC 26 | - --enable-standalone-module 27 | - --disable-mlogc 28 | 29 | make: 30 | image: appgwreg.azurecr.io/modsecurity:latest 31 | build: 32 | dockerfile: docker/Dockerfile 33 | context: . 34 | volumes: 35 | - ./:/microsoft/modsecurity 36 | working_dir: /microsoft/modsecurity 37 | entrypoint: make 38 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | 3 | RUN apt-get update 4 | RUN apt-get install -y \ 5 | automake\ 6 | build-essential \ 7 | curl \ 8 | unzip\ 9 | m4 \ 10 | libtool 11 | 12 | # Install jsoncons 13 | RUN mkdir -p /tmp/jsoncons/ 14 | RUN curl -o /tmp/jsoncons/jsoncons-0.122.0.zip -OL https://github.com/danielaparker/jsoncons/archive/v0.122.0.zip 15 | RUN unzip /tmp/jsoncons/jsoncons-0.122.0.zip -d /tmp/jsoncons 16 | RUN cp -r /tmp/jsoncons/jsoncons-0.122.0/include/jsoncons /usr/include/ 17 | 18 | RUN apt-get install -y \ 19 | apache2-dev \ 20 | g++-4.8 \ 21 | libaprutil1 \ 22 | libcurl4-openssl-dev \ 23 | liblua5.1-dev \ 24 | libluajit-5.1-dev \ 25 | libpcre3-dev \ 26 | libperl-dev \ 27 | libunwind8 \ 28 | libyajl-dev \ 29 | libxml2\ 30 | libxml2-dev\ 31 | unzip 32 | 33 | RUN apt clean \ 34 | && rm -rf /var/lib/apt/lists/* 35 | -------------------------------------------------------------------------------- /ext/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | EXT_CFLAGS = -I../apache2 \ 3 | @APR_CFLAGS@ \ 4 | @APU_CFLAGS@ \ 5 | @APXS_CFLAGS@ \ 6 | @LIBXML2_CFLAGS@ \ 7 | @LUA_CFLAGS@ \ 8 | @SSDEEP_CFLAGS@ 9 | 10 | EXT_CPPFLAGS = @APR_CPPFLAGS@ \ 11 | @LIBXML2_CPPFLAGS@ 12 | 13 | EXT_LIBADD = @APR_LDADD@ \ 14 | @APU_LDADD@ \ 15 | @LIBXML2_LDADD@ \ 16 | @LUA_LDADD@ 17 | 18 | EXT_LDFLAGS = -no-undefined -module -avoid-version \ 19 | @APR_LDFLAGS@ \ 20 | @APU_LDFLAGS@ \ 21 | @APXS_LDFLAGS@ \ 22 | @LIBXML2_LDFLAGS@ \ 23 | @LUA_LDFLAGS@ \ 24 | @SSDEEP_LDFLAGS@ 25 | 26 | pkglibdir = $(prefix)/lib 27 | 28 | pkglib_LTLIBRARIES = mod_op_strstr.la \ 29 | mod_tfn_reverse.la \ 30 | mod_var_remote_addr_port.la \ 31 | mod_reqbody_example.la 32 | 33 | mod_op_strstr_la_SOURCES = mod_op_strstr.c 34 | mod_op_strstr_la_CFLAGS = $(EXT_CFLAGS) 35 | mod_op_strstr_la_CPPFLAGS = $(EXT_CPPFLAGS) 36 | mod_op_strstr_la_LIBADD = $(EXT_LIBADD) 37 | mod_op_strstr_la_LDFLAGS = $(EXT_LDFLAGS) 38 | 39 | mod_tfn_reverse_la_SOURCES = mod_tfn_reverse.c 40 | mod_tfn_reverse_la_CFLAGS = $(EXT_CFLAGS) 41 | mod_tfn_reverse_la_CPPFLAGS = $(EXT_CPPFLAGS) 42 | mod_tfn_reverse_la_LIBADD = $(EXT_LIBADD) 43 | mod_tfn_reverse_la_LDFLAGS = $(EXT_LDFLAGS) 44 | 45 | mod_var_remote_addr_port_la_SOURCES = mod_var_remote_addr_port.c 46 | mod_var_remote_addr_port_la_CFLAGS = $(EXT_CFLAGS) 47 | mod_var_remote_addr_port_la_CPPFLAGS = $(EXT_CPPFLAGS) 48 | mod_var_remote_addr_port_la_LIBADD = $(EXT_LIBADD) 49 | mod_var_remote_addr_port_la_LDFLAGS = $(EXT_LDFLAGS) 50 | 51 | mod_reqbody_example_la_SOURCES = mod_reqbody_example.c 52 | mod_reqbody_example_la_CFLAGS = $(EXT_CFLAGS) 53 | mod_reqbody_example_la_CPPFLAGS = $(EXT_CPPFLAGS) 54 | mod_reqbody_example_la_LIBADD = $(EXT_LIBADD) 55 | mod_reqbody_example_la_LDFLAGS = $(EXT_LDFLAGS) 56 | 57 | install-exec-hook: $(pkglib_LTLIBRARIES) 58 | @echo "Removing unused static libraries..."; \ 59 | for m in $(pkglib_LTLIBRARIES); do \ 60 | base=`echo $$m | sed 's/\..*//'`; \ 61 | rm -f $(DESTDIR)$(pkglibdir)/$$base.*a; \ 62 | cp -p $(DESTDIR)$(pkglibdir)/$$base.so $(APXS_MODULES); \ 63 | done 64 | -------------------------------------------------------------------------------- /ext/README: -------------------------------------------------------------------------------- 1 | Custom ModSecurity Modules 2 | -------------------------- 3 | 4 | This directory contains three examples how you can extend 5 | ModSecurity without having to touch it directly, simply 6 | by creating custom Apache modules. 7 | 8 | NOTE: ModSecurity must be compiled with API support 9 | to use this feature (the API is enabled by default, 10 | but it will have been disabled if you used -DNO_MODSEC_API). 11 | 12 | 13 | Building the Example Custom Modules 14 | ----------------------------------- 15 | 16 | 1) Example custom transformation function module 17 | 18 | Module mod_tfn_reverse.c creates a custom transformation 19 | function "reverse" that reverses the content it receives 20 | on input. 21 | 22 | # Compile as a normal user 23 | apxs -I -I/usr/include/libxml2 \ 24 | -ca mod_tfn_reverse.c 25 | 26 | # Install as superuser 27 | sudo apxs -i mod_tfn_reverse.la 28 | 29 | 30 | 2) Example custom operator module 31 | 32 | Module mod_op_strstr.c creates a custom operator "strstr" 33 | that implements fast matching using the Boyer-Moore-Horspool 34 | algorithm. 35 | 36 | # Compile as a normal user 37 | apxs -I -I/usr/include/libxml2 \ 38 | -ca mod_op_strstr.c 39 | 40 | # Install as superuser 41 | sudo apxs -i mod_op_strstr.la 42 | 43 | 44 | 3) Example custom target variable module 45 | 46 | Module mod_var_remote_addr_port.c creates a custom variable "REMOTE_ADDR_PORT" 47 | that combines the REMOTE_ADDR and REMOTE_PORT into a.b.c.d:port format. 48 | 49 | # Compile as a normal user 50 | apxs -I -I/usr/include/libxml2 \ 51 | -ca mod_var_remote_addr_port.c 52 | 53 | # Install as superuser 54 | sudo apxs -i mod_var_remote_addr_port.la 55 | 56 | 57 | 3) Example custom request body parser module 58 | 59 | Module mod_reqbody_example.c creates a custom request body parser named 60 | "EXAMPLE". It does noting in particular, but shows the basic structure 61 | of such a module. 62 | 63 | # Compile as a normal user 64 | apxs -I -I/usr/include/libxml2 \ 65 | -ca mod_reqbody_example.c 66 | 67 | # Install as superuser 68 | sudo apxs -i mod_var_remote_addr_port.la 69 | 70 | # Write a phase 1 rule to set the parser 71 | SecAction "phase:1,pass,nolog,ctl:requestBodyProcessor=EXAMPLE" 72 | 73 | 74 | Using the Modules 75 | ----------------- 76 | 77 | Once the modules are built and installed, you load them like any other Apache module, but they must be loaded *after* the mod_security2.so module. 78 | 79 | # Load ModSecurity 80 | LoadModule security2_module modules/mod_security2.so 81 | 82 | # Load ModSecurity custom modules 83 | LoadModule tfn_reverse_module modules/mod_tfn_reverse.so 84 | LoadModule op_strstr_module modules/mod_op_strstr.so 85 | LoadModule var_remote_addr_port_module modules/mod_var_remote_addr_port.so 86 | 87 | # All three custom var/op/tfn used 88 | SecRule REMOTE_ADDR_PORT "@strstr 1.2.3.4:5678" "t:reverse" 89 | 90 | -------------------------------------------------------------------------------- /iis/ModSecurity.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /iis/build_modsecurity.bat: -------------------------------------------------------------------------------- 1 | 2 | set DEPENDENCIES_DIR=dependencies\build_dir 3 | set OUTPUT_DIR=dependencies\release_files 4 | 5 | set CURRENT_DIR=%cd% 6 | 7 | @echo Checking for vcargs... %1 8 | @if NOT (%1) == "" call %1 9 | @if (%ERRORLEVEL%) == (1) goto build_wrong_vcarg 10 | 11 | @echo Deleting old stuff... 12 | @del *.obj *.dll *.lib 13 | 14 | @echo apache2... 15 | cd ..\apache2 16 | del *.obj *.dll *.lib 17 | del libinjection\*.obj libinjection\*.dll libinjection\*.lib 18 | NMAKE -f Makefile.win APACHE=..\iis\%DEPENDENCIES_DIR%\Apache24 PCRE=..\iis\%DEPENDENCIES_DIR%\pcre\build LIBXML2=..\iis\%DEPENDENCIES_DIR%\libxml2 LUA=..\iis\%DEPENDENCIES_DIR%\lua\src VERSION=VERSION_IIS YAJL=..\iis\%DEPENDENCIES_DIR%\yajl\build\yajl-2.1.0 SSDEEP=..\iis\%DEPENDENCIES_DIR%\ssdeep CURL=..\iis\%DEPENDENCIES_DIR%\curl IIS_BUILD=yes 19 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 20 | 21 | @echo mlogc... 22 | cd ..\mlogc 23 | del *.obj *.dll *.lib 24 | nmake -f Makefile.win clean 25 | nmake -f Makefile.win APACHE=..\iis\%DEPENDENCIES_DIR%\Apache24 PCRE=..\iis\%DEPENDENCIES_DIR%\pcre\build CURL=..\iis\%DEPENDENCIES_DIR%\curl YAJL=..\iis\%DEPENDENCIES_DIR%\yajl\build\yajl-2.1.0 SSDEEP=..\iis\%DEPENDENCIES_DIR%\ssdeep VERSION=VERSION_IIS 26 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 27 | 28 | @echo iis... 29 | cd ..\iis 30 | del *.obj *.dll *.lib 31 | nmake -f Makefile.win clean 32 | NMAKE -f Makefile.win APACHE=..\iis\%DEPENDENCIES_DIR%\Apache24 PCRE=..\iis\%DEPENDENCIES_DIR%\pcre\build LIBXML2=..\iis\%DEPENDENCIES_DIR%\libxml2 LUA=..\iis\%DEPENDENCIES_DIR%\lua\src VERSION=VERSION_IIS YAJL=..\iis\%DEPENDENCIES_DIR%\yajl\build\yajl-2.1.0 SSDEEP=..\iis\%DEPENDENCIES_DIR%\ssdeep CURL=..\iis\%DEPENDENCIES_DIR%\curl 33 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 34 | 35 | cd %CURRENT_DIR% 36 | 37 | @echo Copy... 38 | copy /y ..\mlogc\mlogc.exe %OUTPUT_DIR% 39 | copy /y ..\iis\modsecurityiis.dll %OUTPUT_DIR% 40 | copy /y ..\iis\modsecurityiis.pdb %OUTPUT_DIR% 41 | 42 | exit /B 0 43 | 44 | :build_wrong_vcargs 45 | @echo Please specify a valid vcargs 46 | @goto failed 47 | 48 | :build_failed 49 | @echo Problems during the building phase 50 | @goto failed 51 | 52 | :failed 53 | @cd %CURRENT_DIR% 54 | @exit /B 1 55 | 56 | -------------------------------------------------------------------------------- /iis/build_msi.bat: -------------------------------------------------------------------------------- 1 | 2 | 3 | set PATH="%PATH%;C:\Program Files (x86)\WiX Toolset v3.8\bin;C:\Program Files (x86)\WiX Toolset v3.7\bin;" 4 | set CURRENT_DIR=%cd% 5 | 6 | del installer.wix* 7 | 8 | "candle.exe" -ext WixUtilExtension -ext WixUIExtension "%CURRENT_DIR%\installer.wxs" -out "%CURRENT_DIR%\installer.wixobj" -arch x64 9 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 10 | 11 | "light.exe" -ext WixUtilExtension -ext WixUIExtension "%CURRENT_DIR%\installer.wixobj" -out "%CURRENT_DIR%\installer-64.msi" 12 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 13 | 14 | "candle.exe" -ext WixUtilExtension -ext WixUIExtension "%CURRENT_DIR%\installer.wxs" -out "%CURRENT_DIR%\installer.wixobj" -arch x86 15 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 16 | 17 | "light.exe" -ext WixUtilExtension -ext WixUIExtension "%CURRENT_DIR%\installer.wixobj" -out "%CURRENT_DIR%\installer-32.msi" 18 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 19 | 20 | exit /B 0 21 | 22 | :build_failed 23 | @echo Problems during the building phase 24 | @goto failed 25 | 26 | :failed 27 | @cd %CURRENT_DIR% 28 | @exit /B 1 29 | 30 | -------------------------------------------------------------------------------- /iis/build_release.bat: -------------------------------------------------------------------------------- 1 | 2 | echo "Building release..." 3 | 4 | set RELEASE_DIR=release 5 | set OUTPUT_DIR=%cd%\dependencies\release_files 6 | set CURRENT_DIR=%cd% 7 | 8 | set AMD64=%RELEASE_DIR%\amd64 9 | set X86=%RELEASE_DIR%\x86 10 | 11 | mkdir "%RELEASE_DIR%" 12 | 13 | mkdir "%AMD64%" 14 | 15 | mkdir "%X86%" 16 | 17 | set VCARGS32="C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\vcvars32.bat" 18 | set VCARGS64="C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat" 19 | 20 | set SSDEEP_ARCH="x64" 21 | call build_dependencies.bat %VCARGS64% 22 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 23 | call build_modsecurity.bat %VCARGS64% 24 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 25 | 26 | copy "%OUTPUT_DIR%\libapr-1.dll" "%AMD64%" 27 | copy "%OUTPUT_DIR%\libapriconv-1.dll" "%AMD64%" 28 | copy "%OUTPUT_DIR%\libaprutil-1.dll" "%AMD64%" 29 | copy "%OUTPUT_DIR%\libcurl.dll" "%AMD64%" 30 | copy "%OUTPUT_DIR%\libxml2.dll" "%AMD64%" 31 | copy "%OUTPUT_DIR%\lua5.1.dll" "%AMD64%" 32 | copy "%OUTPUT_DIR%\mlogc.exe" "%AMD64%" 33 | copy "%OUTPUT_DIR%\ModSecurityIIS.dll" "%AMD64%" 34 | copy "%OUTPUT_DIR%\pcre.dll" "%AMD64%" 35 | copy "%OUTPUT_DIR%\zlib1.dll" "%AMD64%" 36 | copy "%OUTPUT_DIR%\yajl.dll" "%AMD64%" 37 | copy "%OUTPUT_DIR%\fuzzy.dll" "%AMD64%" 38 | 39 | set SSDEEP_ARCH="x86" 40 | call build_dependencies.bat %VCARGS32% 41 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 42 | call build_modsecurity.bat %VCARGS32% 43 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 44 | 45 | copy "%OUTPUT_DIR%\libapr-1.dll" "%X86%" 46 | copy "%OUTPUT_DIR%\libapriconv-1.dll" "%X86%" 47 | copy "%OUTPUT_DIR%\libaprutil-1.dll" "%X86%" 48 | copy "%OUTPUT_DIR%\libcurl.dll" "%X86%" 49 | copy "%OUTPUT_DIR%\libxml2.dll" "%X86%" 50 | copy "%OUTPUT_DIR%\lua5.1.dll" "%X86%" 51 | copy "%OUTPUT_DIR%\mlogc.exe" "%X86%" 52 | copy "%OUTPUT_DIR%\ModSecurityIIS.dll" "%X86%" 53 | copy "%OUTPUT_DIR%\pcre.dll" "%X86%" 54 | copy "%OUTPUT_DIR%\zlib1.dll" "%X86%" 55 | copy "%OUTPUT_DIR%\yajl.dll" "%X86%" 56 | copy "%OUTPUT_DIR%\fuzzy.dll" "%X86%" 57 | 58 | 59 | :: copy %OUTPUT_DIR%\Installer.exe %RELEASE_DIR% 60 | :: copy %OUTPUT_DIR%\ModSecurity.xml %RELEASE_DIR% 61 | :: copy %OUTPUT_DIR%\owasp_csr.zip %RELEASE_DIR% 62 | :: copy %OUTPUT_DIR%\README.txt %RELEASE_DIR% 63 | 64 | 65 | exit /B 0 66 | 67 | :build_failed 68 | @echo Problems during the building phase 69 | @goto failed 70 | 71 | :failed 72 | @cd %CURRENT_DIR% 73 | @exit /B 1 74 | 75 | -------------------------------------------------------------------------------- /iis/build_release_amd64.bat: -------------------------------------------------------------------------------- 1 | 2 | echo "Building release..." 3 | 4 | set RELEASE_DIR=release 5 | set OUTPUT_DIR=%cd%\dependencies\release_files 6 | set CURRENT_DIR=%cd% 7 | 8 | set AMD64=%RELEASE_DIR%\amd64 9 | 10 | mkdir "%RELEASE_DIR%" 11 | 12 | mkdir "%AMD64%" 13 | 14 | set VCARGS64="C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsx86_amd64.bat" 15 | 16 | 17 | set SSDEEP_ARCH="x64" 18 | call build_dependencies.bat %VCARGS64% 19 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 20 | call build_modsecurity.bat %VCARGS64% 21 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 22 | 23 | copy "%OUTPUT_DIR%\libapr-1.dll" "%AMD64%" 24 | copy "%OUTPUT_DIR%\libapriconv-1.dll" "%AMD64%" 25 | copy "%OUTPUT_DIR%\libaprutil-1.dll" "%AMD64%" 26 | copy "%OUTPUT_DIR%\libcurl.dll" "%AMD64%" 27 | copy "%OUTPUT_DIR%\libxml2.dll" "%AMD64%" 28 | copy "%OUTPUT_DIR%\lua5.1.dll" "%AMD64%" 29 | copy "%OUTPUT_DIR%\mlogc.exe" "%AMD64%" 30 | copy "%OUTPUT_DIR%\ModSecurityIIS.dll" "%AMD64%" 31 | copy "%OUTPUT_DIR%\pcre.dll" "%AMD64%" 32 | copy "%OUTPUT_DIR%\zlib1.dll" "%AMD64%" 33 | copy "%OUTPUT_DIR%\yajl.dll" "%AMD64%" 34 | copy "%OUTPUT_DIR%\fuzzy.dll" "%AMD64%" 35 | 36 | :: copy %OUTPUT_DIR%\Installer.exe %RELEASE_DIR% 37 | :: copy %OUTPUT_DIR%\ModSecurity.xml %RELEASE_DIR% 38 | :: copy %OUTPUT_DIR%\owasp_csr.zip %RELEASE_DIR% 39 | :: copy %OUTPUT_DIR%\README.txt %RELEASE_DIR% 40 | 41 | 42 | exit /B 0 43 | 44 | :build_failed 45 | @echo Problems during the building phase 46 | @goto failed 47 | 48 | :failed 49 | @cd %CURRENT_DIR% 50 | @exit /B 1 51 | 52 | -------------------------------------------------------------------------------- /iis/dependencies/build_apache.bat: -------------------------------------------------------------------------------- 1 | @cd "%WORK_DIR%" 2 | @set APACHE=%WORK_DIR%\Apache24 3 | 4 | @if NOT EXIST "%SOURCE_DIR%\%APACHE_BIN%" goto file_not_found_bin 5 | @if NOT EXIST "%SOURCE_DIR%\%APACHE_SRC%" goto file_not_found_src 6 | 7 | @7z.exe x "%SOURCE_DIR%\%APACHE_BIN%" 8 | @if NOT (%ERRORLEVEL%) == (0) goto something_went_wrong 9 | 10 | @7z.exe x "%SOURCE_DIR%\%APACHE_SRC%" -so | 7z.exe x -aoa -si -ttar 11 | @if NOT (%ERRORLEVEL%) == (0) goto something_went_wrong 12 | 13 | :: Missing: %APACHE%\bin\libapr-1.pdb %APACHE%\bin\libapr-1.lib ? 14 | copy /y "%APACHE%\bin\libapr-1.dll" "%OUTPUT_DIR%" 15 | @if NOT (%ERRORLEVEL%) == (0) goto something_went_wrong_copy 16 | 17 | :: Missing: %APACHE%\bin\libapriconv-1.pdb %APACHE%\lib\libapriconv-1.lib ? 18 | copy /y "%APACHE%\bin\libapriconv-1.dll" "%OUTPUT_DIR%" 19 | @if NOT (%ERRORLEVEL%) == (0) goto something_went_wrong_copy 20 | 21 | :: Missing: %APACHE%\bin\libaprutil-1.pdb %APACHE%\lib\libaprutil-1.lib ? 22 | copy /y "%APACHE%\bin\libaprutil-1.dll" "%OUTPUT_DIR%" 23 | @if NOT (%ERRORLEVEL%) == (0) goto something_went_wrong_copy 24 | 25 | @cd "%WORK_DIR%" 26 | 27 | @exit /B 0 28 | 29 | :something_went_wrong_copy 30 | @echo Something went wrong while trying to copy Apache binaries files. 31 | @goto failed 32 | 33 | :file_not_found_bin 34 | @echo File not found: %SOURCE_DIR%\%APACHE_BIN% 35 | @goto failed 36 | 37 | :file_not_found_src 38 | @echo File not found: %SOURCE_DIR%\%APACHE_SRC% 39 | @goto failed 40 | 41 | :something_went_wrong 42 | @echo Something went wrong while unzip Apache files. 43 | @goto failed 44 | 45 | :failed 46 | @exit /B 1 47 | 48 | -------------------------------------------------------------------------------- /iis/dependencies/build_cmake.bat: -------------------------------------------------------------------------------- 1 | @cd "%WORK_DIR%" 2 | 3 | @if NOT EXIST "%SOURCE_DIR%\%CMAKE%" goto file_not_found 4 | 5 | 6 | @7z.exe x "%SOURCE_DIR%\%CMAKE%" 7 | @if NOT (%ERRORLEVEL%) == (0) goto something_went_wrong 8 | 9 | @exit /B 0 10 | 11 | :file_not_found 12 | @echo File not found: %SOURCE_DIR%\%CMAKE% 13 | @goto failed 14 | 15 | :something_went_wrong 16 | @echo Something went wrong while unzip CMake files. 17 | @goto failed 18 | 19 | :failed 20 | @exit /B 1 -------------------------------------------------------------------------------- /iis/dependencies/build_curl.bat: -------------------------------------------------------------------------------- 1 | cd "%WORK_DIR%" 2 | @if NOT EXIST "%SOURCE_DIR%\%CURL%" goto file_not_found_bin 3 | echo "7z..." 4 | 7z.exe x "%SOURCE_DIR%\%CURL%" 5 | echo "Timeout..." 6 | timeout 5 7 | echo "Curl..." 8 | set CURL_DIR=%CURL:~0,-4% 9 | echo "Move..." 10 | move "%CURL_DIR%" "curl" 11 | echo "Cd..." 12 | CD "curl\winbuild" 13 | 14 | @set ARCH=x86 15 | @call cl 2>&1 | findstr /C:"x64" 16 | @if (%ERRORLEVEL%) == (0) set ARCH=x64 17 | 18 | nmake /f Makefile.vc mode=dll ENABLE_WINSSL=yes MACHINE=%ARCH% WITH_ZLIB=dll 19 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 20 | 21 | cd "%WORK_DIR%" 22 | 23 | copy /y "%WORK_DIR%\curl\builds\libcurl-vc-%ARCH%-release-dll-zlib-dll-ipv6-sspi-winssl-obj-lib\libcurl.dll" "%OUTPUT_DIR%" 24 | copy /y "%WORK_DIR%\curl\builds\libcurl-vc-%ARCH%-release-dll-zlib-dll-ipv6-sspi-winssl-obj-lib\libcurl.lib" "%OUTPUT_DIR%" 25 | copy /y "%WORK_DIR%\curl\builds\libcurl-vc-%ARCH%-release-dll-zlib-dll-ipv6-sspi-winssl-obj-lib\libcurl.lib" "%WORK_DIR%\curl\libcurl.lib" 26 | 27 | exit /B 0 28 | 29 | :file_not_found_bin 30 | @echo File not found: "%SOURCE_DIR%\%CURL%" 31 | @goto failed 32 | 33 | :build_failed 34 | @echo Problems during the building phase 35 | @goto failed 36 | 37 | :failed 38 | @exit /B 1 39 | 40 | 41 | -> 42 | -------------------------------------------------------------------------------- /iis/dependencies/build_libxml2.bat: -------------------------------------------------------------------------------- 1 | cd "%WORK_DIR%" 2 | 3 | @if NOT EXIST "%SOURCE_DIR%\%LIBXML2%" goto file_not_found_bin 4 | 5 | @7z.exe x "%SOURCE_DIR%\%LIBXML2%" -so | 7z.exe x -aoa -si -ttar 6 | 7 | set LIBXML2_DIR=%LIBXML2:~0,-7% 8 | 9 | move "%LIBXML2_DIR%" "libxml2" 10 | 11 | :: fart.exe -r -i -C "%WORK_DIR%\%LIBXML2_DIR%\win32\*.*" \x2Fopt:nowin98 " " 12 | cd "libxml2\win32" 13 | CSCRIPT configure.js iconv=no vcmanifest=yes zlib=yes 14 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 15 | NMAKE -f Makefile.msvc 16 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 17 | 18 | cd "%WORK%" 19 | 20 | copy /y "%WORK_DIR%\libxml2\win32\bin.msvc\libxml2.dll" "%OUTPUT_DIR%" 21 | copy /y "%WORK_DIR%\libxml2\win32\bin.msvc\libxml2.lib" "%OUTPUT_DIR%" 22 | 23 | @exit /B 0 24 | 25 | :file_not_found_bin 26 | @echo File not found: "%SOURCE_DIR%\%LIBXML2%" 27 | @goto failed 28 | 29 | :build_failed 30 | @echo Problems during the building phase 31 | @goto failed 32 | 33 | :failed 34 | @exit /B 1 35 | 36 | -------------------------------------------------------------------------------- /iis/dependencies/build_lua.bat: -------------------------------------------------------------------------------- 1 | cd "%WORK_DIR%" 2 | 3 | @if NOT EXIST "%SOURCE_DIR%\%LUA%" goto file_not_found_bin 4 | 5 | @7z.exe x "%SOURCE_DIR%\%LUA%" -so | 7z.exe x -aoa -si -ttar 6 | 7 | set LUA_DIR=%LUA:~0,-7% 8 | 9 | move "%LUA_DIR%" "lua" 10 | 11 | cd "lua\src" 12 | 13 | CL /Ox /arch:SSE2 /GF /GL /Gy /FD /EHsc /MD /Zi /TC /wd4005 /D "_MBCS" /D "LUA_CORE" /D "LUA_BUILD_AS_DLL" /D "_CRT_SECURE_NO_WARNINGS" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_WIN32" /D "_WINDLL" /c *.c 14 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 15 | DEL lua.obj luac.obj 16 | LINK /DLL /LTCG /DEBUG /OUT:lua5.1.dll *.obj 17 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 18 | IF EXIST lua5.1.dll.manifest MT -manifest lua5.1.dll.manifest -outputresource:lua5.1.dll;2 19 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 20 | 21 | cd "%WORK_DIR%" 22 | 23 | copy /y "%WORK_DIR%\lua\src\lua5.1.dll" "%OUTPUT_DIR%" 24 | copy /y "%WORK_DIR%\lua\src\lua5.1.pdb" "%OUTPUT_DIR%" 25 | copy /y "%WORK_DIR%\lua\src\lua5.1.lib" "%OUTPUT_DIR%" 26 | 27 | @exit /B 0 28 | 29 | :file_not_found_bin 30 | @echo File not found: "%SOURCE_DIR%\%LUA%" 31 | @goto failed 32 | 33 | :build_failed 34 | @echo Problems during the building phase 35 | @goto failed 36 | 37 | :failed 38 | @exit /B 1 39 | 40 | -------------------------------------------------------------------------------- /iis/dependencies/build_pcre.bat: -------------------------------------------------------------------------------- 1 | ::@if NOT (%ERRORLEVEL%) == (1) Echo "Patch successfull... For more info on patch see: https://vcs.pcre.org/pcre/code/trunk/CMakeLists.txt?r1=1659&r2=1677&view=patch" 2 | 3 | cd "%WORK_DIR%" 4 | 5 | @if NOT EXIST "%SOURCE_DIR%\%APACHE_BIN%" goto file_not_found_bin 6 | 7 | 7z.exe x "%SOURCE_DIR%\%PCRE%" 8 | set PCRE_DIR=%PCRE:~0,-4% 9 | 10 | move "%PCRE_DIR%" "pcre" 11 | 12 | @if "%PCRE_DIR%" == "pcre-8.40" ( 13 | Echo. && Echo "PCRE 8.40 found... patching with patch-pcre-8.40.vbs..." 14 | cscript /B /Nologo ../patch-pcre-8.40.vbs 15 | ) 16 | 17 | cd "pcre" 18 | cat CMakeLists.txt | sed "s/PCRE_STATIC_RUNTIME OFF CACHE BOOL/PCRE_STATIC_RUNTIME/g" | sed "s/PCRE_NO_RECURSE OFF/PCRE_NO_RECURSE ON/g" > CMakeLists.txt.ops 19 | move CMakeLists.txt CMakeLists.txt.old 20 | move CMakeLists.txt.ops CMakeLists.txt 21 | mkdir build 22 | cd build 23 | CMAKE -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=True ../ 24 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 25 | NMAKE 26 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 27 | cd "%WORK%" 28 | 29 | copy /y "%WORK_DIR%\pcre\build\pcre.dll" "%OUTPUT_DIR%" 30 | copy /y "%WORK_DIR%\pcre\build\pcre.pdb" "%OUTPUT_DIR%" 31 | copy /y "%WORK_DIR%\pcre\build\pcre.lib" "%OUTPUT_DIR%" 32 | copy /y "%WORK_DIR%\pcre\pcre.h.generic" "%WORK_DIR%\pcre\pcre.h" 33 | echo "a" 34 | @exit /B 0 35 | 36 | :file_not_found_bin 37 | @echo File not found: "%SOURCE_DIR%\%PCRE%" 38 | @goto failed 39 | 40 | :build_failed 41 | @echo Problems during the building phase 42 | @goto failed 43 | 44 | :failed 45 | @exit /B 1 46 | -------------------------------------------------------------------------------- /iis/dependencies/build_ssdeep.bat: -------------------------------------------------------------------------------- 1 | cd "%WORK_DIR%" 2 | 3 | echo "%SOURCE_DIR%\%SSDEEP%" 4 | echo "%SOURCE_DIR%\%SSDEEP_BIN%" 5 | 6 | @if NOT EXIST "%SOURCE_DIR%\%SSDEEP%" goto build_failed 7 | 8 | @7z.exe x "%SOURCE_DIR%\%SSDEEP_BIN%" 9 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 10 | @7z.exe x "%SOURCE_DIR%\%SSDEEP%" -so | 7z.exe x -aoa -si -ttar 11 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 12 | 13 | set SSDEEP_DIR=%SSDEEP_BIN:~0,-4% 14 | 15 | move "%SSDEEP_DIR%" "ssdeep" 16 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 17 | cd "%WORK_DIR%\ssdeep\" 18 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 19 | 20 | @set SSDEEP_ARCH="x86" 21 | @call cl 2>&1 | findstr /C:"x64" 22 | @if (%ERRORLEVEL%) == (0) set SSDEEP_ARCH="x64" 23 | 24 | lib /machine:%SSDEEP_ARCH% /def:fuzzy.def 25 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 26 | 27 | copy /y "%WORK_DIR%\ssdeep\fuzzy.dll" "%OUTPUT_DIR%" 28 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 29 | copy /y "%WORK_DIR%\ssdeep\fuzzy.def" "%OUTPUT_DIR%" 30 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 31 | copy /y "%WORK_DIR%\ssdeep\fuzzy.lib" "%OUTPUT_DIR%" 32 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 33 | 34 | 35 | @exit /B 0 36 | 37 | :build_failed 38 | @echo Problems during the building phase 39 | @goto failed 40 | 41 | :failed 42 | @exit /B 1 43 | -------------------------------------------------------------------------------- /iis/dependencies/build_yajl.bat: -------------------------------------------------------------------------------- 1 | cd "%WORK_DIR%" 2 | 3 | @if NOT EXIST "%SOURCE_DIR%\%YAJL%" goto file_not_found_bin 4 | 5 | 7z.exe x "%SOURCE_DIR%\%YAJL%" 6 | set YAJL_DIR=%YAJL:~0,-4% 7 | echo "%SOURCE_DIR%\%YAJL%" 8 | echo "%YAJL_DIR%" 9 | pwd 10 | move "%YAJL_DIR%" "%WORK_DIR%\yajl" 11 | pwd 12 | cd "yajl" 13 | pwd 14 | mkdir build 15 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 16 | cd build 17 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 18 | cmake -G"NMake Makefiles" -DCMAKE_BUILD_TYPE=Release .. 19 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 20 | nmake 21 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 22 | 23 | cd "%WORK%" 24 | 25 | copy /y "%WORK_DIR%\yajl\build\%YAJL_DIR%\lib\yajl.dll" "%OUTPUT_DIR%" 26 | :: copy /y "%WORK_DIR%\yajl\build\%YAJL_DIR%\lib\yajl.pdb" "%OUTPUT_DIR%" 27 | copy /y "%WORK_DIR%\yajl\build\%YAJL_DIR%\lib\yajl.lib" "%OUTPUT_DIR%" 28 | copy /y "%WORK_DIR%\yajl\build\%YAJL_DIR%\lib\yajl_s.lib" "%OUTPUT_DIR%" 29 | 30 | copy /y "%WORK_DIR%\yajl\build\%YAJL_DIR%\lib\yajl.dll" "%WORK_DIR%\yajl\build\%YAJL_DIR%\include\yajl.dll" 31 | copy /y "%WORK_DIR%\yajl\build\%YAJL_DIR%\lib\yajl.lib" "%WORK_DIR%\yajl\build\%YAJL_DIR%\include\yajl.lib" 32 | copy /y "%WORK_DIR%\yajl\build\%YAJL_DIR%\lib\yajl_s.lib" "%WORK_DIR%\yajl\build\%YAJL_DIR%\include\yajl_s.lib" 33 | 34 | 35 | @exit /B 0 36 | 37 | :file_not_found_bin 38 | @echo File not found: "%SOURCE_DIR%\%YAJL%" 39 | @goto failed 40 | 41 | :build_failed 42 | @echo Problems during the building phase 43 | @goto failed 44 | 45 | :failed 46 | @exit /B 1 47 | -------------------------------------------------------------------------------- /iis/dependencies/build_zlib.bat: -------------------------------------------------------------------------------- 1 | cd "%WORK_DIR%" 2 | 3 | @if NOT EXIST "%SOURCE_DIR%\%ZLIB%" goto file_not_found_bin 4 | 5 | 6 | @7z.exe x "%SOURCE_DIR%\%ZLIB%" -so | 7z.exe x -aoa -si -ttar 7 | 8 | set ZLIB_DIR=%ZLIB:~0,-7% 9 | 10 | move "%ZLIB_DIR%" "zlib" 11 | 12 | cd "zlib" 13 | nmake -f win32\Makefile.msc 14 | @if NOT (%ERRORLEVEL%) == (0) goto build_failed 15 | SET INCLUDE=%INCLUDE%;%WORK_DIR%\zlib 16 | SET LIB=%LIB%;%WORK_DIR%\zlib 17 | cd "%WORK_DIR%" 18 | 19 | copy /y "%WORK_DIR%\zlib\zlib1.dll" "%OUTPUT_DIR%" 20 | copy /y "%WORK_DIR%\zlib\zlib1.pdb" "%OUTPUT_DIR%" 21 | copy /y "%WORK_DIR%\zlib\zdll.lib" "%OUTPUT_DIR%" 22 | 23 | @exit /B 0 24 | 25 | :file_not_found_bin 26 | @echo File not found: "%SOURCE_DIR%\%ZLIB%" 27 | @goto failed 28 | 29 | :build_failed 30 | @echo Problems during the building phase 31 | @goto failed 32 | 33 | :failed 34 | @exit /B 1 35 | -------------------------------------------------------------------------------- /iis/dependencies_bin/cmake-3.8.2-win32-x86.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/cmake-3.8.2-win32-x86.zip -------------------------------------------------------------------------------- /iis/dependencies_bin/curl-7.54.1.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/curl-7.54.1.zip -------------------------------------------------------------------------------- /iis/dependencies_bin/httpd-2.4.27-win32-VC11.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/httpd-2.4.27-win32-VC11.zip -------------------------------------------------------------------------------- /iis/dependencies_bin/httpd-2.4.27-win64-VC11.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/httpd-2.4.27-win64-VC11.zip -------------------------------------------------------------------------------- /iis/dependencies_bin/httpd-2.4.27.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/httpd-2.4.27.tar.gz -------------------------------------------------------------------------------- /iis/dependencies_bin/libxml2-2.9.4.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/libxml2-2.9.4.tar.gz -------------------------------------------------------------------------------- /iis/dependencies_bin/lua-5.3.4.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/lua-5.3.4.tar.gz -------------------------------------------------------------------------------- /iis/dependencies_bin/pcre-8.40.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/pcre-8.40.zip -------------------------------------------------------------------------------- /iis/dependencies_bin/ssdeep-2.13.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/ssdeep-2.13.tar.gz -------------------------------------------------------------------------------- /iis/dependencies_bin/ssdeep-2.13.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/ssdeep-2.13.zip -------------------------------------------------------------------------------- /iis/dependencies_bin/yajl-2.1.0.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/yajl-2.1.0.zip -------------------------------------------------------------------------------- /iis/dependencies_bin/zlib-1.2.11.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/dependencies_bin/zlib-1.2.11.tar.gz -------------------------------------------------------------------------------- /iis/download_files.bat: -------------------------------------------------------------------------------- 1 | 2 | ::@set CMAKE=cmake-3.8.2-win32-x86.zip 3 | ::@set PCRE=pcre-8.40.zip 4 | ::@set ZLIB=zlib-1.2.11.tar.gz 5 | ::@set LIBXML2=libxml2-2.9.4.tar.gz 6 | ::@set LUA=lua-5.3.4.tar.gz 7 | ::@set CURL=curl-7.54.1.zip 8 | ::@set APACHE_SRC=httpd-2.4.27.tar.gz 9 | ::@set APACHE_BIN32=httpd-2.4.27-win32-VC11.zip 10 | ::@set APACHE_BIN64=httpd-2.4.27-win64-VC11.zip 11 | ::@set YAJL=yajl-2.1.0.zip 12 | ::@set SSDEEP=ssdeep-2.13.tar.gz 13 | ::@set SSDEEP_BIN=ssdeep-2.13.zip 14 | 15 | :: BITSAdmin refuses to download YAJL from GitHub URL 16 | :: @set YAJL_URL=https://github.com/lloyd/yajl/archive/%YAJL:~-9% 17 | @set YAJL_URL=http://http.debian.net/debian/pool/main/y/yajl/yajl_2.1.0.orig.tar.gz 18 | 19 | @set CMAKE_URL=https://cmake.org/files/v3.8/%CMAKE% 20 | @set PCRE_URL=https://ftp.pcre.org/pub/pcre/%PCRE% 21 | @set ZLIB_URL=https://zlib.net/%ZLIB% 22 | @set LIBXML2_URL=http://xmlsoft.org/sources/%LIBXML2% 23 | @set LUA_URL=https://www.lua.org/ftp/%LUA% 24 | @set CURL_URL=http://curl.askapache.com/download/%CURL% 25 | @set APACHE_SRC_URL=https://www.apache.org/dist/httpd/%APACHE_SRC% 26 | @set APACHE_BIN_URL=https://www.apachelounge.com/download/VC11/binaries 27 | @set SSDEEP_URL=https://downloads.sourceforge.net/project/ssdeep/ssdeep-2.13 28 | 29 | bitsadmin.exe /transfer "Downloading dependencies..." %CMAKE_URL% %SOURCE_DIR%\%CMAKE% %PCRE_URL% %SOURCE_DIR%\%PCRE% %ZLIB_URL% %SOURCE_DIR%\%ZLIB% %LIBXML2_URL% %SOURCE_DIR%\%LIBXML2% %LUA_URL% %SOURCE_DIR%\%LUA% %CURL_URL% %SOURCE_DIR%\%CURL% %APACHE_SRC_URL% %SOURCE_DIR%\%APACHE_SRC% %APACHE_BIN_URL%/%APACHE_BIN32% %SOURCE_DIR%\%APACHE_BIN32% %APACHE_BIN_URL%/%APACHE_BIN64% %SOURCE_DIR%\%APACHE_BIN64% %YAJL_URL% %SOURCE_DIR%\%YAJL% %SSDEEP_URL%/%SSDEEP% %SOURCE_DIR%\%SSDEEP% %SSDEEP_URL%/%SSDEEP_BIN% %SOURCE_DIR%\%SSDEEP_BIN% 30 | 31 | 32 | @if NOT (%ERRORLEVEL%) == (0) goto :failed_to_download 33 | @exit /B 0 34 | 35 | :failed_to_download 36 | @echo. && echo Failed to download dependency files... Try again or manually download the files to %SOURCE_DIR% and comment "@call download_files.bat" from build_dependencies.bat 37 | @goto failed 38 | 39 | :failed 40 | @exit /B 1 41 | 42 | -------------------------------------------------------------------------------- /iis/getModSecurityPkgs.ps1: -------------------------------------------------------------------------------- 1 | param( 2 | [Parameter(Mandatory=$true)][string]$locationUri 3 | ) 4 | 5 | function getFile($fileName){ 6 | $fPath = join-path -path $outDir -childpath $fileName 7 | if (!(Test-Path $fPath)){ 8 | write "getting file $fileName from $locationName to $outDir" 9 | $fileUri = $locationUri + '/' + $fileName 10 | Invoke-WebRequest -Uri $fileUri -OutFile $fPath 11 | } else { 12 | write "File $fileName exist, nothing to do" 13 | } 14 | } 15 | 16 | $outDir = join-path -path $env:USERPROFILE -childpath Downloads 17 | $neededPkgs = New-Object 'System.Collections.Generic.List[String]' 18 | $neededPkgs.Add('cmake-3.8.2-win32-x86.zip') 19 | $neededPkgs.Add('pcre-8.40.zip') 20 | $neededPkgs.Add('zlib-1.2.11.tar.gz') 21 | $neededPkgs.Add('libxml2-2.9.4.tar.gz') 22 | $neededPkgs.Add('lua-5.3.4.tar.gz') 23 | $neededPkgs.Add('curl-7.54.1.zip') 24 | $neededPkgs.Add('httpd-2.4.27.tar.gz') 25 | $neededPkgs.Add('httpd-2.4.27-win32-VC11.zip') 26 | $neededPkgs.Add('httpd-2.4.27-win64-VC11.zip') 27 | $neededPkgs.Add('yajl-2.1.0.zip') 28 | $neededPkgs.Add('ssdeep-2.13.tar.gz') 29 | $neededPkgs.Add('ssdeep-2.13.zip') 30 | 31 | Foreach ($i in $neededPkgs){ 32 | getFile $i 33 | } -------------------------------------------------------------------------------- /iis/mlogc.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /iis/mymodule.def: -------------------------------------------------------------------------------- 1 | LIBRARY "ModSecurityIIS" 2 | 3 | EXPORTS 4 | RegisterModule 5 | -------------------------------------------------------------------------------- /iis/mymodule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef __MY_MODULE_H__ 16 | #define __MY_MODULE_H__ 17 | 18 | // The module implementation. 19 | // This class is responsible for implementing the 20 | // module functionality for each of the server events 21 | // that it registers for. 22 | class CMyHttpModule : public CHttpModule 23 | { 24 | public: 25 | HANDLE m_hEventLog; 26 | DWORD m_dwPageSize; 27 | CRITICAL_SECTION m_csLock; 28 | 29 | REQUEST_NOTIFICATION_STATUS 30 | OnBeginRequest( 31 | IN IHttpContext * pHttpContext, 32 | IN IHttpEventProvider * pProvider 33 | ); 34 | 35 | REQUEST_NOTIFICATION_STATUS 36 | OnSendResponse( 37 | IN IHttpContext * pHttpContext, 38 | IN ISendResponseProvider * pProvider 39 | ); 40 | 41 | REQUEST_NOTIFICATION_STATUS 42 | OnPostEndRequest( 43 | IN IHttpContext * pHttpContext, 44 | IN IHttpEventProvider * pProvider 45 | ); 46 | 47 | HRESULT ReadFileChunk(HTTP_DATA_CHUNK *chunk, char *buf); 48 | 49 | CMyHttpModule(); 50 | ~CMyHttpModule(); 51 | 52 | void Dispose(); 53 | 54 | BOOL WriteEventViewerLog(LPCSTR szNotification, WORD category = EVENTLOG_INFORMATION_TYPE); 55 | BOOL status_call_already_sent; 56 | }; 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /iis/mymodulefactory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef __MODULE_FACTORY_H__ 16 | #define __MODULE_FACTORY_H__ 17 | 18 | // Factory class for CMyHttpModule. 19 | // This class is responsible for creating instances 20 | // of CMyHttpModule for each request. 21 | class CMyHttpModuleFactory : public IHttpModuleFactory 22 | { 23 | CMyHttpModule * m_pModule; 24 | CRITICAL_SECTION m_csLock; 25 | 26 | public: 27 | CMyHttpModuleFactory() 28 | { 29 | m_pModule = NULL; 30 | 31 | InitializeCriticalSection(&m_csLock); 32 | } 33 | 34 | virtual 35 | HRESULT 36 | GetHttpModule( 37 | OUT CHttpModule **ppModule, 38 | IN IModuleAllocator * 39 | ) 40 | { 41 | HRESULT hr = S_OK; 42 | 43 | if ( ppModule == NULL ) 44 | { 45 | hr = HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ); 46 | goto Finished; 47 | } 48 | 49 | EnterCriticalSection(&m_csLock); 50 | 51 | if(m_pModule == NULL) 52 | { 53 | m_pModule = new CMyHttpModule(); 54 | 55 | if ( m_pModule == NULL ) 56 | { 57 | hr = HRESULT_FROM_WIN32( ERROR_NOT_ENOUGH_MEMORY ); 58 | goto Finished; 59 | } 60 | } 61 | 62 | LeaveCriticalSection(&m_csLock); 63 | 64 | *ppModule = m_pModule; 65 | 66 | Finished: 67 | 68 | return hr; 69 | } 70 | 71 | virtual 72 | void 73 | Terminate() 74 | { 75 | if ( m_pModule != NULL ) 76 | { 77 | //m_pModule->WriteEventViewerLog("Module terminated."); 78 | delete m_pModule; 79 | m_pModule = NULL; 80 | } 81 | 82 | delete this; 83 | } 84 | }; 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /iis/wix/Microsoft_VC110_CRT_x64.msm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/wix/Microsoft_VC110_CRT_x64.msm -------------------------------------------------------------------------------- /iis/wix/Microsoft_VC110_CRT_x86.msm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/wix/Microsoft_VC110_CRT_x86.msm -------------------------------------------------------------------------------- /iis/wix/Microsoft_VC120_CRT_x64.msm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/wix/Microsoft_VC120_CRT_x64.msm -------------------------------------------------------------------------------- /iis/wix/Microsoft_VC120_CRT_x86.msm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/wix/Microsoft_VC120_CRT_x86.msm -------------------------------------------------------------------------------- /iis/wix/README.TXT: -------------------------------------------------------------------------------- 1 | Please note that installing ModSecurity for IIS requires IIS to be installed and enabled. 2 | 3 | 4 | After installing ModSecurity for IIS, the module will be running in all websites by default. To remove from a website add to web.config: 5 | 6 | 7 | 8 | 9 | 10 | To configure module in a website add to web.config: 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | where configFile is standard ModSecurity config file. 20 | 21 | Events from the module will show up in "Application" Windows log. 22 | -------------------------------------------------------------------------------- /iis/wix/banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/wix/banner.jpg -------------------------------------------------------------------------------- /iis/wix/dialog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/iis/wix/dialog.jpg -------------------------------------------------------------------------------- /iis/wix/list_dependencies.bat: -------------------------------------------------------------------------------- 1 | 2 | @echo off 3 | 4 | echo * 5 | echo * 6 | echo * ModSecurityIIS - list dependencies 7 | echo * 8 | echo * 9 | echo * This script is likely to be used as part as a debugging process. 10 | echo * 11 | echo * 12 | echo * The main function of this script is to list all ModSecurityIIS runtime 13 | echo * dependencies, including system dependencies, to check if there is a 14 | echo * missing library or a version mismatch. This can be very usefull in case 15 | echo * ModSecurityIIS refuses to register as IIS module or if IIS refuses to 16 | echo * start. 17 | echo * 18 | echo * 19 | echo * 20 | 21 | pause 22 | 23 | :LOOP_FILE 24 | SET /a log_file=%RANDOM%+100000 25 | SET log_file=%TEMP%\ModSecurityIIS-depedencies-%log_file:~-5%.TXT 26 | IF EXIST %log_file% GOTO LOOP_FILE 27 | 28 | echo Saving logs at: %log_file% 29 | 30 | set POSSIBLE_PATHS_X86="C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\dumpbin.exe" "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\dumpbin.exe" 31 | set POSSIBLE_PATHS_X64="C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\bin\x86_amd64\dumpbin.exe" 32 | 33 | for %%i in (%POSSIBLE_PATHS_X86%) do ( 34 | echo Checking for dumpbin x86... %%i 35 | echo Checking for dumpbin x86... %%i >> %log_file% 36 | if exist %%i ( 37 | SET DUMPBIN_X86=%%i 38 | goto found_x86 39 | ) 40 | ) 41 | :found_x86 42 | 43 | for %%i in (%POSSIBLE_PATHS_X64%) do ( 44 | echo Checking for dumpbin x64... %%i 45 | echo Checking for dumpbin x64... %%i >> %log_file% 46 | if exist %%i ( 47 | SET DUMPBIN_X64=%%i 48 | goto found_x64 49 | ) 50 | ) 51 | :found_x64 52 | 53 | if "%DUMPBIN_X86:~1,-1%" == "" ( 54 | echo Dumpbin x86 not found. 55 | echo Dumpbin x86 not found. >> %log_file% 56 | ) else ( 57 | echo Using dumpbin x86: %DUMPBIN_X86% 58 | echo Using dumpbin x86: %DUMPBIN_X86% >> %log_file% 59 | %DUMPBIN_X86% /imports /dependents %* >> %log_file% 60 | ) 61 | ) 62 | 63 | if "%DUMPBIN_X64:~1,-1%" == "" ( 64 | echo Dumpbin x64 not found. 65 | echo Dumpbin x64 not found. >> %log_file% 66 | ) else ( 67 | echo Using dumpbin x64: %DUMPBIN_X64% 68 | echo Using dumpbin x64: %DUMPBIN_X64% >> %log_file% 69 | %DUMPBIN_X64% /imports /dependents %* >> %log_file% 70 | ) 71 | 72 | goto exit 73 | 74 | :exit 75 | echo Logs were saved at: %log_file%. 76 | echo Trying to open it with explorer... 77 | explorer %log_file% 78 | echo Done. 79 | pause 80 | -------------------------------------------------------------------------------- /iis/wix/modsecurity_iis.conf: -------------------------------------------------------------------------------- 1 | Include modsecurity.conf 2 | Include modsecurity_crs_10_setup.conf 3 | Include owasp_crs\base_rules\*.conf 4 | -------------------------------------------------------------------------------- /mlogc/INSTALL: -------------------------------------------------------------------------------- 1 | ModSecurity Audit Log Collector (mlogc) 2 | 3 | Mlogc is used to connect a ModSecurity sensor to the central 4 | audit log repository. 5 | 6 | To Install: 7 | =========== 8 | 9 | 1) Copy the mlogc executable to an appropriate location. 10 | 11 | A good location might be /usr/local/bin, /opt/mlogc/bin, etc. 12 | 13 | 2) Create sensor in the central audit log repository. Note the 14 | username and the password (SENSOR_USERNAME, SENSOR_PASSWORD). 15 | Also note the IP address central repository listens on 16 | (CONSOLE_IP_ADDRESS). 17 | 18 | 3) Configure the ModSecurity sensor to use mlogc 19 | 20 | # Use ReleventOnly auditing 21 | SecAuditEngine RelevantOnly 22 | 23 | # Must use concurrent logging 24 | SecAuditLogType Concurrent 25 | 26 | # Send all audit log parts 27 | SecAuditLogParts ABIDEFGHZ 28 | 29 | # Use the same /CollectorRoot/LogStorageDir as in mlogc.conf 30 | SecAuditLogStorageDir /var/log/mlogc/data 31 | 32 | # Pipe audit log to mlogc with your configuration 33 | SecAuditLog "|/usr/local/bin/mlogc /etc/mlogc.conf" 34 | 35 | 4) Using the mlogc-default.conf as a template, configure the logger. 36 | 37 | Typically these are the only directives that will need to be modified 38 | to conform to your site: 39 | 40 | # Points to the root of the installation. All relative 41 | # paths configured in this file will be resolved with the 42 | # help of this path (LogStorageDir, TransactionLog, etc.) 43 | # 44 | # Typically, this will be the parent directory that is configured 45 | # in ModSecurity for the SecAuditLogStorageDirectory. So, if 46 | # your SecAuditLogStorageDirectory is set to /var/log/mlogc/data, 47 | # then set this to /var/log/mlogc. 48 | CollectorRoot "/var/log/mlogc" 49 | 50 | # ModSecurity Console receiving URI. You can change the host 51 | # and the port parts but leave everything else as is. 52 | ConsoleURI https://CONSOLE_IP_ADDRESS:8886/rpc/auditLogReceiver 53 | 54 | # Sensor credentials 55 | SensorUsername "SENSOR_USERNAME" 56 | SensorPassword "SENSOR_PASSWORD" 57 | 58 | # Base directory where the audit logs are stored. This can be specified 59 | # as a path relative to the CollectorRoot, or a full path. It should 60 | # resolve to the same path as ModSecurity's SecAuditLogStorageDirectory. 61 | LogStorageDir "data" 62 | 63 | See the mlogc-default.conf configuration file for details on other 64 | configuration directives. 65 | 66 | 5) Restart the ModSecurity sensor. 67 | 68 | From now on every audit log generated will go to the repository. Make 69 | sure you create an alert. Transactions without alerts will be recorded 70 | but not displayed on the home page. 71 | 72 | To troubleshoot, generate alerts and observe file "mlogc-error.log". 73 | 74 | If mlogc fails to connect to the server it will pause for a period 75 | of time (60 seconds by default) before it will try again. 76 | 77 | -------------------------------------------------------------------------------- /mlogc/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | bin_SCRIPTS = mlogc-batch-load.pl 3 | 4 | bin_PROGRAMS = mlogc 5 | 6 | mlogc_SOURCES = mlogc.c 7 | 8 | mlogc_CPPFLAGS = @APR_CPPFLAGS@ \ 9 | @PCRE_CPPFLAGS@ \ 10 | @CURL_CPPFLAGS@ \ 11 | -I$(top_srcdir)/apache2 12 | 13 | mlogc_CFLAGS = @APR_CFLAGS@ \ 14 | @CURL_CFLAGS@ \ 15 | @PCRE_CFLAGS@ 16 | 17 | mlogc_LDFLAGS = @APR_LDFLAGS@ \ 18 | @CURL_LDFLAGS@ \ 19 | @PCRE_LDFLAGS@ 20 | 21 | mlogc_LDADD = @APR_LDADD@ \ 22 | @CURL_LDADD@ \ 23 | @PCRE_LDADD@ 24 | -------------------------------------------------------------------------------- /mlogc/Makefile.win: -------------------------------------------------------------------------------- 1 | ########################################################################### 2 | ### You Will need to modify the following variables for your system 3 | ########################################################################### 4 | ########################################################################### 5 | 6 | # Path to Apache httpd installation 7 | BASE = %APACHE% 8 | 9 | # Paths to required libraries 10 | PCRE = %PCRE% 11 | CURL = %CURL% 12 | 13 | # Linking libraries 14 | LIBS = $(BASE)\lib\libapr-1.lib \ 15 | $(BASE)\lib\libaprutil-1.lib \ 16 | $(PCRE)\pcre.lib \ 17 | $(CURL)\libcurl.lib \ 18 | wsock32.lib 19 | 20 | ########################################################################### 21 | ########################################################################### 22 | 23 | CC = cL 24 | 25 | MT = mt 26 | 27 | DEFS = /nologo /O2 /W3 -DWIN32 -DWINNT -Dinline=APR_INLINE -D_CONSOLE -D$(VERSION) 28 | 29 | EXE = mlogc.exe 30 | 31 | INCLUDES = -I. -I..\apache2 \ 32 | -I$(PCRE)\include -I$(PCRE) \ 33 | -I$(CURL)\include -I$(CURL) \ 34 | -I$(BASE)\include 35 | 36 | CFLAGS= -MT $(INCLUDES) $(DEFS) 37 | 38 | LDFLAGS = 39 | 40 | OBJS = mlogc.obj 41 | 42 | all: $(EXE) 43 | 44 | .c.obj: 45 | $(CC) $(CFLAGS) -c $< -Fo$@ 46 | 47 | .cpp.obj: 48 | $(CC) $(CFLAGS) -c $< -Fo$@ 49 | 50 | $(EXE): $(OBJS) 51 | $(CC) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) /link /NODEFAULTLIB:MSVCRT.lib /subsystem:console 52 | 53 | install: $(EXE) 54 | copy $(EXE) $(BASE)\bin 55 | 56 | clean: 57 | del $(OBJS) $(EXE) *.dll *.lib *.pdb *.idb *.ilk *.exp *.res *.rc *.bin *.manifest 58 | -------------------------------------------------------------------------------- /nginx/TODO: -------------------------------------------------------------------------------- 1 | Modsecurity NGINX TODO 2 | 3 | * Code Cleanup 4 | 5 | * Create a method for action DROP as in Apache 6 | 7 | * Add CRS Support 8 | 9 | * Specific NGINX config file 10 | 11 | * Separate nginx/ IIS/ apache/ and generic/ folders 12 | 13 | * Source code documentation (insert doxygen headers) 14 | 15 | * Create better build infrastructure with support for tests and automated regression 16 | 17 | * Better things for test 18 | -------------------------------------------------------------------------------- /nginx/modsecurity/apr_bucket_nginx.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "apr_buckets.h" 4 | 5 | apr_bucket * apr_bucket_nginx_create(ngx_buf_t *buf, apr_bucket_alloc_t *list); 6 | 7 | apr_bucket * apr_bucket_nginx_make(apr_bucket *e, ngx_buf_t *buf); 8 | 9 | #define ngx_buf_to_apr_bucket apr_bucket_nginx_create 10 | 11 | ngx_int_t copy_chain_to_brigade(ngx_chain_t *chain, apr_bucket_brigade *bb, ngx_int_t last_buf); 12 | -------------------------------------------------------------------------------- /nginx/modsecurity/config.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | CFLAGS="$CFLAGS \ 4 | @APR_CFLAGS@ \ 5 | @APU_CFLAGS@ \ 6 | @APXS_CFLAGS@ \ 7 | @LIBXML2_CFLAGS@ \ 8 | @LUA_CFLAGS@ \ 9 | @MODSEC_EXTRA_CFLAGS@ \ 10 | @PCRE_CFLAGS@ \ 11 | @YAJL_CFLAGS@ \ 12 | @SSDEEP_CFLAGS@" 13 | 14 | 15 | CORE_LIBS="$CORE_LIBS \ 16 | @APR_LINKLD@ \ 17 | @APU_LINKLD@ \ 18 | @APXS_CFLAGS@ \ 19 | @CURL_LDADD@ \ 20 | @LIBXML2_LDADD@ \ 21 | @LUA_LDADD@ \ 22 | @PCRE_LDADD@ \ 23 | @APXS_LIBS@ \ 24 | @YAJL_LIBS@ \ 25 | @SSDEEP_LDFLAGS@ \ 26 | -lstdc++" 27 | 28 | ngx_addon_name=ngx_http_modsecurity 29 | 30 | CORE_MODULES="$CORE_MODULES" 31 | 32 | HTTP_AUX_FILTER_MODULES="ngx_http_modsecurity $HTTP_AUX_FILTER_MODULES" 33 | 34 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS \ 35 | $ngx_addon_dir/ngx_http_modsecurity.c \ 36 | $ngx_addon_dir/ngx_http_modsecurity_config_cache.c \ 37 | $ngx_addon_dir/apr_bucket_nginx.c" 38 | 39 | NGX_ADDON_DEPS="$NGX_ADDON_DEPS \ 40 | $ngx_addon_dir/ngx_http_modsecurity_config_cache.h \ 41 | $ngx_addon_dir/apr_bucket_nginx.h" 42 | 43 | CORE_LIBS="$ngx_addon_dir/../../standalone/.libs/standalone.a $CORE_LIBS" 44 | 45 | CORE_INCS="$CORE_INCS \ 46 | $ngx_addon_dir \ 47 | $ngx_addon_dir/../../standalone \ 48 | $ngx_addon_dir/../../apache2" 49 | 50 | -------------------------------------------------------------------------------- /nginx/modsecurity/ngx_http_modsecurity_config_cache.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | /* 7 | * ModSecurity configuration cache is used to prevent loading configuration 8 | * multiple times if one and the same configuration file is applied in multiple 9 | * different contexts. 10 | * 11 | * The main problem with loading ModSecurity configuration independently for each 12 | * context is that the allocated memory block can be quite large (10-20 Mb) so if, 13 | * for example, the same configuration is used for 10-20 listeners it will cause 14 | * significant memory overuse for no good reason. 15 | * 16 | * The cache helps alleviate this by storing pointers to configuration objects created 17 | * from ModSecurity configuration files and re-using existing objects when the same path 18 | * occurs several times during Nginx configuration loading. 19 | */ 20 | 21 | typedef struct directory_config directory_config; 22 | 23 | typedef struct { 24 | ngx_rbtree_t rbtree; 25 | } ngx_http_modsecurity_config_cache_t; 26 | 27 | /* Create configuration cache */ 28 | ngx_http_modsecurity_config_cache_t *ngx_http_modsecurity_config_cache_init(ngx_conf_t *cf); 29 | 30 | /* Add configuration block for the respective file path into configuration cache */ 31 | ngx_int_t ngx_http_modsecurity_config_cache_insert(ngx_http_modsecurity_config_cache_t *cache, 32 | ngx_conf_t *cf, ngx_str_t *path, directory_config *config); 33 | 34 | /* Look up configuration block for the respective file path in configuration cache */ 35 | directory_config *ngx_http_modsecurity_config_cache_lookup(ngx_http_modsecurity_config_cache_t *cache, 36 | ngx_str_t *path); 37 | -------------------------------------------------------------------------------- /stamp-h1: -------------------------------------------------------------------------------- 1 | timestamp for modsecurity_config_auto.h 2 | -------------------------------------------------------------------------------- /standalone/hooks.c: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #include 16 | 17 | #include "http_core.h" 18 | #include "http_request.h" 19 | 20 | #include "modsecurity.h" 21 | #include "apache2.h" 22 | #include "http_main.h" 23 | #include "http_connection.h" 24 | 25 | #include "apr_optional.h" 26 | #include "mod_log_config.h" 27 | 28 | #include "msc_logging.h" 29 | #include "msc_util.h" 30 | 31 | #include "ap_mpm.h" 32 | #include "scoreboard.h" 33 | 34 | #include "apr_version.h" 35 | 36 | #include "apr_lib.h" 37 | #include "ap_config.h" 38 | #include "http_config.h" 39 | #include "hooks.h" 40 | 41 | #define DECLARE_EXTERNAL_HOOK(ns,link,ret,name,args) \ 42 | ns##_HOOK_##name##_t *hookfn_##name = NULL; \ 43 | link##_DECLARE(void) ns##_hook_##name(ns##_HOOK_##name##_t *pf, \ 44 | const char * const *aszPre, \ 45 | const char * const *aszSucc, int nOrder) \ 46 | { \ 47 | hookfn_##name = pf; \ 48 | } 49 | 50 | #define DECLARE_HOOK(ret,name,args) \ 51 | DECLARE_EXTERNAL_HOOK(ap,AP,ret,name,args) 52 | 53 | 54 | DECLARE_HOOK(int,pre_config,(apr_pool_t *pconf,apr_pool_t *plog, apr_pool_t *ptemp)) 55 | DECLARE_HOOK(int,post_config,(apr_pool_t *pconf,apr_pool_t *plog, apr_pool_t *ptemp,server_rec *s)) 56 | DECLARE_HOOK(void,child_init,(apr_pool_t *pchild, server_rec *s)) 57 | DECLARE_HOOK(int,process_connection,(conn_rec *c)) 58 | DECLARE_HOOK(int,post_read_request,(request_rec *r)) 59 | DECLARE_HOOK(int,fixups,(request_rec *r)) 60 | DECLARE_HOOK(void, error_log, (const char *file, int line, int level, 61 | apr_status_t status, const server_rec *s, 62 | const request_rec *r, apr_pool_t *pool, 63 | const char *errstr)) 64 | DECLARE_HOOK(int,log_transaction,(request_rec *r)) 65 | DECLARE_HOOK(void,insert_filter,(request_rec *r)) 66 | DECLARE_HOOK(void,insert_error_filter,(request_rec *r)) 67 | 68 | #ifndef _WIN32 69 | DECLARE_HOOK(void,set_lock_owner,(const char *user, const char *group)) 70 | #endif 71 | -------------------------------------------------------------------------------- /standalone/hooks.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ModSecurity for Apache 2.x, http://www.modsecurity.org/ 3 | * Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/) 4 | * 5 | * You may not use this file except in compliance with 6 | * the License.  You may obtain a copy of the License at 7 | * 8 | *     http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * If any of the files related to licensing are missing or if you have any 11 | * other questions related to licensing please contact Trustwave Holdings, Inc. 12 | * directly using the email address security@modsecurity.org. 13 | */ 14 | 15 | #ifndef _HOOKS_HEADER 16 | #define _HOOKS_HEADER 17 | 18 | #include "http_config.h" 19 | 20 | #ifndef _WIN32 21 | AP_DECLARE_HOOK(void,set_lock_owner,(const char *user, const char *group)) 22 | #endif 23 | 24 | #endif -------------------------------------------------------------------------------- /standalone/modules.mk: -------------------------------------------------------------------------------- 1 | MOD_SECURITY2 = mod_security2 apache2_config apache2_io apache2_util \ 2 | re re_operators re_actions re_tfns re_variables \ 3 | msc_logging msc_xml msc_multipart modsecurity msc_parsers msc_util msc_pcre \ 4 | persist_dbm msc_reqbody pdf_protect msc_geo msc_gsb msc_unicode acmp msc_lua 5 | 6 | H = re.h modsecurity.h msc_logging.h msc_multipart.h msc_parsers.h \ 7 | msc_pcre.h msc_util.h msc_xml.h persist_dbm.h apache2.h pdf_protect.h \ 8 | msc_geo.h msc_gsb.h msc_unicode.h acmp.h utf8tables.h msc_lua.h 9 | 10 | ${MOD_SECURITY2:=.slo}: ${H} 11 | ${MOD_SECURITY2:=.lo}: ${H} 12 | ${MOD_SECURITY2:=.o}: ${H} 13 | 14 | mod_security2.la: ${MOD_SECURITY2:=.slo} 15 | $(SH_LINK) -rpath $(libexecdir) -module -avoid-version ${MOD_SECURITY2:=.lo} 16 | 17 | DISTCLEAN_TARGETS = modules.mk 18 | 19 | shared = mod_security2.la 20 | -------------------------------------------------------------------------------- /standalone/standalone.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "standalone", "standalone.vcxproj", "{20EC871F-B6A0-4398-9B67-A33598A796E8}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Release|Win32 = Release|Win32 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {20EC871F-B6A0-4398-9B67-A33598A796E8}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {20EC871F-B6A0-4398-9B67-A33598A796E8}.Debug|Win32.Build.0 = Debug|Win32 16 | {20EC871F-B6A0-4398-9B67-A33598A796E8}.Debug|x64.ActiveCfg = Debug|x64 17 | {20EC871F-B6A0-4398-9B67-A33598A796E8}.Debug|x64.Build.0 = Debug|x64 18 | {20EC871F-B6A0-4398-9B67-A33598A796E8}.Release|Win32.ActiveCfg = Release|Win32 19 | {20EC871F-B6A0-4398-9B67-A33598A796E8}.Release|Win32.Build.0 = Release|Win32 20 | {20EC871F-B6A0-4398-9B67-A33598A796E8}.Release|x64.ActiveCfg = Release|x64 21 | {20EC871F-B6A0-4398-9B67-A33598A796E8}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /standalone/standalone.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -c d:\temp\antixss.conf -u d:\temp\modsec_urls.txt d:\temp\test1.dat 5 | WindowsLocalDebugger 6 | $(TargetPath) 7 | false 8 | NativeOnly 9 | 10 | 11 | -c d:\xss.conf d:\test.dat 12 | WindowsLocalDebugger 13 | 14 | -------------------------------------------------------------------------------- /tests/CRS_Tests_modsec_dbg.py: -------------------------------------------------------------------------------- 1 | from ftw import ruleset, logchecker, testrunner 2 | import datetime 3 | import pytest 4 | import pdb 5 | import sys 6 | import re 7 | import os 8 | import config 9 | import time 10 | 11 | def test_crs(ruleset, test, logchecker_obj): 12 | # the configuration to this test is done by appveyor.yml, 13 | # the config file points to the modsec conf and sets the regex parsing 14 | 15 | runner = testrunner.TestRunner() 16 | for stage in test.stages: 17 | runner.run_stage(stage, logchecker_obj) 18 | 19 | class FooLogChecker(logchecker.LogChecker): 20 | log_file = None 21 | 22 | def __init__(self): 23 | modsec_conf_file = config.modsecurity_conf_location 24 | with open(modsec_conf_file) as fp: 25 | required_conf_elements = 2 26 | for line in fp: 27 | if 'SecDebugLog ' in line and line[0] != '#': 28 | self.log_file = line.split(' ')[1].rstrip() 29 | required_conf_elements -= 1 30 | 31 | if 'SecDebugLogLevel' in line and line[0] != '#': 32 | required_conf_elements -= 1 33 | 34 | if required_conf_elements == 0: 35 | break 36 | 37 | if required_conf_elements != 0: 38 | sys.exit("Please make sure that SecDebugLog & SecDebugLogLevel in {}".format(config.modsecurity_conf_location)) 39 | 40 | def reverse_readline(self, filename): 41 | with open(filename, 'r') as f: 42 | f.seek(0, os.SEEK_END) 43 | position = f.tell() 44 | line = '' 45 | while position >= 0: 46 | f.seek(position) 47 | next_char = f.read(1) 48 | if next_char == "\n": 49 | yield line[::-1] 50 | line = '' 51 | else: 52 | line += next_char 53 | position -= 1 54 | yield line[::-1] 55 | 56 | def get_logs(self): 57 | log_date_regex = config.log_date_regex 58 | log_date_format = config.log_date_format 59 | pattern = re.compile(r'%s' % log_date_regex) 60 | our_logs = [] 61 | for lline in self.reverse_readline(self.log_file): 62 | # Extract dates from each line 63 | match = re.match(pattern,lline) 64 | if match: 65 | log_date = match.group(1) 66 | # Convert our date 67 | log_date = datetime.datetime.strptime(log_date[:-1], log_date_format) 68 | ftw_start = self.start 69 | # if data is bigger than start add it, otherwise abort 70 | if log_date >= ftw_start.replace(microsecond=0): 71 | our_logs.append(lline) 72 | else: 73 | break 74 | return our_logs 75 | 76 | @pytest.fixture 77 | def logchecker_obj(): 78 | return FooLogChecker() 79 | -------------------------------------------------------------------------------- /tests/Makefile.am: -------------------------------------------------------------------------------- 1 | check_PROGRAMS = msc_test 2 | msc_test_SOURCES = msc_test.c \ 3 | ../apache2/acmp.c \ 4 | ../apache2/libinjection/libinjection_html5.c \ 5 | ../apache2/libinjection/libinjection_sqli.c \ 6 | ../apache2/libinjection/libinjection_xss.c \ 7 | ../apache2/modsecurity.c \ 8 | ../apache2/msc_status_engine.c \ 9 | ../apache2/msc_remote_rules.c \ 10 | ../apache2/msc_crypt.c \ 11 | ../apache2/msc_geo.c \ 12 | ../apache2/msc_gsb.c \ 13 | ../apache2/msc_json.c \ 14 | ../apache2/msc_logging.c \ 15 | ../apache2/msc_lua.c \ 16 | ../apache2/msc_multipart.c \ 17 | ../apache2/msc_parsers.c \ 18 | ../apache2/msc_pcre.c \ 19 | ../apache2/msc_release.c \ 20 | ../apache2/msc_reqbody.c \ 21 | ../apache2/msc_tree.c \ 22 | ../apache2/msc_unicode.c \ 23 | ../apache2/msc_util.c \ 24 | ../apache2/msc_xml.c \ 25 | ../apache2/persist_dbm.c \ 26 | ../apache2/re_actions.c \ 27 | ../apache2/re.c \ 28 | ../apache2/re_operators.c \ 29 | ../apache2/re_tfns.c \ 30 | ../apache2/re_variables.c \ 31 | ../standalone/regex.c \ 32 | ../standalone/server.c \ 33 | ../standalone/config.c 34 | 35 | msc_test_CFLAGS = @APR_CFLAGS@ \ 36 | @APU_CFLAGS@ \ 37 | @APXS_CFLAGS@ \ 38 | @CURL_CFLAGS@ \ 39 | @LIBXML2_CFLAGS@ \ 40 | @LUA_CFLAGS@ \ 41 | @MODSEC_EXTRA_CFLAGS@ \ 42 | @PCRE_CFLAGS@ \ 43 | @YAJL_CFLAGS@ \ 44 | @SSDEEP_CFLAGS@ 45 | 46 | msc_test_CPPFLAGS = -I$(top_srcdir)/apache2 \ 47 | @APR_CPPFLAGS@ \ 48 | @CURL_CPPFLAGS@ \ 49 | @LIBXML2_CFLAGS@ \ 50 | @LIBXML2_CPPFLAGS@ \ 51 | @PCRE_CPPFLAGS@ 52 | 53 | msc_test_LDADD = @APR_LDADD@ \ 54 | @APU_LDADD@ \ 55 | @CURL_LDADD@ \ 56 | @LIBXML2_CFLAGS@ \ 57 | @LIBXML2_LDADD@ \ 58 | @LUA_LDADD@ \ 59 | @PCRE_LDADD@ \ 60 | @YAJL_LDADD@ \ 61 | @SSDEEP_CFLAGS@ 62 | 63 | msc_test_LDFLAGS = @APR_LDFLAGS@ \ 64 | @APU_LDFLAGS@ \ 65 | @APXS_LDFLAGS@ \ 66 | @CURL_LDFLAGS@ \ 67 | @LIBXML2_LDFLAGS@ \ 68 | @LUA_LDFLAGS@ \ 69 | @PCRE_LDFLAGS@ \ 70 | @YAJL_LDFLAGS@ \ 71 | @SSDEEP_LDFLAGS@ 72 | 73 | check_SCRIPTS = run-unit-tests.pl 74 | TESTS = $(check_SCRIPTS) 75 | 76 | test: check 77 | 78 | test-regression: run-regression-tests.pl 79 | $(PERL) run-regression-tests.pl 80 | 81 | test-regression-nginx: run-regression-tests-nginx.pl 82 | $(PERL) run-regression-tests-nginx.pl 83 | 84 | .PHONY: test test-regression 85 | -------------------------------------------------------------------------------- /tests/Parse_test_res.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | import os, sys 4 | import config 5 | 6 | def main(): 7 | fname = sys.argv[1] 8 | no_res = [] 9 | bad_assert = [] 10 | num_of_tests = 0 11 | 12 | with open(fname, 'r') as f: 13 | l = f.readline() 14 | while l: 15 | num_of_tests += 1 16 | if l[0] == 'F': 17 | id = l.split(' -- ')[1].rstrip()[:-1] 18 | n = f.readline() 19 | if 'No response from server' in n: 20 | no_res.append(id) 21 | else: 22 | bad_assert.append(id) 23 | l = f.readline() 24 | 25 | print("Total tests attempted: {}".format(num_of_tests)) 26 | print("No response from server: {}".format(no_res)) 27 | print("Assert failure: {}".format(bad_assert)) 28 | known_fail = config.failing_tests 29 | unknown_fail = [x for x in bad_assert if x not in known_fail] 30 | print("unknown failure: {}".format(unknown_fail)) 31 | if unknown_fail or len(no_res) > num_of_tests/10: 32 | print("Test failed") 33 | exit(1) 34 | 35 | if __name__ == "__main__": 36 | main() 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/action/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/tests/action/.empty -------------------------------------------------------------------------------- /tests/config.py: -------------------------------------------------------------------------------- 1 | # Location of modsecurity.conf 2 | modsecurity_conf_location = "C:\projects\ModSecurity\iis\wix\modsecurity.conf" 3 | 4 | # 5 | #[27/Sep/2018:15:35:09 --0700] - but python has issues with %z so we trim it 6 | log_date_format = "%d/%b/%Y:%H:%M:%S" 7 | #[27/Sep/2018:15:35:09 --0700] 8 | log_date_regex = "\[(\d{1,2}\/[A-Z][a-z]{2}\/\d{4}:\d{1,2}:\d{1,2}:\d{1,2} )" 9 | 10 | # Regular expression to filter for timestamp in Apache Error Log 11 | # 12 | # Default timestamp format: (example: [Thu Nov 09 09:04:38.912314 2017]) 13 | # log_date_regex = "\[([A-Z][a-z]{2} [A-z][a-z]{2} \d{1,2} \d{1,2}\:\d{1,2}\:\d{1,2}\.\d+? \d{4})\]" 14 | # 15 | # Reverse format: (example: [2017-11-09 08:25:03.002312]) 16 | #log_date_regex = "\[([0-9-]{10} [0-9:.]{15})\]" 17 | 18 | # Date format matching the timestamp format used by Apache 19 | # in order to generate matching timestamp ourself 20 | # 21 | # Default timestamp format: (example: see above) 22 | # log_date_format = "%a %b %d %H:%M:%S.%f %Y" 23 | # 24 | # Reverse format: (example: see above) 25 | #log_date_format = "%Y-%m-%d %H:%M:%S.%f" 26 | failing_tests = ['920100-10', '920100-12', '920100-14', '920100-2', '920100-4', '920100-6', '920100-8', '920160-4', '920170-5', '920170-6', '920180-1', '920180-3', '920200-3', '920200-4', '920200-7', '920200-9', '920210-5', '920220-2', '920240-2', '920260-2', '920270-6', '920271-5', '920271-6', '920272-4', '920273-2', '920273-4', '920274-5', '920290-1', '920310-2', '920310-5', '920311-2', '920320-2', '920330-2', '920350-2', '920420-9', '920430-8', '920450-5', '920450-8', '920470-4', '920470-5', '932100-3', '933110-11', '933110-19', '933130-3', '933130-6', '933151-3', '933151-5', '933160-22', '933161-5', '941100-4', '941120-1', '941160-1FN', '941310-1', '942420-1', '943110-4', '944100-11', '944100-12', '944100-15', '944100-16', '944110-11', '944110-12', '944110-15', '944110-16', '944120-107', '944120-108', '944120-124', '944120-125', '944120-22', '944120-23', '944120-39', '944120-40', '944120-5', '944120-56', '944120-57', '944120-6', '944120-73', '944120-74', '944120-90', '944120-91', '944210-22', '944210-23', '944210-39', '944210-40', '944210-5', '944210-6', '920200-10', '920240-3', '920270-7', '920310-3', '920310-6', '920470-6', '942480-2', '920220-3', '941100-5FN', '941110-2', '933160-21', '920311-3', '921110-5', '942500-1'] 27 | -------------------------------------------------------------------------------- /tests/csv_rx-pm.pl.in: -------------------------------------------------------------------------------- 1 | #!@PERL@ 2 | # 3 | # Example to generate CSV performance data from test results taken from 4 | # test generated by gen_rx-pm.pl. 5 | # 6 | use strict; 7 | 8 | my %H = (); 9 | while (<>) { 10 | chomp; 11 | my ($op, $label, $n, $i, $value) = (m/\s*\d+\)\s+\S+\s+"([^"]*)"\s+(\S+)\s+(\d+) item\(s\): passed\s+\((\d+)\s+\@\s+([-\+\d\.E]+) msec\s.*/); 12 | 13 | next unless defined($value); 14 | $H{$n}{$label} = $value; 15 | 16 | } 17 | 18 | printf "%s, %s, %s, %s\n", qw(N rx1 rx2 pm1); 19 | for (sort {$a <=> $b} keys %H) { 20 | printf "%s, %s, %s, %s\n", $_, $H{$_}{rx1}, $H{$_}{rx2}, $H{$_}{pm1} 21 | }; 22 | -------------------------------------------------------------------------------- /tests/gen_rx-pm.pl.in: -------------------------------------------------------------------------------- 1 | #!@PERL@ 2 | # 3 | # Generates a test file for comparing @rx and @pm speed. 4 | # 5 | use strict; 6 | use Regexp::Assemble; 7 | 8 | srand(424242); # We want this static, so we can compare different runs 9 | 10 | my $MIN = $ARGV[0] || 0; 11 | my $MAX = $ARGV[1] || 5000; 12 | my $INC = $ARGV[2] || int($MAX * .05); 13 | my $ITERATIONS = 10000; 14 | my $MINSTRLEN = 2; 15 | my $MAXSTRLEN = 8; 16 | 17 | my $match = join '', ('a' .. 'z'); 18 | my @param = (); 19 | my $i=$MIN; 20 | while ($i <= $MAX) { 21 | my $ra = Regexp::Assemble->new; 22 | 23 | while (@param < $i) { 24 | unshift @param, rndstr(); 25 | } 26 | 27 | $ra->add(@param); 28 | 29 | printf ( 30 | "# rx: %6d\n". 31 | "{\n". 32 | " comment => \"rx1 %6d item(s)\",\n". 33 | " type => \"op\",\n". 34 | " name => \"rx\",\n". 35 | " param => qr/%s/,\n". 36 | " input => \"%s\",\n". 37 | " ret => " . (@param ? 0 : 1) . ",". 38 | " iterations => %d,\n". 39 | "},\n", 40 | $i, 41 | $i, 42 | (@param ? '(?:' . join('|', @param) . ')' : ""), 43 | $match, 44 | $ITERATIONS, 45 | ); 46 | 47 | printf ( 48 | "# rx-optimized: %6d\n". 49 | "{\n". 50 | " comment => \"rx2 %6d item(s)\",\n". 51 | " type => \"op\",\n". 52 | " name => \"rx\",\n". 53 | " param => qr/%s/,\n". 54 | " input => \"%s\",\n". 55 | " ret => " . (@param ? 0 : 1) . ",". 56 | " iterations => %d,\n". 57 | "},\n", 58 | $i, 59 | $i, 60 | (@param ? $ra->as_string : ""), 61 | $match, 62 | $ITERATIONS, 63 | ); 64 | 65 | printf ( 66 | "# pm: %6d\n". 67 | "{\n". 68 | " comment => \"pm1 %6d item(s)\",\n". 69 | " type => \"op\",\n". 70 | " name => \"pm\",\n". 71 | " param => \"%s\",\n". 72 | " input => \"%s\",\n". 73 | " ret => 0,". 74 | " iterations => %d,\n". 75 | "},\n", 76 | $i, 77 | $i, 78 | join(' ', @param ? @param : ("''")), 79 | $match, 80 | $ITERATIONS, 81 | ); 82 | 83 | $i = ($i == $MIN) ? ($i + $INC) - ($i % $INC) : $i + $INC; 84 | 85 | } 86 | 87 | sub rndstr { 88 | my @c = ('a' .. 'z'); 89 | my $rndstr; 90 | my $max = int(rand($MAXSTRLEN - $MINSTRLEN)) + $MINSTRLEN; 91 | foreach (1 .. $max) { 92 | $rndstr .= $c[rand @c]; 93 | } 94 | # We need a string that is not in another string for "last" 95 | if ($match =~ m/$rndstr/) { 96 | $rndstr = rndstr(); 97 | } 98 | return $rndstr; 99 | } 100 | -------------------------------------------------------------------------------- /tests/op/beginsWith.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "beginsWith", 5 | param => "", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "beginsWith", 12 | param => "TestCase", 13 | input => "", 14 | ret => 0, 15 | }, 16 | { 17 | type => "op", 18 | name => "beginsWith", 19 | param => "", 20 | input => "TestCase", 21 | ret => 1, 22 | }, 23 | 24 | ### General 25 | { 26 | type => "op", 27 | name => "beginsWith", 28 | param => "abcdef", 29 | input => "abcdef", 30 | ret => 1, 31 | }, 32 | { 33 | type => "op", 34 | name => "beginsWith", 35 | param => "abcdef", 36 | input => "abcdefghi", 37 | ret => 1, 38 | }, 39 | { 40 | type => "op", 41 | name => "beginsWith", 42 | param => "abcdef", 43 | input => "abc", 44 | ret => 0, 45 | }, 46 | -------------------------------------------------------------------------------- /tests/op/contains.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "contains", 5 | param => "", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "contains", 12 | param => "TestCase", 13 | input => "", 14 | ret => 0, 15 | }, 16 | { 17 | type => "op", 18 | name => "contains", 19 | param => "", 20 | input => "TestCase", 21 | ret => 1, 22 | }, 23 | 24 | ### General 25 | { 26 | type => "op", 27 | name => "contains", 28 | param => "abc", 29 | input => "abcdefghi", 30 | ret => 1, 31 | }, 32 | { 33 | type => "op", 34 | name => "contains", 35 | param => "def", 36 | input => "abcdefghi", 37 | ret => 1, 38 | }, 39 | { 40 | type => "op", 41 | name => "contains", 42 | param => "ghi", 43 | input => "abcdefghi", 44 | ret => 1, 45 | }, 46 | { 47 | type => "op", 48 | name => "contains", 49 | param => "ghij", 50 | input => "abcdefghi", 51 | ret => 0, 52 | }, 53 | { 54 | type => "op", 55 | name => "contains", 56 | param => "x", 57 | input => "x", 58 | ret => 1, 59 | }, 60 | { 61 | type => "op", 62 | name => "contains", 63 | param => "y", 64 | input => "xyz", 65 | ret => 1, 66 | }, 67 | { 68 | type => "op", 69 | name => "contains", 70 | param => "hiding", 71 | input => "hidinX<-not quite, but is later on->hiding", 72 | ret => 1, 73 | }, 74 | -------------------------------------------------------------------------------- /tests/op/containsWord.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "containsWord", 5 | param => "", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "containsWord", 12 | param => "TestCase", 13 | input => "", 14 | ret => 0, 15 | }, 16 | { 17 | type => "op", 18 | name => "containsWord", 19 | param => "", 20 | input => "TestCase", 21 | ret => 1, 22 | }, 23 | 24 | ### General 25 | { 26 | type => "op", 27 | name => "containsWord", 28 | param => "abc", 29 | input => "abcdefghi", 30 | ret => 0, 31 | }, 32 | { 33 | type => "op", 34 | name => "containsWord", 35 | param => "def", 36 | input => "abcdefghi", 37 | ret => 0, 38 | }, 39 | { 40 | type => "op", 41 | name => "containsWord", 42 | param => "ghi", 43 | input => "abcdefghi", 44 | ret => 0, 45 | }, 46 | { 47 | type => "op", 48 | name => "containsWord", 49 | param => "abc", 50 | input => "abc def ghi", 51 | ret => 1, 52 | }, 53 | { 54 | type => "op", 55 | name => "containsWord", 56 | param => "def", 57 | input => "abc def ghi", 58 | ret => 1, 59 | }, 60 | { 61 | type => "op", 62 | name => "containsWord", 63 | param => "ghi", 64 | input => "abc def ghi", 65 | ret => 1, 66 | }, 67 | { 68 | type => "op", 69 | name => "containsWord", 70 | param => "abc", 71 | input => "abc\0def ghi", 72 | ret => 1, 73 | }, 74 | { 75 | type => "op", 76 | name => "containsWord", 77 | param => "def", 78 | input => "abc\0def ghi", 79 | ret => 1, 80 | }, 81 | { 82 | type => "op", 83 | name => "containsWord", 84 | param => "x", 85 | input => "x", 86 | ret => 1, 87 | }, 88 | { 89 | type => "op", 90 | name => "containsWord", 91 | param => "x", 92 | input => " x ", 93 | ret => 1, 94 | }, 95 | { 96 | type => "op", 97 | name => "containsWord", 98 | param => "y", 99 | input => "xyz", 100 | ret => 0, 101 | }, 102 | { 103 | type => "op", 104 | name => "containsWord", 105 | param => "hiding", 106 | input => "hidingX<-not on word boundary, but is later on->hiding", 107 | ret => 1, 108 | }, 109 | -------------------------------------------------------------------------------- /tests/op/detectSQLi.t: -------------------------------------------------------------------------------- 1 | { 2 | type => "op", 3 | name => "detectSQLi", 4 | input => "", 5 | ret => 0 6 | }, 7 | { 8 | type => "op", 9 | name => "detectSQLi", 10 | input => "this is not isqli", 11 | ret => 0 12 | }, 13 | { 14 | type => "op", 15 | name => "detectSQLi", 16 | input => "ascii(substring(version() from 1 for 1))", 17 | ret => 1 18 | } 19 | -------------------------------------------------------------------------------- /tests/op/detectXSS.t: -------------------------------------------------------------------------------- 1 | { 2 | type => "op", 3 | name => "detectXSS", 4 | input => "", 5 | ret => 0 6 | }, 7 | { 8 | type => "op", 9 | name => "detectXSS", 10 | input => "this is not an XSS", 11 | ret => 0 12 | }, 13 | { 14 | type => "op", 15 | name => "detectXSS", 16 | input => ")", 17 | ret => 1 18 | } 19 | -------------------------------------------------------------------------------- /tests/op/endsWith.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "endsWith", 5 | param => "", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "endsWith", 12 | param => "TestCase", 13 | input => "", 14 | ret => 0, 15 | }, 16 | { 17 | type => "op", 18 | name => "endsWith", 19 | param => "", 20 | input => "TestCase", 21 | ret => 1, 22 | }, 23 | 24 | ### General 25 | { 26 | type => "op", 27 | name => "endsWith", 28 | param => "abc", 29 | input => "abcdefghi", 30 | ret => 0, 31 | }, 32 | { 33 | type => "op", 34 | name => "endsWith", 35 | param => "def", 36 | input => "abcdefghi", 37 | ret => 0, 38 | }, 39 | { 40 | type => "op", 41 | name => "endsWith", 42 | param => "ghi", 43 | input => "abcdefghi", 44 | ret => 1, 45 | }, 46 | { 47 | type => "op", 48 | name => "endsWith", 49 | param => "ghi", 50 | input => "abcdef\0ghi", 51 | ret => 1, 52 | }, 53 | -------------------------------------------------------------------------------- /tests/op/eq.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "eq", 5 | param => "0", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "eq", 12 | param => "5", 13 | input => "", 14 | ret => 0, 15 | }, 16 | 17 | ### Invalid 18 | # xxx interpreted as 0 19 | { 20 | type => "op", 21 | name => "eq", 22 | param => "xxx", 23 | input => "0", 24 | ret => 1, 25 | }, 26 | # xxx interpreted as 0 27 | { 28 | type => "op", 29 | name => "eq", 30 | param => "xxx", 31 | input => "5", 32 | ret => 0, 33 | }, 34 | # xxx interpreted as 0 35 | { 36 | type => "op", 37 | name => "eq", 38 | param => "xxx", 39 | input => "-1", 40 | ret => 0, 41 | }, 42 | # xxx interpreted as 0 43 | { 44 | type => "op", 45 | name => "eq", 46 | param => "0", 47 | input => "xxx", 48 | ret => 1, 49 | }, 50 | # xxx interpreted as 0 51 | { 52 | type => "op", 53 | name => "eq", 54 | param => "5", 55 | input => "xxx", 56 | ret => 0, 57 | }, 58 | 59 | ### General 60 | { 61 | type => "op", 62 | name => "eq", 63 | param => "0", 64 | input => "-5", 65 | ret => 0, 66 | }, 67 | { 68 | type => "op", 69 | name => "eq", 70 | param => "0", 71 | input => "0", 72 | ret => 1, 73 | }, 74 | { 75 | type => "op", 76 | name => "eq", 77 | param => "0", 78 | input => "5", 79 | ret => 0, 80 | }, 81 | { 82 | type => "op", 83 | name => "eq", 84 | param => "5", 85 | input => "0", 86 | ret => 0, 87 | }, 88 | { 89 | type => "op", 90 | name => "eq", 91 | param => "5", 92 | input => "5", 93 | ret => 1, 94 | }, 95 | { 96 | type => "op", 97 | name => "eq", 98 | param => "5", 99 | input => "10", 100 | ret => 0, 101 | }, 102 | -------------------------------------------------------------------------------- /tests/op/ge.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "ge", 5 | param => "0", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "ge", 12 | param => "5", 13 | input => "", 14 | ret => 0, 15 | }, 16 | 17 | ### Invalid 18 | # xxx interpreted as 0 19 | { 20 | type => "op", 21 | name => "ge", 22 | param => "xxx", 23 | input => "5", 24 | ret => 1, 25 | }, 26 | # xxx interpreted as 0 27 | { 28 | type => "op", 29 | name => "ge", 30 | param => "xxx", 31 | input => "-1", 32 | ret => 0, 33 | }, 34 | # xxx interpreted as 0 35 | { 36 | type => "op", 37 | name => "ge", 38 | param => "0", 39 | input => "xxx", 40 | ret => 1, 41 | }, 42 | # xxx interpreted as 0 43 | { 44 | type => "op", 45 | name => "ge", 46 | param => "5", 47 | input => "xxx", 48 | ret => 0, 49 | }, 50 | 51 | ### General 52 | { 53 | type => "op", 54 | name => "ge", 55 | param => "0", 56 | input => "-5", 57 | ret => 0, 58 | }, 59 | { 60 | type => "op", 61 | name => "ge", 62 | param => "0", 63 | input => "0", 64 | ret => 1, 65 | }, 66 | { 67 | type => "op", 68 | name => "ge", 69 | param => "0", 70 | input => "5", 71 | ret => 1, 72 | }, 73 | { 74 | type => "op", 75 | name => "ge", 76 | param => "5", 77 | input => "0", 78 | ret => 0, 79 | }, 80 | { 81 | type => "op", 82 | name => "ge", 83 | param => "5", 84 | input => "5", 85 | ret => 1, 86 | }, 87 | { 88 | type => "op", 89 | name => "ge", 90 | param => "5", 91 | input => "10", 92 | ret => 1, 93 | }, 94 | -------------------------------------------------------------------------------- /tests/op/geoLookup.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | # NOTE: All will return 0 because of lacking DB 3 | { 4 | type => "op", 5 | name => "geoLookup", 6 | param => "", 7 | input => "", 8 | ret => 0, 9 | }, 10 | { 11 | type => "op", 12 | name => "geoLookup", 13 | param => "TestCase", 14 | input => "", 15 | ret => 0, 16 | }, 17 | 18 | # Failed Lookup 19 | { 20 | type => "op", 21 | name => "geoLookup", 22 | param => "", 23 | input => "127.0.0.1", 24 | ret => 0, 25 | }, 26 | 27 | # Good 28 | { 29 | type => "op", 30 | name => "geoLookup", 31 | param => "", 32 | input => "216.75.21.122", 33 | #ret => 1, 34 | ret => 0, 35 | }, 36 | { 37 | type => "op", 38 | name => "geoLookup", 39 | param => "", 40 | input => "www.modsecurity.org", 41 | #ret => 1, 42 | ret => 0, 43 | }, 44 | 45 | -------------------------------------------------------------------------------- /tests/op/gt.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "gt", 5 | param => "0", 6 | input => "", 7 | ret => 0, 8 | }, 9 | { 10 | type => "op", 11 | name => "gt", 12 | param => "5", 13 | input => "", 14 | ret => 0, 15 | }, 16 | 17 | ### Invalid 18 | # xxx interpreted as 0 19 | { 20 | type => "op", 21 | name => "gt", 22 | param => "xxx", 23 | input => "5", 24 | ret => 1, 25 | }, 26 | # xxx interpreted as 0 27 | { 28 | type => "op", 29 | name => "gt", 30 | param => "xxx", 31 | input => "-1", 32 | ret => 0, 33 | }, 34 | # xxx interpreted as 0 35 | { 36 | type => "op", 37 | name => "gt", 38 | param => "-1", 39 | input => "xxx", 40 | ret => 1, 41 | }, 42 | # xxx interpreted as 0 43 | { 44 | type => "op", 45 | name => "gt", 46 | param => "5", 47 | input => "xxx", 48 | ret => 0, 49 | }, 50 | 51 | ### General 52 | { 53 | type => "op", 54 | name => "gt", 55 | param => "0", 56 | input => "-5", 57 | ret => 0, 58 | }, 59 | { 60 | type => "op", 61 | name => "gt", 62 | param => "0", 63 | input => "0", 64 | ret => 0, 65 | }, 66 | { 67 | type => "op", 68 | name => "gt", 69 | param => "0", 70 | input => "5", 71 | ret => 1, 72 | }, 73 | { 74 | type => "op", 75 | name => "gt", 76 | param => "5", 77 | input => "0", 78 | ret => 0, 79 | }, 80 | { 81 | type => "op", 82 | name => "gt", 83 | param => "5", 84 | input => "5", 85 | ret => 0, 86 | }, 87 | { 88 | type => "op", 89 | name => "gt", 90 | param => "5", 91 | input => "10", 92 | ret => 1, 93 | }, 94 | -------------------------------------------------------------------------------- /tests/op/inspectFile.t: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/op/le.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "le", 5 | param => "0", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "le", 12 | param => "5", 13 | input => "", 14 | ret => 1, 15 | }, 16 | 17 | ### Invalid 18 | # xxx interpreted as 0 19 | { 20 | type => "op", 21 | name => "le", 22 | param => "xxx", 23 | input => "5", 24 | ret => 0, 25 | }, 26 | # xxx interpreted as 0 27 | { 28 | type => "op", 29 | name => "le", 30 | param => "xxx", 31 | input => "-1", 32 | ret => 1, 33 | }, 34 | # xxx interpreted as 0 35 | { 36 | type => "op", 37 | name => "le", 38 | param => "0", 39 | input => "xxx", 40 | ret => 1, 41 | }, 42 | # xxx interpreted as 0 43 | { 44 | type => "op", 45 | name => "le", 46 | param => "5", 47 | input => "xxx", 48 | ret => 1, 49 | }, 50 | 51 | ### General 52 | { 53 | type => "op", 54 | name => "le", 55 | param => "0", 56 | input => "-5", 57 | ret => 1, 58 | }, 59 | { 60 | type => "op", 61 | name => "le", 62 | param => "0", 63 | input => "0", 64 | ret => 1, 65 | }, 66 | { 67 | type => "op", 68 | name => "le", 69 | param => "0", 70 | input => "5", 71 | ret => 0, 72 | }, 73 | { 74 | type => "op", 75 | name => "le", 76 | param => "5", 77 | input => "0", 78 | ret => 1, 79 | }, 80 | { 81 | type => "op", 82 | name => "le", 83 | param => "5", 84 | input => "5", 85 | ret => 1, 86 | }, 87 | { 88 | type => "op", 89 | name => "le", 90 | param => "5", 91 | input => "10", 92 | ret => 0, 93 | }, 94 | -------------------------------------------------------------------------------- /tests/op/lt.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "lt", 5 | param => "0", 6 | input => "", 7 | ret => 0, 8 | }, 9 | { 10 | type => "op", 11 | name => "lt", 12 | param => "5", 13 | input => "", 14 | ret => 1, 15 | }, 16 | 17 | ### Invalid 18 | # xxx interpreted as 0 19 | { 20 | type => "op", 21 | name => "lt", 22 | param => "xxx", 23 | input => "5", 24 | ret => 0, 25 | }, 26 | # xxx interpreted as 0 27 | { 28 | type => "op", 29 | name => "lt", 30 | param => "xxx", 31 | input => "-1", 32 | ret => 1, 33 | }, 34 | # xxx interpreted as 0 35 | { 36 | type => "op", 37 | name => "lt", 38 | param => "-1", 39 | input => "xxx", 40 | ret => 0, 41 | }, 42 | # xxx interpreted as 0 43 | { 44 | type => "op", 45 | name => "lt", 46 | param => "5", 47 | input => "xxx", 48 | ret => 1, 49 | }, 50 | 51 | ### General 52 | { 53 | type => "op", 54 | name => "lt", 55 | param => "0", 56 | input => "-5", 57 | ret => 1, 58 | }, 59 | { 60 | type => "op", 61 | name => "lt", 62 | param => "0", 63 | input => "0", 64 | ret => 0, 65 | }, 66 | { 67 | type => "op", 68 | name => "lt", 69 | param => "0", 70 | input => "5", 71 | ret => 0, 72 | }, 73 | { 74 | type => "op", 75 | name => "lt", 76 | param => "5", 77 | input => "0", 78 | ret => 1, 79 | }, 80 | { 81 | type => "op", 82 | name => "lt", 83 | param => "5", 84 | input => "5", 85 | ret => 0, 86 | }, 87 | { 88 | type => "op", 89 | name => "lt", 90 | param => "5", 91 | input => "10", 92 | ret => 0, 93 | }, 94 | -------------------------------------------------------------------------------- /tests/op/noMatch.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "noMatch", 5 | param => "", 6 | input => "", 7 | ret => 0, 8 | }, 9 | { 10 | type => "op", 11 | name => "noMatch", 12 | param => "TestCase", 13 | input => "", 14 | ret => 0, 15 | }, 16 | { 17 | type => "op", 18 | name => "noMatch", 19 | param => "", 20 | input => "TestCase", 21 | ret => 0, 22 | }, 23 | 24 | -------------------------------------------------------------------------------- /tests/op/pmFromFile-01.dat: -------------------------------------------------------------------------------- 1 | abc 2 | def 3 | ghi 4 | xxx yyy zzz 5 | -------------------------------------------------------------------------------- /tests/op/pmFromFile.t: -------------------------------------------------------------------------------- 1 | ### No Match 2 | { 3 | type => "op", 4 | name => "pmFromFile", 5 | param => "op/pmFromFile-01.dat", 6 | input => "xxxyyyzzz", 7 | ret => 0, 8 | }, 9 | 10 | ### Multiple 11 | { 12 | type => "op", 13 | name => "pmFromFile", 14 | param => "op/pmFromFile-01.dat", 15 | input => "defxxxyyy", 16 | ret => 1, 17 | }, 18 | { 19 | type => "op", 20 | name => "pmFromFile", 21 | param => "op/pmFromFile-01.dat", 22 | input => "xxxdefyyy", 23 | ret => 1, 24 | }, 25 | { 26 | type => "op", 27 | name => "pmFromFile", 28 | param => "op/pmFromFile-01.dat", 29 | input => "xxxyyydef", 30 | ret => 1, 31 | }, 32 | { 33 | type => "op", 34 | name => "pmFromFile", 35 | param => "op/pmFromFile-01.dat", 36 | input => "xxx yyy zzz", 37 | ret => 1, 38 | }, 39 | { 40 | type => "op", 41 | name => "pmFromFile", 42 | param => "op/pmFromFile-01.dat", 43 | input => "xxx yyy", 44 | ret => 0, 45 | }, 46 | -------------------------------------------------------------------------------- /tests/op/rbl.t: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/op/rx.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "rx", 5 | param => "", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "rx", 12 | param => "TestCase", 13 | input => "", 14 | ret => 0, 15 | }, 16 | { 17 | type => "op", 18 | name => "rx", 19 | param => "", 20 | input => "TestCase", 21 | ret => 1, 22 | }, 23 | 24 | ### General 25 | { 26 | type => "op", 27 | name => "rx", 28 | param => "abc", 29 | input => "abcdefghi", 30 | ret => 1, 31 | }, 32 | { 33 | type => "op", 34 | name => "rx", 35 | param => "def", 36 | input => "abcdefghi", 37 | ret => 1, 38 | }, 39 | { 40 | type => "op", 41 | name => "rx", 42 | param => "ghi", 43 | input => "abcdefghi", 44 | ret => 1, 45 | }, 46 | { 47 | type => "op", 48 | name => "rx", 49 | param => "ghij", 50 | input => "abcdefghi", 51 | ret => 0, 52 | }, 53 | 54 | ### Complex regex 55 | { 56 | type => "op", 57 | name => "rx", 58 | param => "(?i:(sleep\\((\\s*?)(\\d*?)(\\s*?)\\)|benchmark\\((.*?)\\,(.*?)\\)))", 59 | input => "SELECT pg_sleep(10);", 60 | ret => 1, 61 | }, 62 | 63 | -------------------------------------------------------------------------------- /tests/op/streq.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "streq", 5 | param => "", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "streq", 12 | param => "TestCase", 13 | input => "", 14 | ret => 0, 15 | }, 16 | { 17 | type => "op", 18 | name => "streq", 19 | param => "", 20 | input => "TestCase", 21 | ret => 0, 22 | }, 23 | 24 | ### General 25 | { 26 | type => "op", 27 | name => "streq", 28 | param => "abc", 29 | input => "abcdefghi", 30 | ret => 0, 31 | }, 32 | { 33 | type => "op", 34 | name => "streq", 35 | param => "def", 36 | input => "abcdefghi", 37 | ret => 0, 38 | }, 39 | { 40 | type => "op", 41 | name => "streq", 42 | param => "ghi", 43 | input => "abcdefghi", 44 | ret => 0, 45 | }, 46 | { 47 | type => "op", 48 | name => "streq", 49 | param => "abcdefghi", 50 | input => "abcdefghi", 51 | ret => 1, 52 | }, 53 | -------------------------------------------------------------------------------- /tests/op/strmatch.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "strmatch", 5 | param => "TestCase", 6 | input => "", 7 | ret => 0, 8 | }, 9 | ### General 10 | { 11 | type => "op", 12 | name => "strmatch", 13 | param => "abc", 14 | input => "abcdefghi", 15 | ret => 1, 16 | }, 17 | { 18 | type => "op", 19 | name => "strmatch", 20 | param => "def", 21 | input => "abcdefghi", 22 | ret => 1, 23 | }, 24 | { 25 | type => "op", 26 | name => "strmatch", 27 | param => "ghi", 28 | input => "abcdefghi", 29 | ret => 1, 30 | }, 31 | { 32 | type => "op", 33 | name => "strmatch", 34 | param => "ghij", 35 | input => "abcdefghi", 36 | ret => 0, 37 | }, 38 | -------------------------------------------------------------------------------- /tests/op/unconditionalMatch.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "unconditionalMatch", 5 | param => "", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "unconditionalMatch", 12 | param => "TestCase", 13 | input => "", 14 | ret => 1, 15 | }, 16 | { 17 | type => "op", 18 | name => "unconditionalMatch", 19 | param => "", 20 | input => "TestCase", 21 | ret => 1, 22 | }, 23 | 24 | -------------------------------------------------------------------------------- /tests/op/validateByteRange.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "validateByteRange", 5 | param => "0-255", 6 | input => "", 7 | ret => 0, 8 | }, 9 | { 10 | type => "op", 11 | name => "validateByteRange", 12 | param => "", 13 | input => "TestCase", 14 | ret => 1, 15 | }, 16 | 17 | ### Invalid 18 | { 19 | type => "op", 20 | name => "validateByteRange", 21 | param => "xxx", 22 | input => "TestCase", 23 | ret => 1, 24 | }, 25 | { 26 | type => "op", 27 | name => "validateByteRange", 28 | param => "xxx", 29 | input => "\x00", 30 | ret => 0, 31 | }, 32 | 33 | ### General 34 | { 35 | type => "op", 36 | name => "validateByteRange", 37 | param => "0-255", 38 | input => "abcdefghi", 39 | ret => 0, 40 | }, 41 | { 42 | type => "op", 43 | name => "validateByteRange", 44 | param => ord("a")."-".ord("i"), 45 | input => "abcdefghi", 46 | ret => 0, 47 | }, 48 | { 49 | type => "op", 50 | name => "validateByteRange", 51 | param => ord("a")."-".ord("i"), 52 | input => "abcdefghij", 53 | ret => 1, 54 | }, 55 | -------------------------------------------------------------------------------- /tests/op/validateDTD.t: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/op/validateSchema.t: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/op/validateUrlEncoding.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "validateUrlEncoding", 5 | param => "", 6 | input => "", 7 | ret => 0, 8 | }, 9 | 10 | ### General 11 | { 12 | type => "op", 13 | name => "validateUrlEncoding", 14 | param => "", 15 | input => "Hello%20World!", 16 | ret => 0, 17 | }, 18 | { 19 | type => "op", 20 | name => "validateUrlEncoding", 21 | param => "", 22 | input => "Hello+World!", 23 | ret => 0, 24 | }, 25 | { 26 | type => "op", 27 | name => "validateUrlEncoding", 28 | param => "", 29 | input => "HelloWorld!", 30 | ret => 0, 31 | }, 32 | { 33 | type => "op", 34 | name => "validateUrlEncoding", 35 | param => "", 36 | input => "%00Hello%20World!", 37 | ret => 0, 38 | }, 39 | { 40 | type => "op", 41 | name => "validateUrlEncoding", 42 | param => "", 43 | input => "Hello%20World!%00", 44 | ret => 0, 45 | }, 46 | { 47 | type => "op", 48 | name => "validateUrlEncoding", 49 | param => "", 50 | input => "%00", 51 | ret => 0, 52 | }, 53 | { 54 | type => "op", 55 | name => "validateUrlEncoding", 56 | param => "", 57 | input => "%ff", 58 | ret => 0, 59 | }, 60 | { 61 | type => "op", 62 | name => "validateUrlEncoding", 63 | param => "", 64 | input => "%0", 65 | ret => 1, 66 | }, 67 | { 68 | type => "op", 69 | name => "validateUrlEncoding", 70 | param => "", 71 | input => "%f", 72 | ret => 1, 73 | }, 74 | { 75 | type => "op", 76 | name => "validateUrlEncoding", 77 | param => "", 78 | input => "%", 79 | ret => 1, 80 | }, 81 | { 82 | type => "op", 83 | name => "validateUrlEncoding", 84 | param => "", 85 | input => "%0z", 86 | ret => 1, 87 | }, 88 | { 89 | type => "op", 90 | name => "validateUrlEncoding", 91 | param => "", 92 | input => "%z0", 93 | ret => 1, 94 | }, 95 | { 96 | type => "op", 97 | name => "validateUrlEncoding", 98 | param => "", 99 | input => "%0%", 100 | ret => 1, 101 | }, 102 | -------------------------------------------------------------------------------- /tests/op/within.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "op", 4 | name => "within", 5 | param => "", 6 | input => "", 7 | ret => 1, 8 | }, 9 | { 10 | type => "op", 11 | name => "within", 12 | param => "TestCase", 13 | input => "", 14 | ret => 1, 15 | }, 16 | { 17 | type => "op", 18 | name => "within", 19 | param => "", 20 | input => "TestCase", 21 | ret => 0, 22 | }, 23 | 24 | ### General 25 | { 26 | type => "op", 27 | name => "within", 28 | param => "abcdefghi", 29 | input => "abc", 30 | ret => 1, 31 | }, 32 | { 33 | type => "op", 34 | name => "within", 35 | param => "abcdefghi", 36 | input => "def", 37 | ret => 1, 38 | }, 39 | { 40 | type => "op", 41 | name => "within", 42 | param => "abcdefghi", 43 | input => "ghi", 44 | ret => 1, 45 | }, 46 | { 47 | type => "op", 48 | name => "within", 49 | param => "abcdefghi", 50 | input => "ghij", 51 | ret => 0, 52 | }, 53 | -------------------------------------------------------------------------------- /tests/regression/action/00-meta.t: -------------------------------------------------------------------------------- 1 | ### Test meta actions 2 | 3 | # TODO: id 4 | # TODO: logdata 5 | # TODO: msg 6 | # TODO: rev 7 | # TODO: severity 8 | # TODO: tag 9 | -------------------------------------------------------------------------------- /tests/regression/action/00-misc.t: -------------------------------------------------------------------------------- 1 | ### Test misc actions 2 | 3 | # TODO: block 4 | # TODO: capture 5 | # TODO: chain 6 | # TODO: deprecatevar 7 | # TODO: exec 8 | # TODO: expirevar 9 | # TODO: initcol 10 | # TODO: multiMatch 11 | # TODO: pause 12 | # TODO: sanitiseArg 13 | # TODO: sanitiseMatched 14 | # TODO: sanitiseRequestHeader 15 | # TODO: sanitiseResponseHeader 16 | # TODO: setuid 17 | # TODO: setsid 18 | # TODO: setenv 19 | # TODO: setvar 20 | # TODO: skip 21 | # TODO: skipAfter 22 | # TODO: xmlns 23 | -------------------------------------------------------------------------------- /tests/regression/action/00-transformations.t: -------------------------------------------------------------------------------- 1 | ### Transformation tests 2 | 3 | # NOTE: individual tests done in unit tests 4 | 5 | # TODO: t:none to override default 6 | # TODO: t:none inline 7 | # TODO: combined 8 | # TODO: caching 9 | -------------------------------------------------------------------------------- /tests/regression/action/10-append-prepend.t: -------------------------------------------------------------------------------- 1 | # TODO: Need more tests here 2 | 3 | ### append 4 | { 5 | type => "action", 6 | comment => "append content", 7 | conf => qq( 8 | SecRuleEngine On 9 | SecContentInjection On 10 | SecDebugLog "$ENV{DEBUG_LOG}" 11 | SecDebugLogLevel 9 12 | SecAction "phase:1,setvar:tx.test=test,id:500002" 13 | SecAction "phase:2,append:'APPEND: \%{tx.test}',id:500003" 14 | ), 15 | match_log => { 16 | debug => [ "Added content to bottom: APPEND: test", 1 ], 17 | }, 18 | match_response => { 19 | status => qr/^200$/, 20 | content => qr/APPEND: test$/, 21 | }, 22 | request => new HTTP::Request( 23 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 24 | ), 25 | }, 26 | 27 | ### prepend 28 | { 29 | type => "action", 30 | comment => "prepend content", 31 | conf => qq( 32 | SecRuleEngine On 33 | SecContentInjection On 34 | SecDebugLog "$ENV{DEBUG_LOG}" 35 | SecDebugLogLevel 9 36 | SecAction "phase:1,setvar:tx.test=test,id:500004" 37 | SecAction "phase:2,prepend:'PREPEND: \%{tx.test}',id:500005" 38 | ), 39 | match_log => { 40 | debug => [ "Added content to top: PREPEND: test", 1 ], 41 | }, 42 | match_response => { 43 | status => qr/^200$/, 44 | content => qr/^PREPEND: test/, 45 | }, 46 | request => new HTTP::Request( 47 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 48 | ), 49 | }, 50 | -------------------------------------------------------------------------------- /tests/regression/action/10-ctl.t: -------------------------------------------------------------------------------- 1 | ### ctl 2 | 3 | ### ruleRemoveById 4 | { 5 | type => "action", 6 | comment => "ruleRemoveById existing rule across phases", 7 | conf => qq( 8 | SecRuleEngine On 9 | SecAction "phase:2,id:666,deny" 10 | SecAction "phase:1,pass,ctl:ruleRemoveById=666,id:500030" 11 | ), 12 | match_log => { 13 | }, 14 | match_response => { 15 | status => qr/^200$/, 16 | }, 17 | request => new HTTP::Request( 18 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 19 | ), 20 | }, 21 | { 22 | type => "action", 23 | comment => "ruleRemoveById future rule across phases", 24 | conf => qq( 25 | SecRuleEngine On 26 | SecAction "phase:1,pass,ctl:ruleRemoveById=666,id:500031" 27 | SecAction "phase:2,id:666,deny" 28 | ), 29 | match_log => { 30 | }, 31 | match_response => { 32 | status => qr/^200$/, 33 | }, 34 | request => new HTTP::Request( 35 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 36 | ), 37 | }, 38 | { 39 | type => "action", 40 | comment => "ruleRemoveById future rule same phase", 41 | conf => qq( 42 | SecRuleEngine On 43 | SecAction "phase:1,pass,ctl:ruleRemoveById=666,id:500032" 44 | SecAction "phase:1,id:666,deny" 45 | ), 46 | match_log => { 47 | }, 48 | match_response => { 49 | status => qr/^200$/, 50 | }, 51 | request => new HTTP::Request( 52 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 53 | ), 54 | }, 55 | 56 | 57 | -------------------------------------------------------------------------------- /tests/regression/config/00-load-modsec.t: -------------------------------------------------------------------------------- 1 | { 2 | type => "config", 3 | comment => "module loaded", 4 | match_log => { 5 | error => { 6 | apache => [ qr/ModSecurity for Apache.* configured\./, 10 ], 7 | nginx => [ qr/ModSecurity for nginx.* configured\./, 10 ], 8 | }, 9 | }, 10 | }, 11 | { 12 | type => "config", 13 | comment => "minimal config", 14 | conf => sub { 15 | # Open the minimal conf file, substituting the 16 | # relative log paths with full paths. 17 | open(C, "<$ENV{DIST_ROOT}/modsecurity.conf-minimal") or die "$!\n"; 18 | (my $conf = join('', )) =~ s#Log logs/#Log $ENV{TEST_SERVER_ROOT}/logs/#g; 19 | close C; 20 | 21 | return $conf; 22 | }, 23 | match_log => { 24 | error => { 25 | apache => [ qr/ModSecurity for Apache.* configured\./, 10 ], 26 | nginx => [ qr/ModSecurity for nginx.* configured\./, 10 ], 27 | }, 28 | }, 29 | }, 30 | -------------------------------------------------------------------------------- /tests/regression/config/20-chroot.t: -------------------------------------------------------------------------------- 1 | ### SecChroot tests 2 | # TODO: Will not work as we need root access 3 | 4 | #{ 5 | # type => "config", 6 | # comment => "SecChroot", 7 | # httpd_opts => qw( 8 | # -DCHROOT 9 | # ), 10 | # conf => qq( 11 | # # These will be in the chroot 12 | # PidFile /logs/httpd.pid 13 | # ScoreBoardFile /logs/httpd.scoreboard 14 | # User nobody 15 | # Group nogroup 16 | # 17 | # SecAuditEngine On 18 | # SecDebugLog $ENV{DEBUG_LOG} 19 | # SecDebugLogLevel 9 20 | # SecAuditLog $ENV{AUDIT_LOG} 21 | # SecAuditLogStorageDir "/logs/audit" 22 | # SecAuditLogType Concurrent 23 | # SecChrootDir "$ENV{TEST_SERVER_ROOT}" 24 | # ), 25 | # match_log => { 26 | # debug => [ qr/./, 1 ], 27 | # audit => [ qr/./, 1 ], 28 | # }, 29 | # match_response => { 30 | # status => qr/^200$/, 31 | # }, 32 | # request => new HTTP::Request( 33 | # GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 34 | # ), 35 | #}, 36 | -------------------------------------------------------------------------------- /tests/regression/misc/40-secRemoteRules.t.in: -------------------------------------------------------------------------------- 1 | ### SecRemoteRules 2 | 3 | { 4 | type => "misc", 5 | comment => "SecRemoteRules load", 6 | conf => qq( 7 | SecRuleEngine On 8 | SecDebugLog $ENV{DEBUG_LOG} 9 | SecDebugLogLevel 9 10 | SecRequestBodyAccess On 11 | SecRemoteRules 123 "https://www.modsecurity.org/modsecurity-regression-test-secremoterules.txt" 12 | ), 13 | match_log => { 14 | error => [ qr/ModSecurity: Loaded 1 rule/, 1], 15 | }, 16 | }, 17 | { 18 | type => "misc", 19 | comment => "SecRemoteRules apply some remote rules", 20 | conf => qq( 21 | SecRuleEngine On 22 | SecDebugLog $ENV{DEBUG_LOG} 23 | SecDebugLogLevel 9 24 | SecRequestBodyAccess On 25 | SecRemoteRules 123 "https://www.modsecurity.org/modsecurity-regression-test-secremoterules.txt" 26 | ), 27 | match_log => { 28 | error => [ qr/ModSecurity: Warning. Matched phrase \"127.0.0.1\" at REQUEST_FILENAME./, 1], 29 | debug => [ qr/Matched phrase \"127.0.0.1\" at REQUEST_FILENAME/, 1 ], 30 | }, 31 | match_response => { 32 | status => qr/^404$/, 33 | }, 34 | request => new HTTP::Request( 35 | POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/127.0.0.1.html", 36 | [ 37 | "Content-Type" => "application/x-www-form-urlencoded", 38 | ], 39 | # Args 40 | "some_variable=-1' and 1=1 union/* foo */select load_file('/etc/passwd')--" 41 | ), 42 | }, 43 | 44 | -------------------------------------------------------------------------------- /tests/regression/misc/50-ipmatchfromfile-external.t.in: -------------------------------------------------------------------------------- 1 | ### ipMatchFromFile external resource 2 | 3 | { 4 | type => "misc", 5 | comment => "ipMatchFromFile", 6 | conf => qq( 7 | SecRuleEngine On 8 | SecDebugLog $ENV{DEBUG_LOG} 9 | SecDebugLogLevel 9 10 | SecRequestBodyAccess On 11 | SecRule REMOTE_ADDR "\@ipMatchFromFile https://www.modsecurity.org/modsecurity-regression-test.txt" "id:10500,pass" 12 | ), 13 | match_log => { 14 | error => [ qr/ModSecurity: Warning. IPmatchFromFile: \"127.0.0.1\" matched at REMOTE_ADDR./, 1], 15 | debug => [ qr/IPmatchFromFile: \"127.0.0.1\" matched at REMOTE_ADDR./, 1 ], 16 | -error => [ qr/ModSecurity: Problems loading external resources:/, 1], 17 | }, 18 | match_response => { 19 | status => qr/^404$/, 20 | }, 21 | request => new HTTP::Request( 22 | POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/127.0.0.1.html", 23 | [ 24 | "Content-Type" => "application/x-www-form-urlencoded", 25 | ], 26 | # Args 27 | "some_variable=-1' and 1=1 union/* foo */select load_file('/etc/passwd')--" 28 | ), 29 | }, 30 | { 31 | type => "misc", 32 | comment => "ipMatchFromFile - 404 download", 33 | conf => qq( 34 | SecRuleEngine On 35 | SecDebugLog $ENV{DEBUG_LOG} 36 | SecDebugLogLevel 9 37 | SecRequestBodyAccess On 38 | SecRemoteRulesFailAction Warn 39 | SecRule REMOTE_ADDR "\@ipMatchFromFile https://www.modsecurity.org/modsecurity-regression-test-404.txt" "id:10500,pass" 40 | ), 41 | match_log => { 42 | error => [ qr/ModSecurity: Problems loading external resources: Failed to download: \"https:\/\/www.modsecurity.org\/modsecurity-regression-test-404.txt\" error: HTTP response code said error./, 1], 43 | }, 44 | match_response => { 45 | status => qr/^404$/, 46 | }, 47 | request => new HTTP::Request( 48 | POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/127.0.0.1.html", 49 | [ 50 | "Content-Type" => "application/x-www-form-urlencoded", 51 | ], 52 | # Args 53 | "some_variable=-1' and 1=1 union/* foo */select load_file('/etc/passwd')--" 54 | ), 55 | }, 56 | { 57 | type => "misc", 58 | comment => "ipMatchFromFile - bad certificate name", 59 | conf => qq( 60 | SecRuleEngine On 61 | SecDebugLog $ENV{DEBUG_LOG} 62 | SecDebugLogLevel 9 63 | SecRequestBodyAccess On 64 | SecRemoteRulesFailAction Warn 65 | SecRule REMOTE_ADDR "\@ipMatchFromFile https://status.modsecurity.org/modsecurity-regression-test-huge-ip-list.txt" "id:10500,pass" 66 | ), 67 | match_log => { 68 | error => [ qr/ModSecurity: Problems loading external resources: Failed to download: \"https:\/\/status.modsecurity.org\/modsecurity-regression-test-huge-ip-list.txt\" error: [SSL peer certificate or SSH remote key was not OK.|Couldn't connect to server.]/, 1], 69 | }, 70 | }, 71 | 72 | -------------------------------------------------------------------------------- /tests/regression/misc/60-pmfromfile-external.t.in: -------------------------------------------------------------------------------- 1 | ### pmfromfile external resource 2 | 3 | { 4 | type => "misc", 5 | comment => "pmfromfile", 6 | conf => qq( 7 | SecRuleEngine On 8 | SecDebugLog $ENV{DEBUG_LOG} 9 | SecDebugLogLevel 9 10 | SecRequestBodyAccess On 11 | SecRule REQUEST_FILENAME "\@pmFromFile https://www.modsecurity.org/modsecurity-regression-test.txt" "id:'123',phase:2,log,pass,t:none" 12 | ), 13 | match_log => { 14 | error => [ qr/ModSecurity: Warning. Matched phrase \"127.0.0.1\" at REQUEST_FILENAME./, 1], 15 | debug => [ qr/Matched phrase \"127.0.0.1\" at REQUEST_FILENAME/, 1 ], 16 | -error => [ qr/ModSecurity: Problems loading external resources:/, 1], 17 | }, 18 | match_response => { 19 | status => qr/^404$/, 20 | }, 21 | request => new HTTP::Request( 22 | POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/127.0.0.1.html", 23 | [ 24 | "Content-Type" => "application/x-www-form-urlencoded", 25 | ], 26 | # Args 27 | "some_variable=-1' and 1=1 union/* foo */select load_file('/etc/passwd')--" 28 | ), 29 | }, 30 | { 31 | type => "misc", 32 | comment => "pmfromfile - 404 download", 33 | conf => qq( 34 | SecRuleEngine On 35 | SecDebugLog $ENV{DEBUG_LOG} 36 | SecDebugLogLevel 9 37 | SecRequestBodyAccess On 38 | SecRemoteRulesFailAction Warn 39 | SecRule REQUEST_FILENAME "\@pmFromFile https://www.modsecurity.org/modsecurity-regression-test-404.txt" "id:'123',phase:2,log,pass,t:none" 40 | 41 | ), 42 | match_log => { 43 | error => [ qr/ModSecurity: Problems loading external resources: Failed to download: \"https:\/\/www.modsecurity.org\/modsecurity-regression-test-404.txt\" error: HTTP response code said error./, 1], 44 | }, 45 | match_response => { 46 | status => qr/^404$/, 47 | }, 48 | request => new HTTP::Request( 49 | POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/127.0.0.1.html", 50 | [ 51 | "Content-Type" => "application/x-www-form-urlencoded", 52 | ], 53 | # Args 54 | "some_variable=-1' and 1=1 union/* foo */select load_file('/etc/passwd')--" 55 | ), 56 | }, 57 | { 58 | type => "misc", 59 | comment => "pmfromfile - bad certificate name", 60 | conf => qq( 61 | SecRuleEngine On 62 | SecDebugLog $ENV{DEBUG_LOG} 63 | SecDebugLogLevel 9 64 | SecRequestBodyAccess On 65 | SecRemoteRulesFailAction Warn 66 | SecRule REQUEST_FILENAME "\@pmFromFile https://status.modsecurity.org/modsecurity-regression-test.txt" "id:'123',phase:2,log,pass,t:none" 67 | 68 | ), 69 | match_log => { 70 | error => [ qr/ModSecurity: Problems loading external resources: Failed to download: \"https:\/\/status.modsecurity.org\/modsecurity-regression-test.txt\" error: [SSL peer certificate or SSH remote key was not OK.|Couldn't connect to server.]/, 1], 71 | }, 72 | match_response => { 73 | status => qr/^404$/, 74 | }, 75 | request => new HTTP::Request( 76 | POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/127.0.0.1.html", 77 | [ 78 | "Content-Type" => "application/x-www-form-urlencoded", 79 | ], 80 | # Args 81 | "some_variable=-1' and 1=1 union/* foo */select load_file('/etc/passwd')--" 82 | ), 83 | }, 84 | 85 | -------------------------------------------------------------------------------- /tests/regression/nginx/conf/SoapEnvelope-bad.dtd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/regression/nginx/conf/SoapEnvelope.dtd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/regression/nginx/conf/empty.conf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/tests/regression/nginx/conf/empty.conf -------------------------------------------------------------------------------- /tests/regression/nginx/conf/match.lua: -------------------------------------------------------------------------------- 1 | -- Test matching Lua Script to just print debug messages 2 | function main() 3 | m.log(1, "Test message."); 4 | m.log(2, "Test message."); 5 | m.log(3, "Test message."); 6 | m.log(4, "Test message."); 7 | m.log(5, "Test message."); 8 | m.log(6, "Test message."); 9 | m.log(7, "Test message."); 10 | m.log(8, "Test message."); 11 | m.log(9, "Test message."); 12 | 13 | return "Lua script matched."; 14 | end 15 | -------------------------------------------------------------------------------- /tests/regression/nginx/conf/nginx.conf.template: -------------------------------------------------------------------------------- 1 | 2 | user root; 3 | worker_processes 1; 4 | daemon on; 5 | error_log logs/error.log debug; 6 | events { 7 | worker_connections 1024; 8 | } 9 | 10 | http { 11 | ModSecurityEnabled [% enable %]; 12 | ModSecurityConfig [% config %]; 13 | server { 14 | 15 | listen [% listen %]; 16 | server_name localhost; 17 | location / { 18 | error_page 405 = $uri; 19 | } 20 | } 21 | } 22 | 23 | 24 | -------------------------------------------------------------------------------- /tests/regression/nginx/conf/ssdeep.txt: -------------------------------------------------------------------------------- 1 | ssdeep,1.1--blocksize:hash:hash,filename 2 | 96:MbQ1L0LDX8GPI8ov3D2D9zd6/gz2wZhFvV0O598La8Kqvfi0znNa8Xi5SM7XRWCK:KvL8Gg8rWIz2ZKqvfjzQ55RpRHjftQ++,"modsecurity.conf-recommended" 3 | 192:b8B5UQvywcMIJuavpde/Yyz/U/vF+vGCoCvrQr/dw:afcnrvp8zqUvGrzr6,"README_WINDOWS.TXT" 4 | 96:+qK8Z4gA165/hquKNMi68zuEyMM9qNB26x:+RG4z6c1LyZOB26x,"README.TXT" 5 | -------------------------------------------------------------------------------- /tests/regression/nginx/conf/test.lua: -------------------------------------------------------------------------------- 1 | -- Test Lua Script to just print debug messages 2 | function main() 3 | m.log(1, "Test message."); 4 | m.log(2, "Test message."); 5 | m.log(3, "Test message."); 6 | m.log(4, "Test message."); 7 | m.log(5, "Test message."); 8 | m.log(6, "Test message."); 9 | m.log(7, "Test message."); 10 | m.log(8, "Test message."); 11 | m.log(9, "Test message."); 12 | 13 | return nil; 14 | end 15 | -------------------------------------------------------------------------------- /tests/regression/rule/00-basics.t: -------------------------------------------------------------------------------- 1 | ### Tests for basic rule components 2 | 3 | # SecAction 4 | { 5 | type => "rule", 6 | comment => "SecAction (override default)", 7 | conf => qq( 8 | SecRuleEngine On 9 | SecDebugLog $ENV{DEBUG_LOG} 10 | SecDebugLogLevel 4 11 | SecAction "nolog,id:500001" 12 | ), 13 | match_log => { 14 | -error => [ qr/500001/, 1 ], 15 | -audit => [ qr/./, 1 ], 16 | debug => [ qr/Warning\. Unconditional match in SecAction\./, 1 ], 17 | }, 18 | match_response => { 19 | status => qr/^200$/, 20 | }, 21 | request => new HTTP::Request( 22 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 23 | ), 24 | }, 25 | 26 | # SecRule 27 | { 28 | type => "rule", 29 | comment => "SecRule (no action)", 30 | conf => qq( 31 | SecRuleEngine On 32 | SecDebugLog $ENV{DEBUG_LOG} 33 | SecDebugLogLevel 5 34 | SecDefaultAction "phase:2,deny,status:403" 35 | SecRule ARGS:test "value" "id:500032" 36 | ), 37 | match_log => { 38 | error => [ qr/500032/, 1 ], 39 | debug => [ qr/Rule [0-9a-f]+: SecRule "ARGS:test" "\@rx value" "phase:2,deny,status:403,id:500032"$/m, 1 ], 40 | }, 41 | match_response => { 42 | status => qr/^403$/, 43 | }, 44 | request => new HTTP::Request( 45 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?test=value", 46 | ), 47 | }, 48 | { 49 | type => "rule", 50 | comment => "SecRule (action)", 51 | conf => qq( 52 | SecRuleEngine On 53 | SecDebugLog $ENV{DEBUG_LOG} 54 | SecDebugLogLevel 5 55 | SecDefaultAction "phase:2,pass" 56 | SecRule ARGS:test "value" "deny,status:403,id:500033" 57 | ), 58 | match_log => { 59 | error => [ qr/ModSecurity: /, 1 ], 60 | debug => [ qr/Rule [0-9a-f]+: SecRule "ARGS:test" "\@rx value" "phase:2,deny,status:403,id:500033"$/m, 1 ], 61 | }, 62 | match_response => { 63 | status => qr/^403$/, 64 | }, 65 | request => new HTTP::Request( 66 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?test=value", 67 | ), 68 | }, 69 | { 70 | type => "rule", 71 | comment => "SecRule (chain)", 72 | conf => qq( 73 | SecRuleEngine On 74 | SecDebugLog $ENV{DEBUG_LOG} 75 | SecDebugLogLevel 5 76 | SecDefaultAction "phase:2,log,noauditlog,pass,tag:foo" 77 | SecRule ARGS:test "value" "chain,phase:2,deny,status:403,id:500034" 78 | SecRule &ARGS "\@eq 1" "chain,setenv:tx.foo=bar" 79 | SecRule REQUEST_METHOD "\@streq GET" 80 | ), 81 | match_log => { 82 | error => [ qr/ModSecurity: /, 1 ], 83 | debug => [ qr/Rule [0-9a-f]+: SecRule "ARGS:test" "\@rx value" "phase:2,log,noauditlog,tag:foo,chain,deny,status:403,id:500034"\r?\n.*Rule [0-9a-f]+: SecRule "&ARGS" "\@eq 1" "chain,setenv:tx.foo=bar"\r?\n.*Rule [0-9a-f]+: SecRule "REQUEST_METHOD" "\@streq GET"\r?\n/s, 1 ], 84 | }, 85 | match_response => { 86 | status => qr/^403$/, 87 | }, 88 | request => new HTTP::Request( 89 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt?test=value", 90 | ), 91 | }, 92 | -------------------------------------------------------------------------------- /tests/regression/rule/00-inheritance.t: -------------------------------------------------------------------------------- 1 | ### Tests for rule inheritance 2 | 3 | ### TODO: 4 | # SecRuleInheritance 5 | -------------------------------------------------------------------------------- /tests/regression/rule/00-script.t: -------------------------------------------------------------------------------- 1 | ### Test for SecRuleScript 2 | 3 | # Lua 4 | { 5 | type => "rule", 6 | comment => "SecRuleScript (lua absolute nomatch)", 7 | conf => qq( 8 | SecRuleEngine On 9 | SecDebugLog $ENV{DEBUG_LOG} 10 | SecDebugLogLevel 1 11 | SecRuleScript "$ENV{CONF_DIR}/test.lua" "phase:2,deny" 12 | ), 13 | match_log => { 14 | -error => [ qr/Lua script matched\./, 1 ], 15 | debug => [ qr/Test message\./, 1 ], 16 | }, 17 | match_response => { 18 | status => qr/^200$/, 19 | }, 20 | request => new HTTP::Request( 21 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 22 | ), 23 | }, 24 | { 25 | type => "rule", 26 | comment => "SecRuleScript (lua relative nomatch)", 27 | conf => qq( 28 | SecRuleEngine On 29 | SecDebugLog $ENV{DEBUG_LOG} 30 | SecDebugLogLevel 1 31 | SecRuleScript "test.lua" "phase:2,deny" 32 | ), 33 | match_log => { 34 | -error => [ qr/Lua script matched\./, 1 ], 35 | debug => [ qr/Test message\./, 1 ], 36 | }, 37 | match_response => { 38 | status => qr/^200$/, 39 | }, 40 | request => new HTTP::Request( 41 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 42 | ), 43 | }, 44 | { 45 | type => "rule", 46 | comment => "SecRuleScript (lua relative match)", 47 | conf => qq( 48 | SecRuleEngine On 49 | SecDebugLog $ENV{DEBUG_LOG} 50 | SecDebugLogLevel 1 51 | SecRuleScript "match.lua" "phase:2,deny" 52 | ), 53 | match_log => { 54 | error => [ qr/ModSecurity: Access denied with code 403 \(phase 2\)\. Lua script matched\./, 1 ], 55 | debug => [ qr/Test message\./, 1 ], 56 | }, 57 | match_response => { 58 | status => qr/^403$/, 59 | }, 60 | request => new HTTP::Request( 61 | GET => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 62 | ), 63 | }, 64 | -------------------------------------------------------------------------------- /tests/regression/rule/15-json.t: -------------------------------------------------------------------------------- 1 | ### Test for JSON parser 2 | 3 | ### 4 | # OK 5 | { 6 | type => "rule", 7 | comment => "json parser", 8 | conf => qq( 9 | SecRuleEngine On 10 | SecRequestBodyAccess On 11 | SecDebugLog $ENV{DEBUG_LOG} 12 | SecDebugLogLevel 9 13 | SecRule REQUEST_HEADERS:Content-Type "application/json" \\ 14 | "id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON" 15 | SecRule ARGS:foo "bar" "id:'200441',phase:3,log" 16 | ), 17 | match_log => { 18 | error => [ qr/ModSecurity: Warning. Pattern match "bar" at ARGS:foo.|ModSecurity: JSON support was not enabled/s, 1 ], 19 | debug => [ qr/Adding JSON argument 'foo' with value 'bar'|JSON support was not enabled/, 1 ], 20 | }, 21 | match_response => { 22 | status => qr/^200$/, 23 | }, 24 | request => new HTTP::Request( 25 | POST => "http://$ENV{SERVER_NAME}:$ENV{SERVER_PORT}/test.txt", 26 | [ 27 | "Content-Type" => "application/json", 28 | ], 29 | normalize_raw_request_data( 30 | q( 31 | { 32 | "foo":"bar", 33 | "mod":"sec" 34 | } 35 | ), 36 | ), 37 | ), 38 | } 39 | 40 | -------------------------------------------------------------------------------- /tests/regression/server_root/conf/SoapEnvelope-bad.dtd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/regression/server_root/conf/SoapEnvelope.dtd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /tests/regression/server_root/conf/httpd.conf.in: -------------------------------------------------------------------------------- 1 | ### Base configuration for starting Apache httpd 2 | 3 | LoadModule proxy_module @APXS_LIBEXECDIR@/mod_proxy.so 4 | LoadModule proxy_http_module @APXS_LIBEXECDIR@/mod_proxy_http.so 5 | LoadModule unique_id_module @APXS_LIBEXECDIR@/mod_unique_id.so 6 | # TODO: Need to have these configurable 7 | LoadModule security2_module @MSC_BASE_DIR@/apache2/.libs/mod_security2.so 8 | 9 | 10 | LoadModule version_module @APXS_LIBEXECDIR@/mod_version.so 11 | 12 | 13 | = 2.4> 14 | 15 | LoadModule unixd_module @APXS_LIBEXECDIR@/mod_unixd.so 16 | 17 | 18 | LoadModule mpm_worker_module @APXS_LIBEXECDIR@/mod_mpm_worker.so 19 | 20 | LoadModule access_compat_module @APXS_LIBEXECDIR@/mod_access_compat.so 21 | LoadModule authn_core_module @APXS_LIBEXECDIR@/mod_authn_core.so 22 | LoadModule authz_core_module @APXS_LIBEXECDIR@/mod_authz_core.so 23 | 24 | 25 | ServerName localhost 26 | CoreDumpDirectory @MSC_REGRESSION_SERVERROOT_DIR@/tmp 27 | LogLevel debug 28 | ErrorLog @MSC_REGRESSION_LOGS_DIR@/error.log 29 | 30 | 31 | # File locations 32 | PidFile @MSC_REGRESSION_LOGS_DIR@/httpd.pid 33 | ScoreBoardFile @MSC_REGRESSION_LOGS_DIR@/httpd.scoreboard 34 | 35 | DocumentRoot @MSC_REGRESSION_DOCROOT_DIR@ 36 | 37 | Options +Indexes +FollowSymLinks 38 | 39 | 40 | -------------------------------------------------------------------------------- /tests/regression/server_root/conf/match.lua: -------------------------------------------------------------------------------- 1 | -- Test matching Lua Script to just print debug messages 2 | function main() 3 | m.log(1, "Test message."); 4 | m.log(2, "Test message."); 5 | m.log(3, "Test message."); 6 | m.log(4, "Test message."); 7 | m.log(5, "Test message."); 8 | m.log(6, "Test message."); 9 | m.log(7, "Test message."); 10 | m.log(8, "Test message."); 11 | m.log(9, "Test message."); 12 | 13 | return "Lua script matched."; 14 | end 15 | -------------------------------------------------------------------------------- /tests/regression/server_root/conf/ssdeep.txt: -------------------------------------------------------------------------------- 1 | ssdeep,1.1--blocksize:hash:hash,filename 2 | 96:MbQ1L0LDX8GPI8ov3D2D9zd6/gz2wZhFvV0O598La8Kqvfi0znNa8Xi5SM7XRWCK:KvL8Gg8rWIz2ZKqvfjzQ55RpRHjftQ++,"modsecurity.conf-recommended" 3 | 192:b8B5UQvywcMIJuavpde/Yyz/U/vF+vGCoCvrQr/dw:afcnrvp8zqUvGrzr6,"README_WINDOWS.TXT" 4 | 96:+qK8Z4gA165/hquKNMi68zuEyMM9qNB26x:+RG4z6c1LyZOB26x,"README.TXT" 5 | -------------------------------------------------------------------------------- /tests/regression/server_root/conf/test.lua: -------------------------------------------------------------------------------- 1 | -- Test Lua Script to just print debug messages 2 | function main() 3 | m.log(1, "Test message."); 4 | m.log(2, "Test message."); 5 | m.log(3, "Test message."); 6 | m.log(4, "Test message."); 7 | m.log(5, "Test message."); 8 | m.log(6, "Test message."); 9 | m.log(7, "Test message."); 10 | m.log(8, "Test message."); 11 | m.log(9, "Test message."); 12 | 13 | return nil; 14 | end 15 | -------------------------------------------------------------------------------- /tests/regression/server_root/data/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/tests/regression/server_root/data/.empty -------------------------------------------------------------------------------- /tests/regression/server_root/data/ip.dir: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/tests/regression/server_root/data/ip.dir -------------------------------------------------------------------------------- /tests/regression/server_root/htdocs/index.html: -------------------------------------------------------------------------------- 1 | INDEX 2 | -------------------------------------------------------------------------------- /tests/regression/server_root/htdocs/test.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/tests/regression/server_root/htdocs/test.pdf -------------------------------------------------------------------------------- /tests/regression/server_root/htdocs/test.txt: -------------------------------------------------------------------------------- 1 | TEST 2 | -------------------------------------------------------------------------------- /tests/regression/server_root/htdocs/test2.txt: -------------------------------------------------------------------------------- 1 | TEST 2 2 | -------------------------------------------------------------------------------- /tests/regression/server_root/logs/audit/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/tests/regression/server_root/logs/audit/.empty -------------------------------------------------------------------------------- /tests/regression/server_root/logs/subdir/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/tests/regression/server_root/logs/subdir/.empty -------------------------------------------------------------------------------- /tests/regression/server_root/tmp/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/tests/regression/server_root/tmp/.empty -------------------------------------------------------------------------------- /tests/regression/server_root/upload/.empty: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/ModSecurity/b7295f8ee4300fdebf065ea5e5d54b11b8db73df/tests/regression/server_root/upload/.empty -------------------------------------------------------------------------------- /tests/tfn/base64Decode.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "base64Decode", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Test values with varying lengths to check padding 11 | { 12 | type => "tfn", 13 | name => "base64Decode", 14 | input => "VGVzdENhc2U=", 15 | output => "TestCase", 16 | ret => 1, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "base64Decode", 21 | input => "VGVzdENhc2Ux", 22 | output => "TestCase1", 23 | ret => 1, 24 | }, 25 | { 26 | type => "tfn", 27 | name => "base64Decode", 28 | input => "VGVzdENhc2UxMg==", 29 | output => "TestCase12", 30 | ret => 1, 31 | }, 32 | 33 | 34 | ### Check with a NUL 35 | { 36 | type => "tfn", 37 | name => "base64Decode", 38 | input => "VGVzdABDYXNl", 39 | output => "Test\0Case", 40 | ret => 1, 41 | }, 42 | 43 | ### Invalid 44 | # What should happen here? Probably just fail and leave alone. 45 | { 46 | type => "tfn", 47 | name => "base64Decode", 48 | input => "VGVzdENhc2U=\0VGVzdENhc2U=", 49 | output => "TestCase", 50 | ret => 1, 51 | }, 52 | -------------------------------------------------------------------------------- /tests/tfn/base64Encode.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "base64Encode", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Test values with varying lengths to check padding 11 | { 12 | type => "tfn", 13 | name => "base64Encode", 14 | input => "TestCase", 15 | output => "VGVzdENhc2U=", 16 | ret => 1, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "base64Encode", 21 | input => "TestCase1", 22 | output => "VGVzdENhc2Ux", 23 | ret => 1, 24 | }, 25 | { 26 | type => "tfn", 27 | name => "base64Encode", 28 | input => "TestCase12", 29 | output => "VGVzdENhc2UxMg==", 30 | ret => 1, 31 | }, 32 | 33 | ### Check with a NUL 34 | { 35 | type => "tfn", 36 | name => "base64Encode", 37 | input => "Test\0Case", 38 | output => "VGVzdABDYXNl", 39 | ret => 1, 40 | }, 41 | -------------------------------------------------------------------------------- /tests/tfn/compressWhitespace.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "compressWhitespace", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "compressWhitespace", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "compressWhitespace", 21 | input => "Test\0Case", 22 | output => "Test\0Case", 23 | ret => 0, 24 | }, 25 | { 26 | type => "tfn", 27 | name => "compressWhitespace", 28 | input => "Test Case", 29 | output => "Test Case", 30 | ret => 0, 31 | }, 32 | 33 | 34 | ### Compress space/tab 35 | { 36 | type => "tfn", 37 | name => "compressWhitespace", 38 | input => " Test \t Case ", 39 | output => " Test Case ", 40 | ret => 1, 41 | }, 42 | 43 | ### Pretty much everything in one 44 | { 45 | type => "tfn", 46 | name => "compressWhitespace", 47 | input => "This is a test case with a tab \t, vtab \x0b, newline \x0a, return \x0d, formfeed \f, and a NUL\0 in it with a CRLF at the end.\x0d\x0a", 48 | output => "This is a test case with a tab , vtab , newline , return , formfeed , and a NUL\0 in it with a CRLF at the end. ", 49 | ret => 1, 50 | }, 51 | -------------------------------------------------------------------------------- /tests/tfn/cssDecode.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "cssDecode", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "cssDecode", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "cssDecode", 21 | input => "Test\0Case", 22 | output => "Test\0Case", 23 | ret => 0, 24 | }, 25 | 26 | ### Valid Sequences 27 | { 28 | type => "tfn", 29 | name => "cssDecode", 30 | input => "test\\a\\b\\f\\n\\r\\t\\v\\?\\'\\\"\\0\\12\\123\\1234\\12345\\123456\\ff01\\ff5e\\\n\\0 string", 31 | output => qq(test\x0a\x0b\x0fnrtv?'"\x00\x12\x23\x34\x45\x56\x21\x7e\x00 string), 32 | ret => 1, 33 | }, 34 | 35 | ### Invalid Sequences 36 | # Trailing escape == line continuation with no line following (ie nothing) 37 | { 38 | type => "tfn", 39 | name => "cssDecode", 40 | input => "test\\", 41 | output => "test", 42 | ret => 1, 43 | }, 44 | 45 | # Edge cases 46 | # "\1A" == "\x1A" 47 | # "\1 A" == "\x01A" 48 | # "\1234567" == "\x567" 49 | # "\123456 7" == "\x567" 50 | # "\1x" == "\x01x" 51 | # "\1 x" == "\x01 x" 52 | { 53 | type => "tfn", 54 | name => "cssDecode", 55 | input => "\\1A\\1 A\\1234567\\123456 7\\1x\\1 x", 56 | output => "\x1A\x01A\x567\x567\x01x\x01x", 57 | ret => 1, 58 | }, 59 | -------------------------------------------------------------------------------- /tests/tfn/escapeSeqDecode.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "escapeSeqDecode", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "escapeSeqDecode", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "escapeSeqDecode", 21 | input => "Test\0Case", 22 | output => "Test\0Case", 23 | ret => 0, 24 | }, 25 | 26 | ### Valid Sequences 27 | { 28 | type => "tfn", 29 | name => "escapeSeqDecode", 30 | input => "\\a\\b\\f\\n\\r\\t\\v\\?\\'\\\"\\0\\12\\123\\x00\\xff", 31 | output => "\a\b\f\x0a\x0d\t\x0b?'\"\x00\x0a\x53\x00\xff", 32 | ret => 1, 33 | }, 34 | { 35 | type => "tfn", 36 | name => "escapeSeqDecode", 37 | input => "\\a\\b\\f\\n\\r\\t\\v\0\\?\\'\\\"\\0\\12\\123\\x00\\xff", 38 | output => "\a\b\f\x0a\x0d\t\x0b\0?'\"\x00\x0a\x53\x00\xff", 39 | ret => 1, 40 | }, 41 | 42 | ### Invalid Sequences 43 | # \8 and \9 are not octal 44 | # \666 is a byte overflow (0x1b6) and should be truncated to a byte as 0xb6 45 | # \xag and \xga are not hex, 46 | # \0123 is \012 + '3' 47 | { 48 | type => "tfn", 49 | name => "escapeSeqDecode", 50 | input => "\\8\\9\\666\\xag\\xga\\0123", 51 | output => "89\xb6xagxga\x0a3", 52 | ret => 1, 53 | }, 54 | 55 | # \x, \x0 lack enough hex digits 56 | { 57 | type => "tfn", 58 | name => "escapeSeqDecode", 59 | input => "\\x", 60 | output => "x", 61 | ret => 1, 62 | }, 63 | { 64 | type => "tfn", 65 | name => "escapeSeqDecode", 66 | input => "\\x\\x0", 67 | output => "xx0", 68 | ret => 1, 69 | }, 70 | { 71 | type => "tfn", 72 | name => "escapeSeqDecode", 73 | input => "\\x\\x0\0", 74 | output => "xx0\0", 75 | ret => 1, 76 | }, 77 | # Octal at end 78 | { 79 | type => "tfn", 80 | name => "escapeSeqDecode", 81 | input => "\\0", 82 | output => "\x00", 83 | ret => 1, 84 | }, 85 | { 86 | type => "tfn", 87 | name => "escapeSeqDecode", 88 | input => "\\01", 89 | output => "\x01", 90 | ret => 1, 91 | }, 92 | { 93 | type => "tfn", 94 | name => "escapeSeqDecode", 95 | input => "\\012", 96 | output => "\x0a", 97 | ret => 1, 98 | }, 99 | # A forward slash with nothing after 100 | { 101 | type => "tfn", 102 | name => "escapeSeqDecode", 103 | input => "\\", 104 | output => "\\", 105 | ret => 0, 106 | }, 107 | # A forward slash with NUL after 108 | { 109 | type => "tfn", 110 | name => "escapeSeqDecode", 111 | input => "\\\0", 112 | output => "\0", 113 | ret => 1, 114 | }, 115 | -------------------------------------------------------------------------------- /tests/tfn/hexDecode.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "hexDecode", 5 | input => "", 6 | output => "", 7 | ret => 1, 8 | }, 9 | 10 | ### Basic 11 | { 12 | type => "tfn", 13 | name => "hexDecode", 14 | input => "5465737443617365", 15 | output => "TestCase", 16 | ret => 1, 17 | }, 18 | 19 | ### Basic w/NULL 20 | { 21 | type => "tfn", 22 | name => "hexDecode", 23 | input => "546573740043617365", 24 | output => "Test\0Case", 25 | ret => 1, 26 | }, 27 | 28 | ### Invalid 29 | # What should happen here? Probably just fail and leave alone. 30 | { 31 | type => "tfn", 32 | name => "hexDecode", 33 | input => "01234567890a0z01234567890a", 34 | output => "\x01#Eg\x89\x0a#\x01#Eg\x89\x0a", 35 | ret => 1, 36 | }, 37 | { 38 | type => "tfn", 39 | name => "hexDecode", 40 | input => "01234567890az", 41 | output => "\x01#Eg\x89\x0a", 42 | ret => 1, 43 | }, 44 | { 45 | type => "tfn", 46 | name => "hexDecode", 47 | input => "01234567890a0", 48 | output => "\x01#Eg\x89\x0a", 49 | ret => 1, 50 | }, 51 | -------------------------------------------------------------------------------- /tests/tfn/hexEncode.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "hexEncode", 5 | input => "", 6 | output => "", 7 | ret => 1, 8 | }, 9 | 10 | ### Basic 11 | { 12 | type => "tfn", 13 | name => "hexEncode", 14 | input => "TestCase", 15 | output => "5465737443617365", 16 | ret => 1, 17 | }, 18 | 19 | ### Basic w/NULL 20 | { 21 | type => "tfn", 22 | name => "hexEncode", 23 | input => "Test\0Case", 24 | output => "546573740043617365", 25 | ret => 1, 26 | }, 27 | -------------------------------------------------------------------------------- /tests/tfn/htmlEntityDecode.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "htmlEntityDecode", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "htmlEntityDecode", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "htmlEntityDecode", 21 | input => "Test\0Case", 22 | output => "Test\0Case", 23 | ret => 0, 24 | }, 25 | 26 | ### Valid 27 | # With ; 28 | { 29 | type => "tfn", 30 | name => "htmlEntityDecode", 31 | input => "�� � \0d"&<> ", 32 | output => "\0\0\x20\x20\0\x20\0\x64\"&<>\xa0", 33 | ret => 1, 34 | }, 35 | # Without ; 36 | { 37 | type => "tfn", 38 | name => "htmlEntityDecode", 39 | input => "�� � \0d"&<> ", 40 | output => "\0\0\x20\x20\0\x20\0\x64\"&<>\xa0", 41 | ret => 1, 42 | }, 43 | 44 | ### Invalid 45 | { 46 | type => "tfn", 47 | name => "htmlEntityDecode", 48 | input => "&#xg;&#Xg;&#xg0;g;&#a;\0&#a2;a&#a00;a0; a;&foo;", 49 | output => "&#xg;&#Xg;&#xg0;\x02g;&#a;\0&#a2;\x03a&#a00;\x01a0;\x0aa;&foo;", 50 | ret => 1, 51 | }, 52 | { 53 | type => "tfn", 54 | name => "htmlEntityDecode", 55 | input => "&#xg&#Xg&#xg0g&#a\0&#a2a&#a00a0 a&foo", 56 | output => "&#xg&#Xg&#xg0\x02g&#a\0&#a2\x03a&#a00\x01a0\x0aa&foo", 57 | ret => 1, 58 | }, 59 | -------------------------------------------------------------------------------- /tests/tfn/jsDecode.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "jsDecode", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "jsDecode", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "jsDecode", 21 | input => "Test\0Case", 22 | output => "Test\0Case", 23 | ret => 0, 24 | }, 25 | 26 | ### Valid Sequences 27 | { 28 | type => "tfn", 29 | name => "jsDecode", 30 | input => "\\a\\b\\f\\n\\r\\t\\v\\?\\'\\\"\\0\\12\\123\\x00\\xff\\u0021\\uff01", 31 | output => "\a\b\f\x0a\x0d\t\x0b?'\"\x00\x0a\x53\x00\xff\x21\x21", 32 | ret => 1, 33 | }, 34 | { 35 | type => "tfn", 36 | name => "jsDecode", 37 | input => "\\a\\b\\f\\n\\r\\t\\v\0\\?\\'\\\"\\0\\12\\123\\x00\\xff\\u0021\\uff01", 38 | output => "\a\b\f\x0a\x0d\t\x0b\0?'\"\x00\x0a\x53\x00\xff\x21\x21", 39 | ret => 1, 40 | }, 41 | 42 | ### Invalid Sequences 43 | # \8 and \9 are not octal 44 | # \666 is \66 + '6' (JS does not allow the overflow as C does) 45 | # \u00ag, \u00ga, \u0zaa, \uz0aa are not hex 46 | # \xag and \xga are not hex, 47 | # \0123 is \012 + '3' 48 | { 49 | type => "tfn", 50 | name => "jsDecode", 51 | input => "\\8\\9\\666\\u00ag\\u00ga\\u0zaa\\uz0aa\\xag\\xga\\0123\\u00a", 52 | output => "89\x366u00agu00gau0zaauz0aaxagxga\x0a3u00a", 53 | ret => 1, 54 | }, 55 | 56 | # \x, \x0 lack enough hex digits 57 | { 58 | type => "tfn", 59 | name => "jsDecode", 60 | input => "\\x", 61 | output => "x", 62 | ret => 1, 63 | }, 64 | { 65 | type => "tfn", 66 | name => "jsDecode", 67 | input => "\\x\\x0", 68 | output => "xx0", 69 | ret => 1, 70 | }, 71 | { 72 | type => "tfn", 73 | name => "jsDecode", 74 | input => "\\x\\x0\0", 75 | output => "xx0\0", 76 | ret => 1, 77 | }, 78 | # \u, \u0 \u01, \u012 lack enough hex digits 79 | { 80 | type => "tfn", 81 | name => "jsDecode", 82 | input => "\\u", 83 | output => "u", 84 | ret => 1, 85 | }, 86 | { 87 | type => "tfn", 88 | name => "jsDecode", 89 | input => "\\u\\u0", 90 | output => "uu0", 91 | ret => 1, 92 | }, 93 | { 94 | type => "tfn", 95 | name => "jsDecode", 96 | input => "\\u\\u0\\u01", 97 | output => "uu0u01", 98 | ret => 1, 99 | }, 100 | { 101 | type => "tfn", 102 | name => "jsDecode", 103 | input => "\\u\\u0\\u01\\u012", 104 | output => "uu0u01u012", 105 | ret => 1, 106 | }, 107 | { 108 | type => "tfn", 109 | name => "jsDecode", 110 | input => "\\u\\u0\\u01\\u012\0", 111 | output => "uu0u01u012\0", 112 | ret => 1, 113 | }, 114 | # A forward slash with nothing after 115 | { 116 | type => "tfn", 117 | name => "jsDecode", 118 | input => "\\", 119 | output => "\\", 120 | ret => 0, 121 | }, 122 | # A forward slash with NUL after 123 | { 124 | type => "tfn", 125 | name => "jsDecode", 126 | input => "\\\0", 127 | output => "\0", 128 | ret => 1, 129 | }, 130 | -------------------------------------------------------------------------------- /tests/tfn/length.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "length", 5 | input => "", 6 | output => "0", 7 | ret => 1, 8 | }, 9 | 10 | 11 | ### Basic normal and large 12 | { 13 | type => "tfn", 14 | name => "length", 15 | input => "0123456789abcdef", 16 | output => "16", 17 | ret => 1, 18 | }, 19 | # ENH: This sometimes fails w/4096 length 20 | #{ 21 | # type => "tfn", 22 | # name => "length", 23 | # input => ('x' x 8192), 24 | # output => "8192", 25 | # ret => 1, 26 | #}, 27 | 28 | ### With TAB 29 | { 30 | type => "tfn", 31 | name => "length", 32 | input => "0123456789\tabcdef", 33 | output => "17", 34 | ret => 1, 35 | }, 36 | 37 | ### With NUL 38 | { 39 | type => "tfn", 40 | name => "length", 41 | input => "Test\0Case", 42 | output => "9", 43 | ret => 1, 44 | }, 45 | -------------------------------------------------------------------------------- /tests/tfn/lowercase.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "lowercase", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "lowercase", 14 | input => "testcase", 15 | output => "testcase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "lowercase", 21 | input => "test\0case", 22 | output => "test\0case", 23 | ret => 0, 24 | }, 25 | 26 | ### Basic 27 | { 28 | type => "tfn", 29 | name => "lowercase", 30 | input => "TestCase", 31 | output => "testcase", 32 | ret => 1, 33 | }, 34 | { 35 | type => "tfn", 36 | name => "lowercase", 37 | input => "Test\0Case", 38 | output => "test\0case", 39 | ret => 1, 40 | }, 41 | -------------------------------------------------------------------------------- /tests/tfn/md5.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "md5", 5 | input => "", 6 | output => "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42\x7e", 7 | ret => 1, 8 | }, 9 | 10 | ### Basic 11 | { 12 | type => "tfn", 13 | name => "md5", 14 | input => "TestCase", 15 | output => "\xc9\xab\xa2\xc3\xe6\x01\x26\x16\x9e\x80\xe9\xa2\x6b\xa2\x73\xc1", 16 | ret => 1, 17 | }, 18 | 19 | ### Binary w/NUL 20 | { 21 | type => "tfn", 22 | name => "md5", 23 | input => "\x00\x01\x02\x03\x04\x05\x06\x07\x08", 24 | output => "\xa6\xe7\xd3\xb4\x6f\xdf\xaf\x0b\xde\x2a\x1f\x83\x2a\x00\xd2\xde", 25 | ret => 1, 26 | }, 27 | -------------------------------------------------------------------------------- /tests/tfn/parityEven7bit.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "parityEven7bit", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "parityEven7bit", 14 | input => "cefijloqrtwx03569ABDGHKMNPSUVYZ", 15 | output => "cefijloqrtwx03569ABDGHKMNPSUVYZ", 16 | ret => 0, 17 | }, 18 | 19 | ### Parity 20 | { 21 | type => "tfn", 22 | name => "parityEven7bit", 23 | input => "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 24 | output => "\xe1\xe2c\xe4ef\xe7\xe8ij\xebl\xed\xeeo\xf0qr\xf3t\xf5\xf6wx\xf9\xfa0\xb1\xb23\xb456\xb7\xb89AB\xc3D\xc5\xc6GH\xc9\xcaK\xccMN\xcfP\xd1\xd2S\xd4UV\xd7\xd8YZ", 25 | ret => 1, 26 | }, 27 | { 28 | type => "tfn", 29 | name => "parityEven7bit", 30 | input => "abcdefghijklmnopqrstuvwxyz\x000123456789\x00ABCDEFGHIJKLMNOPQRSTUVWXYZ", 31 | output => "\xe1\xe2c\xe4ef\xe7\xe8ij\xebl\xed\xeeo\xf0qr\xf3t\xf5\xf6wx\xf9\xfa\x000\xb1\xb23\xb456\xb7\xb89\x00AB\xc3D\xc5\xc6GH\xc9\xcaK\xccMN\xcfP\xd1\xd2S\xd4UV\xd7\xd8YZ", 32 | ret => 1, 33 | }, 34 | 35 | -------------------------------------------------------------------------------- /tests/tfn/parityOdd7bit.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "parityOdd7bit", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "parityOdd7bit", 14 | input => "abdghkmnpsuvyz12478CEFIJLOQRTW", 15 | output => "abdghkmnpsuvyz12478CEFIJLOQRTW", 16 | ret => 0, 17 | }, 18 | 19 | ### Parity 20 | { 21 | type => "tfn", 22 | name => "parityOdd7bit", 23 | input => "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 24 | output => "ab\xe3d\xe5\xe6gh\xe9\xeak\xecmn\xefp\xf1\xf2s\xf4uv\xf7\xf8yz\xb012\xb34\xb5\xb678\xb9\xc1\xc2C\xc4EF\xc7\xc8IJ\xcbL\xcd\xceO\xd0QR\xd3T\xd5\xd6WX\xd9\xda", 25 | ret => 1, 26 | }, 27 | { 28 | type => "tfn", 29 | name => "parityOdd7bit", 30 | input => "abcdefghijklmnopqrstuvwxyz\x000123456789\x00ABCDEFGHIJKLMNOPQRSTUVWXYZ", 31 | output => "ab\xe3d\xe5\xe6gh\xe9\xeak\xecmn\xefp\xf1\xf2s\xf4uv\xf7\xf8yz\x80\xb012\xb34\xb5\xb678\xb9\x80\xc1\xc2C\xc4EF\xc7\xc8IJ\xcbL\xcd\xceO\xd0QR\xd3T\xd5\xd6WX\xd9\xda", 32 | ret => 1, 33 | }, 34 | 35 | -------------------------------------------------------------------------------- /tests/tfn/parityZero7bit.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "parityZero7bit", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "parityZero7bit", 14 | input => "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 15 | output => "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "parityZero7bit", 21 | input => "abcdefghijklmnopqrstuvwxyz\x000123456789\x00ABCDEFGHIJKLMNOPQRSTUVWXYZ", 22 | output => "abcdefghijklmnopqrstuvwxyz\x000123456789\x00ABCDEFGHIJKLMNOPQRSTUVWXYZ", 23 | ret => 0, 24 | }, 25 | 26 | ### Basic 27 | { 28 | type => "tfn", 29 | name => "parityZero7bit", 30 | input => "\x80\x00\x8f\xff", 31 | output => "\x00\x00\x0f\x7f", 32 | ret => 1, 33 | }, 34 | -------------------------------------------------------------------------------- /tests/tfn/removeNulls.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "removeNulls", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "removeNulls", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "removeNulls", 21 | input => "Test\x01Case", 22 | output => "Test\x01Case", 23 | ret => 0, 24 | }, 25 | 26 | 27 | ### Basics 28 | { 29 | type => "tfn", 30 | name => "removeNulls", 31 | input => "\0TestCase", 32 | output => "TestCase", 33 | ret => 1, 34 | }, 35 | { 36 | type => "tfn", 37 | name => "removeNulls", 38 | input => "Test\0Case", 39 | output => "TestCase", 40 | ret => 1, 41 | }, 42 | { 43 | type => "tfn", 44 | name => "removeNulls", 45 | input => "Test\0\0Case", 46 | output => "TestCase", 47 | ret => 1, 48 | }, 49 | { 50 | type => "tfn", 51 | name => "removeNulls", 52 | input => "TestCase\0", 53 | output => "TestCase", 54 | ret => 1, 55 | }, 56 | { 57 | type => "tfn", 58 | name => "removeNulls", 59 | input => "\0Test\0Case\0", 60 | output => "TestCase", 61 | ret => 1, 62 | }, 63 | -------------------------------------------------------------------------------- /tests/tfn/removeWhitespace.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "removeWhitespace", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "removeWhitespace", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "removeWhitespace", 21 | input => "Test\0Case", 22 | output => "Test\0Case", 23 | ret => 0, 24 | }, 25 | 26 | 27 | ### Remove space/tab 28 | { 29 | type => "tfn", 30 | name => "removeWhitespace", 31 | input => " Test \t Case ", 32 | output => "TestCase", 33 | ret => 1, 34 | }, 35 | 36 | ### Pretty much everything in one 37 | { 38 | type => "tfn", 39 | name => "removeWhitespace", 40 | input => "This is a test case with a tab \t, vtab \x0b, newline \x0a, return \x0d, formfeed \f, and a NUL\0 in it with a CRLF at the end.\x0d\x0a", 41 | output => "Thisisatestcasewithatab,vtab,newline,return,formfeed,andaNUL\0initwithaCRLFattheend.", 42 | ret => 1, 43 | }, 44 | -------------------------------------------------------------------------------- /tests/tfn/replaceNulls.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "replaceNulls", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "replaceNulls", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | 19 | 20 | ### Basics 21 | { 22 | type => "tfn", 23 | name => "replaceNulls", 24 | input => "\0TestCase", 25 | output => " TestCase", 26 | ret => 1, 27 | }, 28 | { 29 | type => "tfn", 30 | name => "replaceNulls", 31 | input => "Test\0Case", 32 | output => "Test Case", 33 | ret => 1, 34 | }, 35 | { 36 | type => "tfn", 37 | name => "replaceNulls", 38 | input => "Test\0\0Case", 39 | output => "Test Case", 40 | ret => 1, 41 | }, 42 | { 43 | type => "tfn", 44 | name => "replaceNulls", 45 | input => "TestCase\0", 46 | output => "TestCase ", 47 | ret => 1, 48 | }, 49 | { 50 | type => "tfn", 51 | name => "replaceNulls", 52 | input => "\0Test\0Case\0", 53 | output => " Test Case ", 54 | ret => 1, 55 | }, 56 | -------------------------------------------------------------------------------- /tests/tfn/sha1.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "sha1", 5 | input => "", 6 | output => "\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18\x90\xaf\xd8\x07\x09", 7 | ret => 1, 8 | }, 9 | 10 | ### Basic 11 | { 12 | type => "tfn", 13 | name => "sha1", 14 | input => "TestCase", 15 | output => "\xa7\x0c\xe3\x83\x89\xe3\x18\xbd\x2b\xe1\x8a\x01\x11\xc6\xdc\x76\xbd\x2c\xd9\xed", 16 | ret => 1, 17 | }, 18 | 19 | ### Binary w/NUL 20 | { 21 | type => "tfn", 22 | name => "sha1", 23 | input => "\x00\x01\x02\x03\x04\x05\x06\x07\x08", 24 | output => "\x63\xbf\x60\xc7\x10\x5a\x07\xa2\xb1\x25\xbb\xf8\x9e\x61\xab\xda\xbc\x69\x78\xc2", 25 | ret => 1, 26 | }, 27 | -------------------------------------------------------------------------------- /tests/tfn/trim.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "trim", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "trim", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "trim", 21 | input => "Test\0Case", 22 | output => "Test\0Case", 23 | ret => 0, 24 | }, 25 | 26 | ### Basics 27 | { 28 | type => "tfn", 29 | name => "trim", 30 | input => " TestCase", 31 | output => "TestCase", 32 | ret => 1, 33 | }, 34 | { 35 | type => "tfn", 36 | name => "trim", 37 | input => "TestCase ", 38 | output => "TestCase", 39 | ret => 1, 40 | }, 41 | { 42 | type => "tfn", 43 | name => "trim", 44 | input => " TestCase ", 45 | output => "TestCase", 46 | ret => 1, 47 | }, 48 | { 49 | type => "tfn", 50 | name => "trim", 51 | input => " Test Case ", 52 | output => "Test Case", 53 | ret => 1, 54 | }, 55 | { 56 | type => "tfn", 57 | name => "trim", 58 | input => " Test \0 Case ", 59 | output => "Test \0 Case", 60 | ret => 1, 61 | }, 62 | { 63 | type => "tfn", 64 | name => "trim", 65 | input => " Test \0 Case \r\n ", 66 | output => "Test \0 Case", 67 | ret => 1, 68 | }, 69 | -------------------------------------------------------------------------------- /tests/tfn/trimLeft.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "trimLeft", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "trimLeft", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "trimLeft", 21 | input => "Test\0Case", 22 | output => "Test\0Case", 23 | ret => 0, 24 | }, 25 | { 26 | type => "tfn", 27 | name => "trimLeft", 28 | input => "TestCase ", 29 | output => "TestCase ", 30 | ret => 0, 31 | }, 32 | 33 | 34 | ### Basics 35 | { 36 | type => "tfn", 37 | name => "trimLeft", 38 | input => " TestCase", 39 | output => "TestCase", 40 | ret => 1, 41 | }, 42 | { 43 | type => "tfn", 44 | name => "trimLeft", 45 | input => " TestCase ", 46 | output => "TestCase ", 47 | ret => 1, 48 | }, 49 | { 50 | type => "tfn", 51 | name => "trimLeft", 52 | input => " Test Case ", 53 | output => "Test Case ", 54 | ret => 1, 55 | }, 56 | { 57 | type => "tfn", 58 | name => "trimLeft", 59 | input => " Test \0 Case ", 60 | output => "Test \0 Case ", 61 | ret => 1, 62 | }, 63 | { 64 | type => "tfn", 65 | name => "trimLeft", 66 | input => " Test \0 Case \r\n ", 67 | output => "Test \0 Case \r\n ", 68 | ret => 1, 69 | }, 70 | -------------------------------------------------------------------------------- /tests/tfn/trimRight.t: -------------------------------------------------------------------------------- 1 | ### Empty 2 | { 3 | type => "tfn", 4 | name => "trimRight", 5 | input => "", 6 | output => "", 7 | ret => 0, 8 | }, 9 | 10 | ### Nothing 11 | { 12 | type => "tfn", 13 | name => "trimRight", 14 | input => "TestCase", 15 | output => "TestCase", 16 | ret => 0, 17 | }, 18 | { 19 | type => "tfn", 20 | name => "trimRight", 21 | input => "Test\0Case", 22 | output => "Test\0Case", 23 | ret => 0, 24 | }, 25 | { 26 | type => "tfn", 27 | name => "trimRight", 28 | input => " TestCase", 29 | output => " TestCase", 30 | ret => 0, 31 | }, 32 | 33 | ### Basics 34 | { 35 | type => "tfn", 36 | name => "trimRight", 37 | input => "TestCase ", 38 | output => "TestCase", 39 | ret => 1, 40 | }, 41 | { 42 | type => "tfn", 43 | name => "trimRight", 44 | input => " TestCase ", 45 | output => " TestCase", 46 | ret => 1, 47 | }, 48 | { 49 | type => "tfn", 50 | name => "trimRight", 51 | input => " Test Case ", 52 | output => " Test Case", 53 | ret => 1, 54 | }, 55 | { 56 | type => "tfn", 57 | name => "trimRight", 58 | input => " Test \0 Case ", 59 | output => " Test \0 Case", 60 | ret => 1, 61 | }, 62 | { 63 | type => "tfn", 64 | name => "trimRight", 65 | input => " Test \0 Case \r\n ", 66 | output => " Test \0 Case", 67 | ret => 1, 68 | }, 69 | -------------------------------------------------------------------------------- /tools/Makefile.am: -------------------------------------------------------------------------------- 1 | bin_SCRIPTS = rules-updater.pl 2 | -------------------------------------------------------------------------------- /tools/README: -------------------------------------------------------------------------------- 1 | These tools are built during the ModSecurity configure process run under the 2 | apache2 directory. To use them you will first need to run configure under 3 | the apache2 directory: 4 | 5 | ./configure [any options] 6 | 7 | -------------------------------------------------------------------------------- /tools/rules-updater-example.conf: -------------------------------------------------------------------------------- 1 | # This is an example configuration to be used with ruleset-updator.pl -c 2 | 3 | # The repository URI. 4 | RepositoryURI http://username:password@www.example.tld/repository/ 5 | 6 | # Where to download the rulesets to 7 | LocalRepository /path/to/repository 8 | 9 | # Where to unpack the rulesets (if Unpack is true) 10 | LocalRules /path/to/repository 11 | 12 | # What version (or version prefix) to use 13 | #Version 1.5 14 | 15 | # Should we unpack the ruleset to LocalRules? 16 | Unpack True 17 | 18 | # Email update notifications 19 | #NotifyEmail "modsec-admin@example.tld, someone@example.tld" 20 | #NotifyEmailFrom "ModSec Rules Updater " 21 | 22 | # Output lots of debugging info? 23 | Debug False 24 | -------------------------------------------------------------------------------- /validator/Makefile.am: -------------------------------------------------------------------------------- 1 | bin_PROGRAMS = validator 2 | 3 | validator_SOURCES = main.c 4 | 5 | # FIXME: Standalone does not mean that it will be a nginx build. 6 | validator_CFLAGS = -DVERSION_NGINX \ 7 | @APR_CFLAGS@ \ 8 | @APU_CFLAGS@ \ 9 | @APXS_CFLAGS@ \ 10 | @CURL_CFLAGS@ \ 11 | @LIBXML2_CFLAGS@ \ 12 | @LUA_CFLAGS@ \ 13 | @MODSEC_EXTRA_CFLAGS@ \ 14 | @PCRE_CFLAGS@ \ 15 | @YAJL_CFLAGS@ \ 16 | @SSDEEP_CFLAGS@ 17 | 18 | validator_CPPFLAGS = @APR_CPPFLAGS@ \ 19 | @LIBXML2_CPPFLAGS@ \ 20 | @PCRE_CPPFLAGS@ 21 | 22 | validator_LDADD = ../standalone/.libs/standalone.a \ 23 | @APR_LDADD@ \ 24 | @APU_LDADD@ \ 25 | @CURL_LDADD@ \ 26 | @LIBXML2_LDADD@ \ 27 | @LUA_LDADD@ \ 28 | @PCRE_LDADD@ \ 29 | @YAJL_LDADD@ \ 30 | -lstdc++ \ 31 | -lm 32 | 33 | validator_LDFLAGS = -no-undefined -module -avoid-version \ 34 | @APR_LDFLAGS@ \ 35 | @APU_LDFLAGS@ \ 36 | @CURL_LDFLAGS@ \ 37 | @APXS_LDFLAGS@ \ 38 | @LIBXML2_LDFLAGS@ \ 39 | @LUA_LDFLAGS@ \ 40 | @PCRE_LDFLAGS@ \ 41 | @YAJL_LDFLAGS@ \ 42 | @SSDEEP_LDFLAGS@ 43 | 44 | -------------------------------------------------------------------------------- /validator/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "standalone/api.h" 4 | 5 | static void print_log(void* obj, int level, char* str) 6 | { 7 | if (str != NULL) { 8 | puts(str); 9 | } 10 | } 11 | 12 | static void exit_with_error(const char* msg) 13 | { 14 | puts(msg); 15 | exit(EXIT_FAILURE); 16 | } 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | if (argc != 2) { 21 | exit_with_error("Invalid number of command line arguments"); 22 | } 23 | 24 | server_rec* modsec_server = modsecInit(); 25 | if (modsec_server == NULL) { 26 | exit_with_error("Failed to create ModSecurity server structure"); 27 | } 28 | char hostname[] = "localhost"; 29 | modsec_server->server_hostname = hostname; 30 | 31 | modsecSetLogHook(NULL, print_log); 32 | modsecStartConfig(); 33 | directory_config *config = modsecGetDefaultConfig(); 34 | if (config == NULL) { 35 | exit_with_error("Error creating default config"); 36 | } 37 | 38 | const char *err = modsecProcessConfig(config, argv[1], NULL); 39 | if (err != NULL) { 40 | exit_with_error(err); 41 | } 42 | 43 | modsecTerminate(); 44 | exit(EXIT_SUCCESS); 45 | } 46 | --------------------------------------------------------------------------------