├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── README.original.md ├── logo.png ├── naxsi_config └── naxsi_core.rules ├── naxsi_src ├── .clang-format ├── Makefile ├── config ├── ext │ └── libinjection │ │ ├── COPYING │ │ ├── example1.c │ │ ├── fptool.c │ │ ├── html5_cli.c │ │ ├── libinjection.h │ │ ├── libinjection_html5.c │ │ ├── libinjection_html5.h │ │ ├── libinjection_sqli.c │ │ ├── libinjection_sqli.h │ │ ├── libinjection_sqli_data.h │ │ ├── libinjection_xss.c │ │ ├── libinjection_xss.h │ │ ├── reader.c │ │ ├── sqli_cli.c │ │ ├── test_speed_sqli.c │ │ ├── test_speed_xss.c │ │ └── testdriver.c ├── naxsi.h ├── naxsi_config.c ├── naxsi_config.h ├── naxsi_json.c ├── naxsi_macros.h ├── naxsi_net.c ├── naxsi_net.h ├── naxsi_raw.c ├── naxsi_runtime.c ├── naxsi_skeleton.c └── naxsi_utils.c ├── nxapi ├── README.md ├── naxsi_kibana.dash ├── nx_datas │ └── country2coords.txt ├── nxapi.json ├── nxapi │ ├── __init__.py │ ├── nxparse.py │ ├── nxtransform.py │ └── nxtypificator.py ├── nxtool.py ├── requirements.txt ├── sample │ └── nginx.log ├── setup.py └── tpl │ ├── APPS │ └── google_analytics-ARGS.tpl │ ├── ARGS │ ├── precise-id.tpl │ ├── site-wide-id.tpl │ ├── url-wide-id-NAME.tpl │ └── url-wide-id.tpl │ ├── BODY │ ├── precise-id.tpl │ ├── site-wide-id.tpl │ ├── url-wide-id-BODY-NAME.tpl │ ├── url-wide-id.tpl │ └── var_name-wide-id.tpl │ ├── HEADERS │ └── cookies.tpl │ └── URI │ ├── global-url-0x_in_pircutres.tpl │ ├── site-wide-id.tpl │ └── url-wide-id.tpl └── t ├── 00naxsi_base.t ├── 01naxsi_whitelists.t ├── 02naxsi_bypass.t ├── 03naxsi_profile.t ├── 04naxsi_files.t ├── 05naxsi_advanced_whitelists.t ├── 06naxsi_weirds.t ├── 07naxsi_argnames.t ├── 08negative_whitelists.t ├── 09sqlmap_tamper.t ├── 10naxsi_modifiers.t ├── 11naxsi_newstyle_config.t ├── 12naxsi_argnames_extended.t ├── 13test.t ├── 14json.t ├── 15json_wl.t ├── 16rx_mz.t ├── 17case.t ├── 18ids.t ├── 19targets.t ├── 20sqlmap.t ├── 22libinjection-base.t ├── 23verylong.t ├── 24rawbody.t ├── 25extra-coverage.t ├── 26improved-matchzones.t ├── 27libinjection-blacklist.t ├── 28log.t ├── 29regression.t ├── 30regr.t ├── 31norules.t ├── 32utf8.t ├── 33ignoreip.t ├── 34ignorecidr.t ├── 35log_json.t ├── confs ├── nginx.conf.example ├── nginx_fuzz.conf.example ├── ngx_cycle.patch └── ngx_process_cycle.patch └── fuzz ├── big-json-post ├── big-multipart-post ├── med-get-bad-format ├── med-get-with-path ├── med-json-post ├── med-multipart-file-post ├── med-multipart-post ├── med-post-non-ascii ├── mini-get-nohost ├── mini-get-sig ├── mini-json-post ├── mini-ko-get ├── mini-multipart-post ├── mini-ok-get ├── mini-unknown-CT-post ├── mini-urlencded-post-2 ├── mini-urlencoded-post └── small-multipart-post /.gitattributes: -------------------------------------------------------------------------------- 1 | t/* linguist-vendored 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.tar.gz 2 | *.asc 3 | t/servroot/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | dist: xenial 2 | language: C 3 | 4 | os: 5 | - linux 6 | 7 | cache: 8 | - apt 9 | - pip 10 | 11 | env: 12 | global: 13 | - VER_NGINX=1.9.11 14 | - COV=0 15 | 16 | compiler: 17 | - clang 18 | - gcc 19 | 20 | addons: 21 | apt: 22 | packages: 23 | - lcov 24 | - cpanminus 25 | 26 | install: 27 | - gem install coveralls-lcov 28 | - cd ./naxsi_src 29 | - if [ "$CC" == "clang" ]; then COV=0; fi 30 | - make 31 | - sudo cpanm -v --notest Test::Nginx 32 | 33 | before_script: 34 | - lcov --directory "../nginx-${VER_NGINX}" --zerocounters 35 | 36 | script: make test 37 | 38 | after_failure: 39 | - cat ../t/servroot/logs/error.log 40 | - cat /tmp/ngx_error.log 41 | - cat /tmp/ngx_access.log 42 | 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![naxsi](https://raw.githubusercontent.com/nbs-system/naxsi/master/logo.png) 2 | 3 | # Project Status 4 | 5 | This is a project status update regarding Naxsi. 6 | 7 | **As you may have noticed, the development of Naxsi has been stopped and the repository will be archived for historical reasons. This means that no new updates or bug fixes will be released for this version.** 8 | 9 | However, if you wish to update to newer versions of Naxsi, we recommend that you use the new repository at https://github.com/wargio/naxsi. This repository has been actively maintained and updated with new features and bug fixes. 10 | 11 | We understand that this news may be disappointing for some of our users who have been relying on Naxsi for their web application security needs. We want to assure you that we are committed to providing the best possible solutions for your security needs and encourage you to explore our security products. 12 | 13 | Thank you for your understanding and continued support. 14 | 15 | ## What is Naxsi? 16 | 17 | NAXSI means [Nginx](http://nginx.org/) Anti [XSS](https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29) & [SQL Injection](https://www.owasp.org/index.php/SQL_injection). 18 | 19 | Technically, it is a third party nginx module, available as a package for 20 | many UNIX-like platforms. This module, by default, reads a small subset of 21 | [simple (and readable) rules](https://github.com/nbs-system/naxsi/blob/master/naxsi_config/naxsi_core.rules) 22 | containing 99% of known patterns involved in 23 | website vulnerabilities. For example, `<`, `|` or `drop` are not supposed 24 | to be part of a URI. 25 | 26 | Being very simple, those patterns may match legitimate queries, it is 27 | the Naxsi's administrator duty to add specific rules that will whitelist 28 | legitimate behaviours. The administrator can either add whitelists manually 29 | by analyzing nginx's error log, or (recommended) start the project with an 30 | intensive auto-learning phase that will automatically generate whitelisting 31 | rules regarding a website's behaviour. 32 | 33 | In short, Naxsi behaves like a DROP-by-default firewall, the only task 34 | is to add required ACCEPT rules for the target website to work properly. 35 | 36 | ## Why is it different? 37 | 38 | Contrary to most Web Application Firewalls, Naxsi doesn't rely on a 39 | signature base like an antivirus, and thus cannot be circumvented by an 40 | "unknown" attack pattern. 41 | Naxsi is [Free software](https://www.gnu.org/licenses/gpl.html) (as in freedom) 42 | and free (as in free beer) to use. 43 | 44 | ## What does it run on? 45 | Naxsi should be compatible with any nginx version. 46 | 47 | It depends on `libpcre` for its regexp support, and is reported to work great on NetBSD, FreeBSD, OpenBSD, Debian, Ubuntu and CentOS. 48 | -------------------------------------------------------------------------------- /README.original.md: -------------------------------------------------------------------------------- 1 | ![naxsi](https://raw.githubusercontent.com/nbs-system/naxsi/master/logo.png) 2 | 3 | [![coverity](https://scan.coverity.com/projects/1883/badge.svg)](https://scan.coverity.com/projects/1883) 4 | [![travis-ci](https://travis-ci.org/nbs-system/naxsi.svg?branch=master)](https://travis-ci.org/nbs-system/naxsi) 5 | [![coveralls](https://coveralls.io/repos/github/nbs-system/naxsi/badge.svg?branch=master)](https://coveralls.io/github/nbs-system/naxsi?branch=master) 6 | [![codecov](http://codecov.io/github/nbs-system/naxsi/coverage.svg?branch=master)](http://codecov.io/github/nbs-system/naxsi?branch=master) 7 | [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/740/badge)](https://bestpractices.coreinfrastructure.org/projects/740) 8 | [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg)](https://gitter.im/nbs-system/naxsi) 9 | 10 | ### We need your help 11 | 12 | [Please fill in this little feedback survey](https://docs.google.com/spreadsheet/viewform?formkey=dG9UWDFuTEhiWWt4UF9fZEtwWFVJUlE6MQ), 2 minutes of your time, great help for us ! 13 | 14 | 15 | ## What is Naxsi? 16 | 17 | NAXSI means [Nginx]( http://nginx.org/ ) Anti [XSS]( https://www.owasp.org/index.php/Cross-site_Scripting_%28XSS%29 ) & [SQL Injection]( https://www.owasp.org/index.php/SQL_injection ). 18 | 19 | Technically, it is a third party nginx module, available as a package for 20 | many UNIX-like platforms. This module, by default, reads a small subset of 21 | [simple (and readable) rules]( https://github.com/nbs-system/naxsi/blob/master/naxsi_config/naxsi_core.rules ) 22 | containing 99% of known patterns involved in 23 | website vulnerabilities. For example, `<`, `|` or `drop` are not supposed 24 | to be part of a URI. 25 | 26 | Being very simple, those patterns may match legitimate queries, it is 27 | the Naxsi's administrator duty to add specific rules that will whitelist 28 | legitimate behaviours. The administrator can either add whitelists manually 29 | by analyzing nginx's error log, or (recommended) start the project with an 30 | intensive auto-learning phase that will automatically generate whitelisting 31 | rules regarding a website's behaviour. 32 | 33 | In short, Naxsi behaves like a DROP-by-default firewall, the only task 34 | is to add required ACCEPT rules for the target website to work properly. 35 | 36 | ## Why is it different? 37 | 38 | Contrary to most Web Application Firewalls, Naxsi doesn't rely on a 39 | signature base like an antivirus, and thus cannot be circumvented by an 40 | "unknown" attack pattern. 41 | Naxsi is [Free software]( https://www.gnu.org/licenses/gpl.html ) (as in freedom) 42 | and free (as in free beer) to use. 43 | 44 | ## What does it run on? 45 | Naxsi should be compatible with any nginx version. 46 | 47 | It depends on `libpcre` for its regexp support, and is reported to work great on NetBSD, FreeBSD, OpenBSD, Debian, Ubuntu and CentOS. 48 | 49 | ### Getting started 50 | 51 | - The [documentation](https://github.com/nbs-system/naxsi/wiki) 52 | - Some [rules]( https://github.com/nbs-system/naxsi-rules ) for mainstream software 53 | - The [nxapi/nxtool]( https://github.com/nbs-system/naxsi/tree/master/nxapi ) to generate rules 54 | 55 | 56 | nxapi-dashboard logo 57 | 58 | ## Security issues 59 | 60 | 61 | If you find a security issue, please send us a mail to the security user, on nbs-system.com, using the gpg key 498C46FF087EDC36E7EAF9D445414A82A9B22D78: 62 | 63 | ``` 64 | -----BEGIN PGP PUBLIC KEY BLOCK----- 65 | 66 | mQENBFnKHhoBCADaOa0MKEqRy0h2ohIzczblzkMQCbU9oD1HwJ1VkYnn7TGW2iKi 67 | NISxisExIXpy2Bn/pA27GiV0V/Do3NL6D9r0oOCrGR27muGM0N/dk9UMv7MWw8zv 68 | K8cO+Sa28s0cAv7r2ogUJj5YOo8D4wHEpE8424TE89V9+Qg/SaFCxKoELFP0c7wu 69 | mtsm0PnL65piZ1EB7lQo2gxg+8AV45MD1Y2rREMKUoZE23X+nXKsmEh9BFEPaU5M 70 | 7WQp0NasqeMNoGhwfw9ttVAeLhkEkaTjW1PkNRIb7vrtV9KVb5uKucflfbOnDlzu 71 | tQ9U3tYto0mcSCRchAClfEmoSi/0mKyb5N6ZABEBAAG0NVNlY3VyaXR5IHRlYW0g 72 | b2YgTkJTIFN5c3RlbSA8c2VjdXJpdHlAbmJzLXN5c3RlbS5jb20+iQE3BBMBCAAh 73 | BQJZyh4aAhsDBQsJCAcCBhUICQoLAgQWAgMBAh4BAheAAAoJEEVBSoKpsi14jy0H 74 | /1/XB9THhvmG0ow81sld2Zx8qhnNed8VvYDS6mEjpDWNVPxENwDbnakEjisq1Hrb 75 | 2UQPYCyQ5dekPNFVwQHIGXkX0eb1Ank+4esBJuEpQ2985tgNhJy5ZX+Imb5C8nZC 76 | 90uYSN1UUg559nUsFeElOXSEH6tIXK/TvjsvMYoi2Ukl6lb7PbIU2fjLY9Iqv3QY 77 | 32p8/Bl1fVKWbXOk0HDgJ6zA3Kr56QhZOLBkxjOa2XAnnIE76jZxUJ9qPCwWd1vW 78 | GFxtx1Y+eZriqHiC9CPe6aBWcIHaTXSu1WBbXrFu8/eCWw243Rxm8l9wgA/a7VWq 79 | WBfO45IhJUwh95naRpw8/4a5AQ0EWcoeGgEIAJtzSyyzfn2RX+BsyoRFANUpIgrV 80 | /9eohYQVNqK3AFthmq7Kjmt4+hszF5+0wCFmWwYqGnqk1/dsWmqpkXsJldEn6oPJ 81 | Bng+Dc67Yki2dR3TroAf95UmI08fhyM7TMXp8m46BPRRMzPNwalEeEm49Oclmfxb 82 | JsWWCChWVLWGz2xgPEAv3fPHqus7Rwz/WIl53l/qy1Wf0ewmjRpVEfnEMKBExtBK 83 | 4kRxQ40LzUZ1SfpyGc3nMbswhevT7/klqrdJdCnlu67Y/IfRGxGZuNj1n1Dib3Hx 84 | zTBHo3Y2R3BB93Ix8dkbLaxLqFbOYVdijCgJklqUWhx7btpQ2xnZyzyCMuUAEQEA 85 | AYkBHwQYAQgACQUCWcoeGgIbDAAKCRBFQUqCqbIteFRvB/9u3Mae8n8ELrJKOn+P 86 | PEbWjutObIuTplvY4QcbnNb9dsgsKryamp4CFJsA5XuitPpC31GDMXBZO5/LLOuH 87 | HoMaXFJdic0NToL/3REhu+aZkNIU6S/iaPRNVhkSV4lwQsvncz+nBaiDUJjyfJm2 88 | kEjVcRTM8yqzcNo/9Gn0ts+XCUqRj7+S1M4Bj3NySoO/w2n+7OLbIAj+wQZcj3Gf 89 | 5QhBYaY4YaFxrJE0IZxyXGHw8xhKR6AN+u4TO7LRCW+cWV/sHWir1MXieJoEG8+R 90 | W/BhrB0Rz5uxOXMoGCCD2TUiHq7zpuHGnYFVmAnHQZaaQxXve4VrcmznxgpV8lpW 91 | mZug 92 | =+eIv 93 | -----END PGP PUBLIC KEY BLOCK----- 94 | ``` 95 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbs-system/naxsi/a59462b8c2f9c2c0c0fbc3ceb287ee5d60b652c3/logo.png -------------------------------------------------------------------------------- /naxsi_config/naxsi_core.rules: -------------------------------------------------------------------------------- 1 | ################################## 2 | ## INTERNAL RULES IDS:1-999 ## 3 | ################################## 4 | #@MainRule "msg:weird request, unable to parse" id:1; 5 | #@MainRule "msg:request too big, stored on disk and not parsed" id:2; 6 | #@MainRule "msg:invalid hex encoding, null bytes" id:10; 7 | #@MainRule "msg:unknown content-type" id:11; 8 | #@MainRule "msg:invalid formatted url" id:12; 9 | #@MainRule "msg:invalid POST format" id:13; 10 | #@MainRule "msg:invalid POST boundary" id:14; 11 | #@MainRule "msg:invalid JSON" id:15; 12 | #@MainRule "msg:empty POST" id:16; 13 | #@MainRule "msg:libinjection_sql" id:17; 14 | #@MainRule "msg:libinjection_xss" id:18; 15 | #@MainRule "msg:no generic rules" id:19; 16 | #@MainRule "msg:bad utf8" id:20; 17 | 18 | 19 | 20 | ################################## 21 | ## SQL Injections IDs:1000-1099 ## 22 | ################################## 23 | MainRule "rx:select|union|update|delete|insert|table|from|ascii|hex|unhex|drop|load_file|substr|group_concat|dumpfile" "msg:sql keywords" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1000; 24 | MainRule "str:\"" "msg:double quote" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8,$XSS:8" id:1001; 25 | MainRule "str:0x" "msg:0x, possible hex encoding" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:2" id:1002; 26 | ## Hardcore rules 27 | MainRule "str:/*" "msg:mysql comment (/*)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8" id:1003; 28 | MainRule "str:*/" "msg:mysql comment (*/)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8" id:1004; 29 | MainRule "str:|" "msg:mysql keyword (|)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8" id:1005; 30 | MainRule "str:&&" "msg:mysql keyword (&&)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8" id:1006; 31 | ## end of hardcore rules 32 | MainRule "str:--" "msg:mysql comment (--)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1007; 33 | MainRule "str:;" "msg:semicolon" "mz:BODY|URL|ARGS" "s:$SQL:4,$XSS:8" id:1008; 34 | MainRule "str:=" "msg:equal sign in var, probable sql/xss" "mz:ARGS|BODY" "s:$SQL:2" id:1009; 35 | MainRule "str:(" "msg:open parenthesis, probable sql/xss" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$SQL:4,$XSS:8" id:1010; 36 | MainRule "str:)" "msg:close parenthesis, probable sql/xss" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$SQL:4,$XSS:8" id:1011; 37 | MainRule "str:'" "msg:simple quote" "mz:ARGS|BODY|URL|$HEADERS_VAR:Cookie" "s:$SQL:4,$XSS:8" id:1013; 38 | MainRule "str:," "msg:comma" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1015; 39 | MainRule "str:#" "msg:mysql comment (#)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1016; 40 | MainRule "str:@@" "msg:double arobase (@@)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1017; 41 | 42 | ############################### 43 | ## OBVIOUS RFI IDs:1100-1199 ## 44 | ############################### 45 | MainRule "str:http://" "msg:http:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1100; 46 | MainRule "str:https://" "msg:https:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1101; 47 | MainRule "str:ftp://" "msg:ftp:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1102; 48 | MainRule "str:php://" "msg:php:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1103; 49 | MainRule "str:sftp://" "msg:sftp:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1104; 50 | MainRule "str:zlib://" "msg:zlib:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1105; 51 | MainRule "str:data://" "msg:data:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1106; 52 | MainRule "str:glob://" "msg:glob:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1107; 53 | MainRule "str:phar://" "msg:phar:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1108; 54 | MainRule "str:file://" "msg:file:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1109; 55 | MainRule "str:gopher://" "msg:gopher:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1110; 56 | MainRule "str:zip://" "msg:zip:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1111; 57 | MainRule "str:expect://" "msg:expect:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1112; 58 | MainRule "str:input://" "msg:input:// scheme" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$RFI:8" id:1113; 59 | 60 | ####################################### 61 | ## Directory traversal IDs:1200-1299 ## 62 | ####################################### 63 | MainRule "str:.." "msg:double dot" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$TRAVERSAL:4" id:1200; 64 | MainRule "str:/etc/passwd" "msg:obvious probe" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$TRAVERSAL:4" id:1202; 65 | MainRule "str:c:\\" "msg:obvious windows path" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$TRAVERSAL:4" id:1203; 66 | MainRule "str:cmd.exe" "msg:obvious probe" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$TRAVERSAL:4" id:1204; 67 | MainRule "str:\\" "msg:backslash" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$TRAVERSAL:4" id:1205; 68 | #MainRule "str:/" "msg:slash in args" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$TRAVERSAL:2" id:1206; 69 | MainRule "str:/..;/" "msg:dir traversal bypass" "mz:ARGS|BODY|$HEADERS_VAR:Cookie" "s:$TRAVERSAL:2" id:1207; 70 | 71 | ######################################## 72 | ## Cross Site Scripting IDs:1300-1399 ## 73 | ######################################## 74 | MainRule "str:<" "msg:html open tag" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1302; 75 | MainRule "str:>" "msg:html close tag" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1303; 76 | MainRule "str:[" "msg:open square backet ([), possible js" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$XSS:4" id:1310; 77 | MainRule "str:]" "msg:close square bracket (]), possible js" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$XSS:4" id:1311; 78 | MainRule "str:~" "msg:tilde (~) character" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$XSS:4" id:1312; 79 | MainRule "str:`" "msg:grave accent (`)" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1314; 80 | MainRule "rx:%[23]." "msg:double encoding" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1315; 81 | 82 | #################################### 83 | ## Evading tricks IDs: 1400-1500 ## 84 | #################################### 85 | MainRule "str:&#" "msg:utf7/8 encoding" "mz:ARGS|BODY|URL|$HEADERS_VAR:Cookie" "s:$EVADE:4" id:1400; 86 | MainRule "str:%U" "msg:M$ encoding" "mz:ARGS|BODY|URL|$HEADERS_VAR:Cookie" "s:$EVADE:4" id:1401; 87 | 88 | ############################# 89 | ## File uploads: 1500-1600 ## 90 | ############################# 91 | MainRule "rx:\.ph|\.asp|\.ht|\.jsp" "msg:asp/php/jsp file upload" "mz:FILE_EXT" "s:$UPLOAD:8" id:1500; 92 | -------------------------------------------------------------------------------- /naxsi_src/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: Mozilla 4 | AccessModifierOffset: -2 5 | AlignAfterOpenBracket: Align 6 | AlignConsecutiveMacros: true 7 | AlignConsecutiveAssignments: true 8 | AlignConsecutiveDeclarations: true 9 | AlignEscapedNewlines: Right 10 | AlignOperands: true 11 | AlignTrailingComments: true 12 | AllowAllArgumentsOnNextLine: true 13 | AllowAllConstructorInitializersOnNextLine: true 14 | AllowAllParametersOfDeclarationOnNextLine: false 15 | AllowShortBlocksOnASingleLine: Never 16 | AllowShortCaseLabelsOnASingleLine: false 17 | AllowShortFunctionsOnASingleLine: Inline 18 | AllowShortLambdasOnASingleLine: All 19 | AllowShortIfStatementsOnASingleLine: Never 20 | AllowShortLoopsOnASingleLine: false 21 | AlwaysBreakAfterDefinitionReturnType: TopLevel 22 | AlwaysBreakAfterReturnType: TopLevel 23 | AlwaysBreakBeforeMultilineStrings: false 24 | AlwaysBreakTemplateDeclarations: Yes 25 | BinPackArguments: false 26 | BinPackParameters: false 27 | BraceWrapping: 28 | AfterCaseLabel: false 29 | AfterClass: true 30 | AfterControlStatement: false 31 | AfterEnum: true 32 | AfterFunction: true 33 | AfterNamespace: false 34 | AfterObjCDeclaration: false 35 | AfterStruct: true 36 | AfterUnion: true 37 | AfterExternBlock: true 38 | BeforeCatch: false 39 | BeforeElse: false 40 | IndentBraces: false 41 | SplitEmptyFunction: true 42 | SplitEmptyRecord: false 43 | SplitEmptyNamespace: true 44 | BreakBeforeBinaryOperators: None 45 | BreakBeforeBraces: Mozilla 46 | BreakBeforeInheritanceComma: false 47 | BreakInheritanceList: BeforeComma 48 | BreakBeforeTernaryOperators: true 49 | BreakConstructorInitializersBeforeComma: false 50 | BreakConstructorInitializers: BeforeComma 51 | BreakAfterJavaFieldAnnotations: false 52 | BreakStringLiterals: true 53 | ColumnLimit: 100 54 | CommentPragmas: '^ IWYU pragma:' 55 | CompactNamespaces: false 56 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 57 | ConstructorInitializerIndentWidth: 2 58 | ContinuationIndentWidth: 2 59 | Cpp11BracedListStyle: false 60 | DeriveLineEnding: true 61 | DerivePointerAlignment: false 62 | DisableFormat: false 63 | ExperimentalAutoDetectBinPacking: false 64 | FixNamespaceComments: false 65 | ForEachMacros: 66 | - foreach 67 | - Q_FOREACH 68 | - BOOST_FOREACH 69 | IncludeBlocks: Preserve 70 | IncludeCategories: 71 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 72 | Priority: 2 73 | SortPriority: 0 74 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 75 | Priority: 3 76 | SortPriority: 0 77 | - Regex: '.*' 78 | Priority: 1 79 | SortPriority: 0 80 | IncludeIsMainRegex: '(Test)?$' 81 | IncludeIsMainSourceRegex: '' 82 | IndentCaseLabels: true 83 | IndentGotoLabels: true 84 | IndentPPDirectives: None 85 | IndentWidth: 2 86 | IndentWrappedFunctionNames: false 87 | JavaScriptQuotes: Leave 88 | JavaScriptWrapImports: true 89 | KeepEmptyLinesAtTheStartOfBlocks: true 90 | MacroBlockBegin: '' 91 | MacroBlockEnd: '' 92 | MaxEmptyLinesToKeep: 1 93 | NamespaceIndentation: None 94 | ObjCBinPackProtocolList: Auto 95 | ObjCBlockIndentWidth: 2 96 | ObjCSpaceAfterProperty: true 97 | ObjCSpaceBeforeProtocolList: false 98 | PenaltyBreakAssignment: 2 99 | PenaltyBreakBeforeFirstCallParameter: 19 100 | PenaltyBreakComment: 300 101 | PenaltyBreakFirstLessLess: 120 102 | PenaltyBreakString: 1000 103 | PenaltyBreakTemplateDeclaration: 10 104 | PenaltyExcessCharacter: 1000000 105 | PenaltyReturnTypeOnItsOwnLine: 200 106 | PointerAlignment: Left 107 | ReflowComments: true 108 | SortIncludes: true 109 | SortUsingDeclarations: true 110 | SpaceAfterCStyleCast: false 111 | SpaceAfterLogicalNot: false 112 | SpaceAfterTemplateKeyword: false 113 | SpaceBeforeAssignmentOperators: true 114 | SpaceBeforeCpp11BracedList: false 115 | SpaceBeforeCtorInitializerColon: true 116 | SpaceBeforeInheritanceColon: true 117 | SpaceBeforeParens: ControlStatements 118 | SpaceBeforeRangeBasedForLoopColon: true 119 | SpaceInEmptyBlock: false 120 | SpaceInEmptyParentheses: false 121 | SpacesBeforeTrailingComments: 1 122 | SpacesInAngles: false 123 | SpacesInConditionalStatement: false 124 | SpacesInContainerLiterals: true 125 | SpacesInCStyleCastParentheses: false 126 | SpacesInParentheses: false 127 | SpacesInSquareBrackets: false 128 | SpaceBeforeSquareBrackets: false 129 | Standard: Latest 130 | StatementMacros: 131 | - Q_UNUSED 132 | - QT_REQUIRE_VERSION 133 | TabWidth: 8 134 | UseCRLF: false 135 | UseTab: Never 136 | ... 137 | 138 | -------------------------------------------------------------------------------- /naxsi_src/Makefile: -------------------------------------------------------------------------------- 1 | CORE_VERS := $(shell grep NAXSI_VERSION naxsi.h | cut -d '"' -f 2) 2 | MOD_PATH := $(shell pwd) 3 | TMP_DIR := /tmp/nginx/ 4 | 5 | # Keys for coverity 6 | CAN := 7 | CAK := 8 | 9 | #Mode: coverage, fuzz, or base 10 | COV ?= 0 11 | FUZZ ?= 0 12 | STOCK ?= 1 13 | 14 | #Allows to force for specific UT only 15 | #TEST := "" 16 | NGINX_VERS := "1.19.2" 17 | 18 | 19 | NGINX_OPTIONS="--with-select_module" 20 | NGINX_OPTIONS+="--conf-path=/tmp/naxsi_ut/nginx.conf" 21 | NGINX_OPTIONS+="--http-client-body-temp-path=/tmp/naxsi_ut/body/" 22 | NGINX_OPTIONS+="--http-fastcgi-temp-path=/tmp/naxsi_ut/fastcgi/" 23 | NGINX_OPTIONS+="--http-proxy-temp-path=/tmp/naxsi_ut/proxy/" 24 | NGINX_OPTIONS+="--lock-path=/tmpnginx.lock" 25 | NGINX_OPTIONS+="--pid-path=/tmp/naxsi_ut/nginx.pid" 26 | NGINX_OPTIONS+="--modules-path=/tmp/naxsi_ut/modules/" 27 | NGINX_OPTIONS+="--without-mail_pop3_module" 28 | NGINX_OPTIONS+="--without-mail_smtp_module" 29 | NGINX_OPTIONS+="--without-mail_imap_module" 30 | NGINX_OPTIONS+="--with-http_v2_module" 31 | NGINX_OPTIONS+="--without-http_uwsgi_module" 32 | NGINX_OPTIONS+="--without-http_scgi_module" 33 | NGINX_OPTIONS+="--prefix=/tmp" 34 | #for coverity NGINX_OPTIONS+="--with-cc=/usr/bin/gcc-6" 35 | #for coverity NGINX_OPTIONS+="--add-dynamic-module=$(MOD_PATH)" 36 | 37 | CFLAGS:="-Wextra -Wall -Werror" 38 | 39 | all: nginx_download configure build install deploy 40 | 41 | re: clean all test 42 | 43 | format_code: 44 | clang-format --verbose -i $(MOD_PATH)/*.c 45 | 46 | FUZZ_PATH := "../fuzz" 47 | AFL_PATH := $(PWD)"/"$(FUZZ_PATH)"/afl/" 48 | 49 | install_afl: 50 | mkdir -p $(FUZZ_PATH) 51 | cd $(FUZZ_PATH) && (wget -nc --no-clobber "http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz" || exit 1) 52 | cd $(FUZZ_PATH) && (test -d $(AFL_PATH) || (mkdir $(FUZZ_PATH)"/afl" && tar -C $(AFL_PATH)/ -xzf afl-latest.tgz --strip-components=1)) 53 | cd $(FUZZ_PATH) && (make -C $(AFL_PATH) && make -C $(AFL_PATH)"/llvm_mode" clean all afl-clang-fast) 54 | 55 | install_preeny: 56 | cd $(FUZZ_PATH) && (test -d preeny || git clone https://github.com/zardus/preeny.git) 57 | cd $(FUZZ_PATH) && make -C preeny/src/ 58 | 59 | fuzz_build: install_afl install_preeny 60 | mkdir -p $(FUZZ_PATH) 61 | STOCK=0 FUZZ=1 make nginx_download 62 | cd $(TMP_DIR) && patch -p1 "./src/core/ngx_cycle.c" < $(MOD_PATH)"/../t/confs/ngx_cycle.patch" 63 | cd $(TMP_DIR) && patch -p1 "./src/os/unix/ngx_process_cycle.c" < $(MOD_PATH)"/../t/confs/ngx_process_cycle.patch" 64 | STOCK=0 FUZZ=1 make configure build install deploy 65 | 66 | fuzz: 67 | LD_PRELOAD=$(FUZZ_PATH)"/preeny/src/desock.so" $(AFL_PATH)"afl-fuzz" -t 10 -i "../t/fuzz/" -o $(FUZZ_PATH)/findings $(TMP_DIR)/objs/nginx 68 | 69 | clean: 70 | rm -f "nginx-"$(NGINX_VERS)".tar.gz" 71 | rm -f "nginx-"$(NGINX_VERS)".tar.gz.asc" 72 | rm -rf /tmp/naxsi_ut/ 73 | rm -rf $(TMP_DIR)/ 74 | rm -rf $(FUZZ_PATH)/ 75 | 76 | nginx_download: 77 | wget --no-clobber "http://nginx.org/download/nginx-"$(NGINX_VERS)".tar.gz" || exit 1 78 | wget --no-clobber "http://nginx.org/download/nginx-"$(NGINX_VERS)".tar.gz.asc" || exit 1 79 | # gpg --keyserver pgp.key-server.io --recv-keys 0x251a28de2685aed4 0x520A9993A1C052F8 80 | # gpg --verify "nginx-"$(NGINX_VERS)".tar.gz.asc" "nginx-"$(NGINX_VERS)".tar.gz" || exit 1 81 | mkdir -p $(TMP_DIR)/ 82 | tar -C $(TMP_DIR)/ -xzf nginx-$(NGINX_VERS).tar.gz --strip-components=1 83 | 84 | configure: 85 | #build non dynamic module (faster) for fuzz/afl 86 | ifeq ($(FUZZ),1) 87 | cd $(TMP_DIR)/ && AFL_PATH=$(AFL_PATH) ./configure --with-cc=$(AFL_PATH)"/llvm_mode/afl-clang-fast" --with-cc-opt="-O3" $(NGINX_OPTIONS) --add-module=$(MOD_PATH) --error-log-path=/dev/null --http-log-path=/dev/null 88 | endif 89 | 90 | ifeq ($(COV),1) 91 | cd $(TMP_DIR)/ && ./configure --with-cc-opt="--coverage -g3 -gstabs" --with-ld-opt="-lgcov" $(NGINX_OPTIONS) --add-dynamic-module=$(MOD_PATH) --error-log-path=/tmp/naxsi_ut/error.log --conf-path=/tmp/naxsi_ut/nginx.conf 92 | endif 93 | 94 | ifeq ($(STOCK),1) 95 | cd $(TMP_DIR)/ && ./configure --with-cc-opt="-g3 -ggdb" $(NGINX_OPTIONS) --add-dynamic-module=$(MOD_PATH) --error-log-path=/tmp/naxsi_ut/error.log --conf-path=/tmp/naxsi_ut/nginx.conf 96 | endif 97 | 98 | 99 | build: 100 | AFL_PATH=$(AFL_PATH) make -C $(TMP_DIR) 101 | if [ -d "/tmp/naxsi_ut" ] && [ -f $(TMP_DIR)/objs/ngx_http_naxsi_module.so ] ; then cp $(TMP_DIR)/objs/ngx_http_naxsi_module.so /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so ; fi 102 | 103 | install: 104 | make -C $(TMP_DIR) install 105 | 106 | deploy: 107 | ifeq ($(FUZZ),1) 108 | @cp ../t/confs/nginx_fuzz.conf.example /tmp/naxsi_ut/nginx.conf 109 | else 110 | @cp ../t/confs/nginx.conf.example /tmp/naxsi_ut/nginx.conf 111 | endif 112 | @cp ../naxsi_config/naxsi_core.rules /tmp/naxsi_ut/naxsi_core.rules 113 | @openssl req -batch -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/nginx.key -out /tmp/nginx.crt 114 | 115 | 116 | # RUN UNIT TESTS 117 | test: 118 | ifeq ($(COV),1) 119 | lcov --directory $(TMP_DIR) --zerocounters 120 | endif 121 | if [ ! $(TEST) ] ; then TEST="*.t" ; fi 122 | export PATH="$(TMP_DIR)/objs/:"$(PATH) ; \ 123 | export PERL5LIB="~/perl5/lib/perl5/" ;\ 124 | cd .. ; prove -r "t/$(TEST)" 125 | ifeq ($(COV),1) 126 | lcov --directory $(TMP_DIR)/objs/addon/naxsi_src/ --capture --output-file naxsi.info --base-directory $(TMP_DIR) 127 | genhtml -s -o /tmp/naxsicov.html naxsi.info 128 | endif 129 | 130 | #Build for coverity and submit build ! 131 | #Remember to enforce gcc-6 when doing so, coverity doesn't support gcc-7 or gcc-8 132 | coverity: nginx_download 133 | @CAK=$(shell cat ../../coverity.key | cut -d ':' -f2) ; \ 134 | CAN=$(shell cat ../../coverity.key | cut -d ':' -f1) ; \ 135 | echo "Coverity token/login : $$CAK and $$CAN"; \ 136 | wget -nc https://scan.coverity.com/download/cxx/linux64 --post-data "token=$$CAK&project=nbs-system%2Fnaxsi" -O /tmp/coverity.tgz ; \ 137 | if ! [ -d /tmp/cov ] ; then \ 138 | mkdir -p /tmp/cov && \ 139 | cd /tmp/cov && \ 140 | cat ../coverity.tgz | tar --strip-components=2 -xvzf - && \ 141 | /tmp/cov/bin/cov-configure --comptype gcc --compiler gcc-6 --template ; \ 142 | fi ; \ 143 | cd $(TMP_DIR) ; \ 144 | ./configure $(NGINX_OPTIONS) && \ 145 | /tmp/cov/bin/cov-build --dir cov-int make -j4 && \ 146 | tar cvzf coverity-res-naxsi.tgz cov-int/ ; \ 147 | curl --form token="$$CAK" \ 148 | --form email="$$CAN" \ 149 | --form file=@$(TMP_DIR)/coverity-res-naxsi.tgz \ 150 | --form version="$(CORE_VERS)" \ 151 | --form description="Automatically submitted" \ 152 | https://scan.coverity.com/builds?project=nbs-system%2Fnaxsi 153 | -------------------------------------------------------------------------------- /naxsi_src/config: -------------------------------------------------------------------------------- 1 | ngx_addon_name=ngx_http_naxsi_module 2 | 3 | if test -n "$ngx_module_link"; then 4 | ngx_module_type=HTTP 5 | ngx_module_name=ngx_http_naxsi_module 6 | ngx_module_srcs="$ngx_addon_dir/naxsi_runtime.c $ngx_addon_dir/naxsi_config.c $ngx_addon_dir/naxsi_utils.c $ngx_addon_dir/naxsi_skeleton.c $ngx_addon_dir/naxsi_json.c $ngx_addon_dir/naxsi_raw.c $ngx_addon_dir/naxsi_net.c $ngx_addon_dir/ext/libinjection/libinjection_sqli.c $ngx_addon_dir/ext/libinjection/libinjection_xss.c $ngx_addon_dir/ext/libinjection/libinjection_html5.c" 7 | . auto/module 8 | else 9 | HTTP_MODULES="$HTTP_MODULES ngx_http_naxsi_module" 10 | NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/naxsi_runtime.c $ngx_addon_dir/naxsi_config.c $ngx_addon_dir/naxsi_utils.c $ngx_addon_dir/naxsi_skeleton.c $ngx_addon_dir/naxsi_json.c $ngx_addon_dir/naxsi_raw.c $ngx_addon_dir/naxsi_net.c $ngx_addon_dir/ext/libinjection/libinjection_sqli.c $ngx_addon_dir/ext/libinjection/libinjection_xss.c $ngx_addon_dir/ext/libinjection/libinjection_html5.c" 11 | NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_addon_dir/naxsi.h $ngx_addon_dir/naxsi_config.h $ngx_addon_dir/naxsi_net.h" 12 | fi 13 | -------------------------------------------------------------------------------- /naxsi_src/ext/libinjection/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2016, Nick Galbreath 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | 2. Redistributions in binary form must reproduce the above copyright 12 | notice, this list of conditions and the following disclaimer in the 13 | documentation and/or other materials provided with the distribution. 14 | 15 | 3. Neither the name of the copyright holder nor the names of its 16 | contributors may be used to endorse or promote products derived from 17 | this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | https://github.com/client9/libinjection 32 | http://opensource.org/licenses/BSD-3-Clause 33 | -------------------------------------------------------------------------------- /naxsi_src/ext/libinjection/example1.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "libinjection.h" 4 | 5 | int main(int argc, const char* argv[]) 6 | { 7 | char fingerprint[8]; 8 | const char* input; 9 | size_t slen; 10 | int issqli; 11 | 12 | if (argc < 2) { 13 | fprintf(stderr, "Usage: %s inputstring\n", argv[0]); 14 | return -1; 15 | } 16 | 17 | input = argv[1]; 18 | slen = strlen(input); 19 | 20 | 21 | issqli = libinjection_sqli(input, slen, fingerprint); 22 | if (issqli) { 23 | printf("sqli with fingerprint of '%s'\n", fingerprint); 24 | } else { 25 | printf("not sqli\n"); 26 | } 27 | 28 | 29 | return issqli; 30 | } 31 | -------------------------------------------------------------------------------- /naxsi_src/ext/libinjection/fptool.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012, 2013 Nick Galbreath 3 | * nickg@client9.com 4 | * BSD License -- see COPYING.txt for details 5 | * 6 | * This is for testing against files in ../data/ *.txt 7 | * Reads from stdin or a list of files, and emits if a line 8 | * is a SQLi attack or not, and does basic statistics 9 | * 10 | */ 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | #include "libinjection.h" 17 | #include "libinjection_sqli.h" 18 | 19 | int main(int argc, const char* argv[]) 20 | { 21 | size_t slen; 22 | int ok; 23 | int single = 0; 24 | int offset = 1; 25 | 26 | sfilter sf; 27 | if (argc < 2) { 28 | fprintf(stderr, "need more args\n"); 29 | return 1; 30 | } 31 | while (1) { 32 | if (strcmp(argv[offset], "-0") == 0) { 33 | single = 1; 34 | offset += 1; 35 | } else { 36 | break; 37 | } 38 | } 39 | 40 | slen = strlen(argv[offset]); 41 | 42 | if (slen == 0) { 43 | return 1; 44 | } 45 | 46 | /* 47 | * "plain" context.. test string "as-is" 48 | */ 49 | libinjection_sqli_init(&sf, argv[offset], slen, 0); 50 | 51 | if (single) { 52 | libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_NONE | FLAG_SQL_ANSI); 53 | libinjection_sqli_check_fingerprint(&sf); 54 | fprintf(stdout, "%s\n", sf.fingerprint); 55 | return 0; 56 | } 57 | 58 | libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_NONE | FLAG_SQL_ANSI); 59 | ok = libinjection_sqli_check_fingerprint(&sf); 60 | fprintf(stdout, "plain-asni\t%s\t%s\n", sf.fingerprint, ok ? "true": "false"); 61 | 62 | libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_NONE | FLAG_SQL_MYSQL); 63 | ok = libinjection_sqli_check_fingerprint(&sf); 64 | fprintf(stdout, "plain-mysql\t%s\t%s\n", sf.fingerprint, ok ? "true": "false"); 65 | 66 | libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_SINGLE | FLAG_SQL_ANSI); 67 | ok = libinjection_sqli_check_fingerprint(&sf); 68 | fprintf(stdout, "single-ansi\t%s\t%s\n", sf.fingerprint, ok ? "true": "false"); 69 | 70 | libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_SINGLE | FLAG_SQL_MYSQL); 71 | ok = libinjection_sqli_check_fingerprint(&sf); 72 | fprintf(stdout, "single-mysql\t%s\t%s\n", sf.fingerprint, ok ? "true": "false"); 73 | 74 | libinjection_sqli_fingerprint(&sf, FLAG_QUOTE_DOUBLE | FLAG_SQL_MYSQL); 75 | ok = libinjection_sqli_check_fingerprint(&sf); 76 | fprintf(stdout, "double-mysql\t%s\t%s\n", sf.fingerprint, ok ? "true": "false"); 77 | 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /naxsi_src/ext/libinjection/html5_cli.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012, 2013, 2014 Nick Galbreath 3 | * nickg@client9.com 4 | * BSD License -- see COPYING.txt for details 5 | * 6 | * This is for testing against files in ../data/ *.txt 7 | * Reads from stdin or a list of files, and emits if a line 8 | * is a SQLi attack or not, and does basic statistics 9 | * 10 | */ 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "libinjection_html5.h" 17 | #include "libinjection_xss.h" 18 | #include "libinjection.h" 19 | 20 | int urlcharmap(char ch); 21 | size_t modp_url_decode(char* dest, const char* s, size_t len); 22 | const char* h5_type_to_string(enum html5_type x); 23 | void print_html5_token(h5_state_t* hs); 24 | 25 | int urlcharmap(char ch) { 26 | switch (ch) { 27 | case '0': return 0; 28 | case '1': return 1; 29 | case '2': return 2; 30 | case '3': return 3; 31 | case '4': return 4; 32 | case '5': return 5; 33 | case '6': return 6; 34 | case '7': return 7; 35 | case '8': return 8; 36 | case '9': return 9; 37 | case 'a': case 'A': return 10; 38 | case 'b': case 'B': return 11; 39 | case 'c': case 'C': return 12; 40 | case 'd': case 'D': return 13; 41 | case 'e': case 'E': return 14; 42 | case 'f': case 'F': return 15; 43 | default: 44 | return 256; 45 | } 46 | } 47 | 48 | size_t modp_url_decode(char* dest, const char* s, size_t len) 49 | { 50 | const char* deststart = dest; 51 | 52 | size_t i = 0; 53 | int d = 0; 54 | while (i < len) { 55 | switch (s[i]) { 56 | case '+': 57 | *dest++ = ' '; 58 | i += 1; 59 | break; 60 | case '%': 61 | if (i+2 < len) { 62 | d = (urlcharmap(s[i+1]) << 4) | urlcharmap(s[i+2]); 63 | if ( d < 256) { 64 | *dest = (char) d; 65 | dest++; 66 | i += 3; /* loop will increment one time */ 67 | } else { 68 | *dest++ = '%'; 69 | i += 1; 70 | } 71 | } else { 72 | *dest++ = '%'; 73 | i += 1; 74 | } 75 | break; 76 | default: 77 | *dest++ = s[i]; 78 | i += 1; 79 | } 80 | } 81 | *dest = '\0'; 82 | return (size_t)(dest - deststart); /* compute "strlen" of dest */ 83 | } 84 | 85 | const char* h5_type_to_string(enum html5_type x) 86 | { 87 | switch (x) { 88 | case DATA_TEXT: return "DATA_TEXT"; 89 | case TAG_NAME_OPEN: return "TAG_NAME_OPEN"; 90 | case TAG_NAME_CLOSE: return "TAG_NAME_CLOSE"; 91 | case TAG_NAME_SELFCLOSE: return "TAG_NAME_SELFCLOSE"; 92 | case TAG_DATA: return "TAG_DATA"; 93 | case TAG_CLOSE: return "TAG_CLOSE"; 94 | case ATTR_NAME: return "ATTR_NAME"; 95 | case ATTR_VALUE: return "ATTR_VALUE"; 96 | case TAG_COMMENT: return "TAG_COMMENT"; 97 | case DOCTYPE: return "DOCTYPE"; 98 | default: 99 | assert(0); 100 | } 101 | } 102 | 103 | void print_html5_token(h5_state_t* hs) 104 | { 105 | char* tmp = (char*) malloc(hs->token_len + 1); 106 | memcpy(tmp, hs->token_start, hs->token_len); 107 | /* TODO.. encode to be printable */ 108 | tmp[hs->token_len] = '\0'; 109 | 110 | printf("%s,%d,%s\n", 111 | h5_type_to_string(hs->token_type), 112 | (int) hs->token_len, 113 | tmp); 114 | 115 | free(tmp); 116 | } 117 | 118 | int main(int argc, const char* argv[]) 119 | { 120 | size_t slen; 121 | h5_state_t hs; 122 | char* copy; 123 | int offset = 1; 124 | int flag = 0; 125 | int urldecode = 0; 126 | 127 | if (argc < 2) { 128 | fprintf(stderr, "need more args\n"); 129 | return 1; 130 | } 131 | 132 | while (offset < argc) { 133 | if (strcmp(argv[offset], "-u") == 0) { 134 | offset += 1; 135 | urldecode = 1; 136 | 137 | } else if (strcmp(argv[offset], "-f") == 0) { 138 | offset += 1; 139 | flag = atoi(argv[offset]); 140 | offset += 1; 141 | } else { 142 | break; 143 | } 144 | } 145 | 146 | /* ATTENTION: argv is a C-string, null terminated. We copy this 147 | * to it's own location, WITHOUT null byte. This way, valgrind 148 | * can see if we run past the buffer. 149 | */ 150 | 151 | slen = strlen(argv[offset]); 152 | copy = (char* ) malloc(slen); 153 | memcpy(copy, argv[offset], slen); 154 | if (urldecode) { 155 | slen = modp_url_decode(copy, copy, slen); 156 | } 157 | 158 | libinjection_h5_init(&hs, copy, slen, (enum html5_flags) flag); 159 | while (libinjection_h5_next(&hs)) { 160 | print_html5_token(&hs); 161 | } 162 | 163 | if (libinjection_is_xss(copy, slen, flag)) { 164 | printf("is injection!\n"); 165 | } 166 | free(copy); 167 | return 0; 168 | } 169 | -------------------------------------------------------------------------------- /naxsi_src/ext/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* input, 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 len); 62 | 63 | LIBINJECTION_END_DECLS 64 | 65 | #endif /* LIBINJECTION_H */ 66 | -------------------------------------------------------------------------------- /naxsi_src/ext/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 | -------------------------------------------------------------------------------- /naxsi_src/ext/libinjection/libinjection_sqli.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_SQLI_H 11 | #define LIBINJECTION_SQLI_H 12 | 13 | #ifdef __cplusplus 14 | extern "C" { 15 | #endif 16 | 17 | /* 18 | * Pull in size_t 19 | */ 20 | #include 21 | 22 | enum sqli_flags { 23 | FLAG_NONE = 0 24 | , FLAG_QUOTE_NONE = 1 /* 1 << 0 */ 25 | , FLAG_QUOTE_SINGLE = 2 /* 1 << 1 */ 26 | , FLAG_QUOTE_DOUBLE = 4 /* 1 << 2 */ 27 | 28 | , FLAG_SQL_ANSI = 8 /* 1 << 3 */ 29 | , FLAG_SQL_MYSQL = 16 /* 1 << 4 */ 30 | }; 31 | 32 | enum lookup_type { 33 | LOOKUP_WORD = 1 34 | , LOOKUP_TYPE = 2 35 | , LOOKUP_OPERATOR = 3 36 | , LOOKUP_FINGERPRINT = 4 37 | }; 38 | 39 | struct libinjection_sqli_token { 40 | #ifdef SWIG 41 | %immutable; 42 | #endif 43 | /* 44 | * position and length of token 45 | * in original string 46 | */ 47 | size_t pos; 48 | size_t len; 49 | 50 | /* count: 51 | * in type 'v', used for number of opening '@' 52 | * but maybe used in other contexts 53 | */ 54 | int count; 55 | 56 | char type; 57 | char str_open; 58 | char str_close; 59 | char val[32]; 60 | }; 61 | 62 | typedef struct libinjection_sqli_token stoken_t; 63 | 64 | /** 65 | * Pointer to function, takes c-string input, 66 | * returns '\0' for no match, else a char 67 | */ 68 | struct libinjection_sqli_state; 69 | typedef char (*ptr_lookup_fn)(struct libinjection_sqli_state*, int lookuptype, const char* word, size_t len); 70 | 71 | struct libinjection_sqli_state { 72 | #ifdef SWIG 73 | %immutable; 74 | #endif 75 | 76 | /* 77 | * input, does not need to be null terminated. 78 | * it is also not modified. 79 | */ 80 | const char *s; 81 | 82 | /* 83 | * input length 84 | */ 85 | size_t slen; 86 | 87 | /* 88 | * How to lookup a word or fingerprint 89 | */ 90 | ptr_lookup_fn lookup; 91 | void* userdata; 92 | 93 | /* 94 | * 95 | */ 96 | int flags; 97 | 98 | /* 99 | * pos is the index in the string during tokenization 100 | */ 101 | size_t pos; 102 | 103 | #ifndef SWIG 104 | /* for SWIG.. don't use this.. use functional API instead */ 105 | 106 | /* MAX TOKENS + 1 since we use one extra token 107 | * to determine the type of the previous token 108 | */ 109 | struct libinjection_sqli_token tokenvec[8]; 110 | #endif 111 | 112 | /* 113 | * Pointer to token position in tokenvec, above 114 | */ 115 | struct libinjection_sqli_token *current; 116 | 117 | /* 118 | * fingerprint pattern c-string 119 | * +1 for ending null 120 | * Minimum of 8 bytes to add gcc's -fstack-protector to work 121 | */ 122 | char fingerprint[8]; 123 | 124 | /* 125 | * Line number of code that said decided if the input was SQLi or 126 | * not. Most of the time it's line that said "it's not a matching 127 | * fingerprint" but there is other logic that sometimes approves 128 | * an input. This is only useful for debugging. 129 | * 130 | */ 131 | int reason; 132 | 133 | /* Number of ddw (dash-dash-white) comments 134 | * These comments are in the form of 135 | * '--[whitespace]' or '--[EOF]' 136 | * 137 | * All databases treat this as a comment. 138 | */ 139 | int stats_comment_ddw; 140 | 141 | /* Number of ddx (dash-dash-[notwhite]) comments 142 | * 143 | * ANSI SQL treats these are comments, MySQL treats this as 144 | * two unary operators '-' '-' 145 | * 146 | * If you are parsing result returns FALSE and 147 | * stats_comment_dd > 0, you should reparse with 148 | * COMMENT_MYSQL 149 | * 150 | */ 151 | int stats_comment_ddx; 152 | 153 | /* 154 | * c-style comments found /x .. x/ 155 | */ 156 | int stats_comment_c; 157 | 158 | /* '#' operators or MySQL EOL comments found 159 | * 160 | */ 161 | int stats_comment_hash; 162 | 163 | /* 164 | * number of tokens folded away 165 | */ 166 | int stats_folds; 167 | 168 | /* 169 | * total tokens processed 170 | */ 171 | int stats_tokens; 172 | 173 | }; 174 | 175 | typedef struct libinjection_sqli_state sfilter; 176 | 177 | struct libinjection_sqli_token* libinjection_sqli_get_token( 178 | struct libinjection_sqli_state* sql_state, int i); 179 | 180 | /* 181 | * Version info. 182 | * 183 | * This is moved into a function to allow SWIG and other auto-generated 184 | * binding to not be modified during minor release changes. We change 185 | * change the version number in the c source file, and not regenerated 186 | * the binding 187 | * 188 | * See python's normalized version 189 | * http://www.python.org/dev/peps/pep-0386/#normalizedversion 190 | */ 191 | const char* libinjection_version(void); 192 | 193 | /** 194 | * 195 | */ 196 | void libinjection_sqli_init(struct libinjection_sqli_state *sf, 197 | const char* s, size_t len, 198 | int flags); 199 | 200 | /** 201 | * Main API: tests for SQLi in three possible contexts, no quotes, 202 | * single quote and double quote 203 | * 204 | * \param sql_state core data structure 205 | * 206 | * \return 1 (true) if SQLi, 0 (false) if benign 207 | */ 208 | int libinjection_is_sqli(struct libinjection_sqli_state* sql_state); 209 | 210 | /* FOR HACKERS ONLY 211 | * provides deep hooks into the decision making process 212 | */ 213 | void libinjection_sqli_callback(struct libinjection_sqli_state *sf, 214 | ptr_lookup_fn fn, 215 | void* userdata); 216 | 217 | 218 | /* 219 | * Resets state, but keeps initial string and callbacks 220 | */ 221 | void libinjection_sqli_reset(struct libinjection_sqli_state *sf, 222 | int flags); 223 | 224 | /** 225 | * 226 | */ 227 | 228 | /** 229 | * This detects SQLi in a single context, mostly useful for custom 230 | * logic and debugging. 231 | * 232 | * \param sql_state Main data structure 233 | * \param flags flags to adjust parsing 234 | * 235 | * \returns a pointer to sfilter.fingerprint as convenience 236 | * do not free! 237 | * 238 | */ 239 | const char* libinjection_sqli_fingerprint(struct libinjection_sqli_state *sql_state, 240 | int flags); 241 | 242 | /** 243 | * The default "word" to token-type or fingerprint function. This 244 | * uses a ASCII case-insensitive binary tree. 245 | */ 246 | char libinjection_sqli_lookup_word(struct libinjection_sqli_state *sql_state, 247 | int lookup_type, 248 | const char* str, 249 | size_t len); 250 | 251 | /* Streaming tokenization interface. 252 | * 253 | * sql_state->current is updated with the current token. 254 | * 255 | * \returns 1, has a token, keep going, or 0 no tokens 256 | * 257 | */ 258 | int libinjection_sqli_tokenize(struct libinjection_sqli_state *sf); 259 | 260 | /** 261 | * parses and folds input, up to 5 tokens 262 | * 263 | */ 264 | int libinjection_sqli_fold(struct libinjection_sqli_state *sf); 265 | 266 | /** The built-in default function to match fingerprints 267 | * and do false negative/positive analysis. This calls the following 268 | * two functions. With this, you over-ride one part or the other. 269 | * 270 | * return libinjection_sqli_blacklist(sql_state) && 271 | * libinjection_sqli_not_whitelist(sql_state); 272 | * 273 | * \param sql_state should be filled out after libinjection_sqli_fingerprint is called 274 | */ 275 | int libinjection_sqli_check_fingerprint(struct libinjection_sqli_state * sql_state); 276 | 277 | /* Given a pattern determine if it's a SQLi pattern. 278 | * 279 | * \return TRUE if sqli, false otherwise 280 | */ 281 | int libinjection_sqli_blacklist(struct libinjection_sqli_state* sql_state); 282 | 283 | /* Given a positive match for a pattern (i.e. pattern is SQLi), this function 284 | * does additional analysis to reduce false positives. 285 | * 286 | * \return TRUE if SQLi, false otherwise 287 | */ 288 | int libinjection_sqli_not_whitelist(struct libinjection_sqli_state * sql_state); 289 | 290 | #ifdef __cplusplus 291 | } 292 | #endif 293 | 294 | #endif /* LIBINJECTION_SQLI_H */ 295 | -------------------------------------------------------------------------------- /naxsi_src/ext/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 | -------------------------------------------------------------------------------- /naxsi_src/ext/libinjection/reader.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "libinjection.h" 7 | #include "libinjection_sqli.h" 8 | #include "libinjection_xss.h" 9 | 10 | #ifndef TRUE 11 | #define TRUE 1 12 | #endif 13 | #ifndef FALSE 14 | #define FALSE 0 15 | #endif 16 | 17 | static int g_test_ok = 0; 18 | static int g_test_fail = 0; 19 | 20 | typedef enum { 21 | MODE_SQLI, 22 | MODE_XSS 23 | } detect_mode_t; 24 | 25 | static void usage(const char* argv[]); 26 | size_t modp_rtrim(char* str, size_t len); 27 | void modp_toprint(char* str, size_t len); 28 | void test_positive(FILE * fd, const char *fname, detect_mode_t mode, 29 | int flag_invert, int flag_true, int flag_quiet); 30 | 31 | int urlcharmap(char ch); 32 | size_t modp_url_decode(char* dest, const char* s, size_t len); 33 | 34 | int urlcharmap(char ch) { 35 | switch (ch) { 36 | case '0': return 0; 37 | case '1': return 1; 38 | case '2': return 2; 39 | case '3': return 3; 40 | case '4': return 4; 41 | case '5': return 5; 42 | case '6': return 6; 43 | case '7': return 7; 44 | case '8': return 8; 45 | case '9': return 9; 46 | case 'a': case 'A': return 10; 47 | case 'b': case 'B': return 11; 48 | case 'c': case 'C': return 12; 49 | case 'd': case 'D': return 13; 50 | case 'e': case 'E': return 14; 51 | case 'f': case 'F': return 15; 52 | default: 53 | return 256; 54 | } 55 | } 56 | 57 | size_t modp_url_decode(char* dest, const char* s, size_t len) 58 | { 59 | const char* deststart = dest; 60 | 61 | size_t i = 0; 62 | int d = 0; 63 | while (i < len) { 64 | switch (s[i]) { 65 | case '+': 66 | *dest++ = ' '; 67 | i += 1; 68 | break; 69 | case '%': 70 | if (i+2 < len) { 71 | d = (urlcharmap(s[i+1]) << 4) | urlcharmap(s[i+2]); 72 | if ( d < 256) { 73 | *dest = (char) d; 74 | dest++; 75 | i += 3; /* loop will increment one time */ 76 | } else { 77 | *dest++ = '%'; 78 | i += 1; 79 | } 80 | } else { 81 | *dest++ = '%'; 82 | i += 1; 83 | } 84 | break; 85 | default: 86 | *dest++ = s[i]; 87 | i += 1; 88 | } 89 | } 90 | *dest = '\0'; 91 | return (size_t)(dest - deststart); /* compute "strlen" of dest */ 92 | } 93 | 94 | void modp_toprint(char* str, size_t len) 95 | { 96 | size_t i; 97 | for (i = 0; i < len; ++i) { 98 | if (str[i] < 32 || str[i] > 126) { 99 | str[i] = '?'; 100 | } 101 | } 102 | } 103 | size_t modp_rtrim(char* str, size_t len) 104 | { 105 | while (len) { 106 | char c = str[len -1]; 107 | if (c == ' ' || c == '\n' || c == '\t' || c == '\r') { 108 | str[len -1] = '\0'; 109 | len -= 1; 110 | } else { 111 | break; 112 | } 113 | } 114 | return len; 115 | } 116 | 117 | void test_positive(FILE * fd, const char *fname, detect_mode_t mode, 118 | int flag_invert, int flag_true, int flag_quiet) 119 | { 120 | char linebuf[8192]; 121 | int issqli = 0; 122 | int linenum = 0; 123 | size_t len; 124 | sfilter sf; 125 | 126 | while (fgets(linebuf, sizeof(linebuf), fd)) { 127 | linenum += 1; 128 | len = modp_rtrim(linebuf, strlen(linebuf)); 129 | if (len == 0) { 130 | continue; 131 | } 132 | if (linebuf[0] == '#') { 133 | continue; 134 | } 135 | 136 | len = modp_url_decode(linebuf, linebuf, len); 137 | switch (mode) { 138 | case MODE_SQLI: { 139 | libinjection_sqli_init(&sf, linebuf, len, 0); 140 | issqli = libinjection_is_sqli(&sf); 141 | break; 142 | } 143 | case MODE_XSS: { 144 | issqli = libinjection_xss(linebuf, len); 145 | break; 146 | } 147 | default: 148 | assert(0); 149 | } 150 | 151 | if (issqli) { 152 | g_test_ok += 1; 153 | } else { 154 | g_test_fail += 1; 155 | } 156 | 157 | if (!flag_quiet) { 158 | if ((issqli && flag_true && ! flag_invert) || 159 | (!issqli && flag_true && flag_invert) || 160 | !flag_true) { 161 | 162 | modp_toprint(linebuf, len); 163 | 164 | switch (mode) { 165 | case MODE_SQLI: { 166 | /* 167 | * if we didn't find a SQLi and fingerprint from 168 | * sqlstats is is 'sns' or 'snsns' then redo using 169 | * plain context 170 | */ 171 | if (!issqli && (strcmp(sf.fingerprint, "sns") == 0 || 172 | strcmp(sf.fingerprint, "snsns") == 0)) { 173 | libinjection_sqli_fingerprint(&sf, 0); 174 | } 175 | 176 | fprintf(stdout, "%s\t%d\t%s\t%s\t%s\n", 177 | fname, linenum, 178 | (issqli ? "True" : "False"), sf.fingerprint, linebuf); 179 | break; 180 | } 181 | case MODE_XSS: { 182 | fprintf(stdout, "%s\t%d\t%s\t%s\n", 183 | fname, linenum, 184 | (issqli ? "True" : "False"), linebuf); 185 | break; 186 | } 187 | default: 188 | assert(0); 189 | } 190 | } 191 | } 192 | } 193 | } 194 | 195 | static void usage(const char* argv[]) 196 | { 197 | fprintf(stdout, "usage: %s [flags] [files...]\n", argv[0]); 198 | fprintf(stdout, "%s\n", ""); 199 | fprintf(stdout, "%s\n", "-q --quiet : quiet mode"); 200 | fprintf(stdout, "%s\n", "-m --max-fails : number of failed cases need to fail entire test"); 201 | fprintf(stdout, "%s\n", "-s INTEGER : repeat each test N time " 202 | "(for performance testing)"); 203 | fprintf(stdout, "%s\n", "-t : only print positive matches"); 204 | fprintf(stdout, "%s\n", "-x --mode-xss : test input for XSS"); 205 | fprintf(stdout, "%s\n", "-i --invert : invert test logic " 206 | "(input is tested for being safe)"); 207 | 208 | fprintf(stdout, "%s\n", ""); 209 | fprintf(stdout, "%s\n", "-? -h -help --help : this page"); 210 | fprintf(stdout, "%s\n", ""); 211 | } 212 | 213 | int main(int argc, const char *argv[]) 214 | { 215 | /* 216 | * invert output, by 217 | */ 218 | int flag_invert = FALSE; 219 | 220 | /* 221 | * don't print anything.. useful for 222 | * performance monitors, gprof. 223 | */ 224 | int flag_quiet = FALSE; 225 | 226 | /* 227 | * only print positive results 228 | * with invert, only print negative results 229 | */ 230 | int flag_true = FALSE; 231 | detect_mode_t mode = MODE_SQLI; 232 | 233 | int flag_slow = 1; 234 | int count = 0; 235 | int max = -1; 236 | 237 | int i, j; 238 | int offset = 1; 239 | 240 | while (offset < argc) { 241 | if (strcmp(argv[offset], "-?") == 0 || 242 | strcmp(argv[offset], "-h") == 0 || 243 | strcmp(argv[offset], "-help") == 0 || 244 | strcmp(argv[offset], "--help") == 0) { 245 | usage(argv); 246 | exit(0); 247 | } 248 | 249 | if (strcmp(argv[offset], "-i") == 0) { 250 | offset += 1; 251 | flag_invert = TRUE; 252 | } else if (strcmp(argv[offset], "-q") == 0 || 253 | strcmp(argv[offset], "--quiet") == 0) { 254 | offset += 1; 255 | flag_quiet = TRUE; 256 | } else if (strcmp(argv[offset], "-t") == 0) { 257 | offset += 1; 258 | flag_true = TRUE; 259 | } else if (strcmp(argv[offset], "-s") == 0) { 260 | offset += 1; 261 | flag_slow = 100; 262 | } else if (strcmp(argv[offset], "-m") == 0 || 263 | strcmp(argv[offset], "--max-fails") == 0) { 264 | offset += 1; 265 | max = atoi(argv[offset]); 266 | offset += 1; 267 | } else if (strcmp(argv[offset], "-x") == 0 || 268 | strcmp(argv[offset], "--mode-xss") == 0) { 269 | mode = MODE_XSS; 270 | offset += 1; 271 | } else { 272 | break; 273 | } 274 | } 275 | 276 | if (offset == argc) { 277 | test_positive(stdin, "stdin", mode, flag_invert, flag_true, flag_quiet); 278 | } else { 279 | for (j = 0; j < flag_slow; ++j) { 280 | for (i = offset; i < argc; ++i) { 281 | FILE* fd = fopen(argv[i], "r"); 282 | if (fd) { 283 | test_positive(fd, argv[i], mode, flag_invert, flag_true, flag_quiet); 284 | fclose(fd); 285 | } 286 | } 287 | } 288 | } 289 | 290 | if (!flag_quiet) { 291 | fprintf(stdout, "%s", "\n"); 292 | fprintf(stdout, "SQLI : %d\n", g_test_ok); 293 | fprintf(stdout, "SAFE : %d\n", g_test_fail); 294 | fprintf(stdout, "TOTAL : %d\n", g_test_ok + g_test_fail); 295 | } 296 | 297 | if (max == -1) { 298 | return 0; 299 | } 300 | 301 | count = g_test_ok; 302 | if (flag_invert) { 303 | count = g_test_fail; 304 | } 305 | 306 | if (count > max) { 307 | printf("\nThreshold is %d, got %d, failing.\n", max, count); 308 | return 1; 309 | } else { 310 | printf("\nThreshold is %d, got %d, passing.\n", max, count); 311 | return 0; 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /naxsi_src/ext/libinjection/sqli_cli.c: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2012, 2013 Nick Galbreath 3 | * nickg@client9.com 4 | * BSD License -- see COPYING.txt for details 5 | * 6 | * This is for testing against files in ../data/ *.txt 7 | * Reads from stdin or a list of files, and emits if a line 8 | * is a SQLi attack or not, and does basic statistics 9 | * 10 | */ 11 | #include 12 | #include 13 | #include 14 | 15 | #include "libinjection.h" 16 | #include "libinjection_sqli.h" 17 | 18 | void print_string(stoken_t* t); 19 | void print_var(stoken_t* t); 20 | void print_token(stoken_t *t); 21 | 22 | void print_string(stoken_t* t) 23 | { 24 | /* print opening quote */ 25 | if (t->str_open != '\0') { 26 | printf("%c", t->str_open); 27 | } 28 | 29 | /* print content */ 30 | printf("%s", t->val); 31 | 32 | /* print closing quote */ 33 | if (t->str_close != '\0') { 34 | printf("%c", t->str_close); 35 | } 36 | } 37 | 38 | void print_var(stoken_t* t) 39 | { 40 | if (t->count >= 1) { 41 | printf("%c", '@'); 42 | } 43 | if (t->count == 2) { 44 | printf("%c", '@'); 45 | } 46 | print_string(t); 47 | } 48 | 49 | void print_token(stoken_t *t) { 50 | printf("%c ", t->type); 51 | switch (t->type) { 52 | case 's': 53 | print_string(t); 54 | break; 55 | case 'v': 56 | print_var(t); 57 | break; 58 | default: 59 | printf("%s", t->val); 60 | } 61 | printf("%s", "\n"); 62 | } 63 | 64 | void usage() { 65 | printf("\n"); 66 | printf("libinjection sqli tester\n"); 67 | printf("\n"); 68 | printf(" -ca parse as ANSI SQL\n"); 69 | printf(" -cm parse as MySQL SQL\n"); 70 | printf(" -q0 parse as is\n"); 71 | printf(" -q1 parse in single-quote mode\n"); 72 | printf(" -q2 parse in doiuble-quote mode\n"); 73 | printf("\n"); 74 | printf(" -f --fold fold results\n"); 75 | printf("\n"); 76 | printf(" -d --detect detect SQLI. empty reply = not detected\n"); 77 | printf("\n"); 78 | } 79 | 80 | int main(int argc, const char* argv[]) 81 | { 82 | size_t slen; 83 | char* copy; 84 | 85 | int flags = 0; 86 | int fold = 0; 87 | int detect = 0; 88 | 89 | int i; 90 | int count; 91 | int offset = 1; 92 | int issqli; 93 | 94 | sfilter sf; 95 | 96 | if (argc < 2) { 97 | usage(); 98 | return 1; 99 | } 100 | while (1) { 101 | if (strcmp(argv[offset], "-h") == 0 || strcmp(argv[offset], "-?") == 0 || strcmp(argv[offset], "--help") == 0) { 102 | usage(); 103 | return 1; 104 | } 105 | if (strcmp(argv[offset], "-m") == 0) { 106 | flags |= FLAG_SQL_MYSQL; 107 | offset += 1; 108 | } 109 | else if (strcmp(argv[offset], "-f") == 0 || strcmp(argv[offset], "--fold") == 0) { 110 | fold = 1; 111 | offset += 1; 112 | } else if (strcmp(argv[offset], "-d") == 0 || strcmp(argv[offset], "--detect") == 0) { 113 | detect = 1; 114 | offset += 1; 115 | } else if (strcmp(argv[offset], "-ca") == 0) { 116 | flags |= FLAG_SQL_ANSI; 117 | offset += 1; 118 | } else if (strcmp(argv[offset], "-cm") == 0) { 119 | flags |= FLAG_SQL_MYSQL; 120 | offset += 1; 121 | } else if (strcmp(argv[offset], "-q0") == 0) { 122 | flags |= FLAG_QUOTE_NONE; 123 | offset += 1; 124 | } else if (strcmp(argv[offset], "-q1") == 0) { 125 | flags |= FLAG_QUOTE_SINGLE; 126 | offset += 1; 127 | } else if (strcmp(argv[offset], "-q2") == 0) { 128 | flags |= FLAG_QUOTE_DOUBLE; 129 | offset += 1; 130 | } else { 131 | break; 132 | } 133 | } 134 | 135 | /* ATTENTION: argv is a C-string, null terminated. We copy this 136 | * to it's own location, WITHOUT null byte. This way, valgrind 137 | * can see if we run past the buffer. 138 | */ 139 | 140 | slen = strlen(argv[offset]); 141 | copy = (char* ) malloc(slen); 142 | memcpy(copy, argv[offset], slen); 143 | libinjection_sqli_init(&sf, copy, slen, flags); 144 | 145 | if (detect == 1) { 146 | issqli = libinjection_is_sqli(&sf); 147 | if (issqli) { 148 | printf("%s\n", sf.fingerprint); 149 | } 150 | } else if (fold == 1) { 151 | count = libinjection_sqli_fold(&sf); 152 | for (i = 0; i < count; ++i) { 153 | print_token(&(sf.tokenvec[i])); 154 | } 155 | } else { 156 | while (libinjection_sqli_tokenize(&sf)) { 157 | print_token(sf.current); 158 | } 159 | } 160 | 161 | free(copy); 162 | 163 | return 0; 164 | } 165 | -------------------------------------------------------------------------------- /naxsi_src/ext/libinjection/test_speed_sqli.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A not very good test for performance. This is mostly useful in 3 | * testing performance -regressions- 4 | * 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | #include "libinjection.h" 11 | #include "libinjection_sqli.h" 12 | int testIsSQL(void); 13 | 14 | int testIsSQL(void) 15 | { 16 | const char* const s[] = { 17 | "123 LIKE -1234.5678E+2;", 18 | "APPLE 19.123 'FOO' \"BAR\"", 19 | "/* BAR */ UNION ALL SELECT (2,3,4)", 20 | "1 || COS(+0X04) --FOOBAR", 21 | "dog apple @cat banana bar", 22 | "dog apple cat \"banana \'bar", 23 | "102 TABLE CLOTH", 24 | "(1001-'1') union select 1,2,3,4 from credit_cards", 25 | NULL 26 | }; 27 | const int imax = 1000000; 28 | int i, j; 29 | size_t slen; 30 | sfilter sf; 31 | clock_t t0,t1; 32 | double total; 33 | int tps; 34 | 35 | t0 = clock(); 36 | for (i = imax, j=0; i != 0; --i, ++j) { 37 | if (s[j] == NULL) { 38 | j = 0; 39 | } 40 | 41 | slen = strlen(s[j]); 42 | libinjection_sqli_init(&sf, s[j], slen, FLAG_QUOTE_NONE | FLAG_SQL_ANSI); 43 | libinjection_is_sqli(&sf); 44 | } 45 | 46 | t1 = clock(); 47 | total = (double) (t1 - t0) / (double) CLOCKS_PER_SEC; 48 | tps = (int)((double) imax / total); 49 | return tps; 50 | } 51 | 52 | int main() 53 | { 54 | const int mintps = 450000; 55 | int tps = testIsSQL(); 56 | 57 | printf("\nTPS : %d\n\n", tps); 58 | 59 | if (tps < mintps) { 60 | printf("FAIL: %d < %d\n", tps, mintps); 61 | /* FAIL */ 62 | return 1; 63 | } else { 64 | printf("OK: %d > %d\n", tps, mintps); 65 | /* OK */ 66 | return 0; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /naxsi_src/ext/libinjection/test_speed_xss.c: -------------------------------------------------------------------------------- 1 | /* 2 | * A not very good test for performance. This is mostly useful in 3 | * testing performance -regressions- 4 | * 5 | */ 6 | #include 7 | #include 8 | #include 9 | 10 | #include "libinjection.h" 11 | int testIsSQL(void); 12 | 13 | int testIsSQL(void) 14 | { 15 | const char* const s[] = { 16 | "", 17 | ">" 18 | "x >", 19 | "' >", 20 | "\">", 21 | "red;", 22 | "red;}", 23 | "red;\"/>", 24 | "');}", 25 | "onerror=alert(1)>", 26 | "x onerror=alert(1);>", 27 | "x' onerror=alert(1);>", 28 | "x\" onerror=alert(1);>", 29 | "", 30 | "", 31 | "", 32 | "", 33 | "", 34 | "", 35 | "123 LIKE -1234.5678E+2;", 36 | "APPLE 19.123 'FOO' \"BAR\"", 37 | "/* BAR */ UNION ALL SELECT (2,3,4)", 38 | "1 || COS(+0X04) --FOOBAR", 39 | "dog apple @cat banana bar", 40 | "dog apple cat \"banana \'bar", 41 | "102 TABLE CLOTH", 42 | "(1001-'1') union select 1,2,3,4 from credit_cards", 43 | NULL 44 | }; 45 | const int imax = 1000000; 46 | int i, j; 47 | size_t slen; 48 | clock_t t0,t1; 49 | double total; 50 | int tps; 51 | 52 | t0 = clock(); 53 | for (i = imax, j=0; i != 0; --i, ++j) { 54 | if (s[j] == NULL) { 55 | j = 0; 56 | } 57 | 58 | slen = strlen(s[j]); 59 | libinjection_xss(s[j], slen); 60 | } 61 | 62 | t1 = clock(); 63 | total = (double) (t1 - t0) / (double) CLOCKS_PER_SEC; 64 | tps = (int)((double) imax / total); 65 | return tps; 66 | } 67 | 68 | int main() 69 | { 70 | const int mintps = 500000; 71 | int tps = testIsSQL(); 72 | 73 | printf("\nTPS : %d\n\n", tps); 74 | 75 | if (tps < 500000) { 76 | printf("FAIL: %d < %d\n", tps, mintps); 77 | /* FAIL */ 78 | return 1; 79 | } else { 80 | printf("OK: %d > %d\n", tps, mintps); 81 | /* OK */ 82 | return 0; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /naxsi_src/ext/libinjection/testdriver.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "libinjection.h" 7 | #include "libinjection_sqli.h" 8 | #include "libinjection_html5.h" 9 | #include "libinjection_xss.h" 10 | 11 | static char g_test[8096]; 12 | static char g_input[8096]; 13 | static char g_expected[8096]; 14 | 15 | size_t modp_rtrim(char* str, size_t len); 16 | size_t print_string(char* buf, size_t len, stoken_t* t); 17 | size_t print_var(char* buf, size_t len, stoken_t* t); 18 | size_t print_token(char* buf, size_t len, stoken_t *t); 19 | int read_file(const char* fname, int flags, int testtype); 20 | const char* h5_type_to_string(enum html5_type x); 21 | size_t print_html5_token(char* buf, size_t len, h5_state_t* hs); 22 | 23 | size_t modp_rtrim(char* str, size_t len) 24 | { 25 | while (len) { 26 | char c = str[len -1]; 27 | if (c == ' ' || c == '\n' || c == '\t' || c == '\r') { 28 | str[len -1] = '\0'; 29 | len -= 1; 30 | } else { 31 | break; 32 | } 33 | } 34 | return len; 35 | } 36 | 37 | size_t print_string(char* buf, size_t len, stoken_t* t) 38 | { 39 | int slen = 0; 40 | 41 | /* print opening quote */ 42 | if (t->str_open != '\0') { 43 | slen = sprintf(buf + len, "%c", t->str_open); 44 | assert(slen >= 0); 45 | len += (size_t) slen; 46 | } 47 | 48 | /* print content */ 49 | slen = sprintf(buf + len, "%s", t->val); 50 | assert(slen >= 0); 51 | len += (size_t) slen; 52 | 53 | /* print closing quote */ 54 | if (t->str_close != '\0') { 55 | slen = sprintf(buf + len, "%c", t->str_close); 56 | assert(slen >= 0); 57 | len += (size_t) slen; 58 | } 59 | 60 | return len; 61 | } 62 | 63 | size_t print_var(char* buf, size_t len, stoken_t* t) 64 | { 65 | int slen = 0; 66 | if (t->count >= 1) { 67 | slen = sprintf(buf + len, "%c", '@'); 68 | assert(slen >= 0); 69 | len += (size_t) slen; 70 | } 71 | if (t->count == 2) { 72 | slen = sprintf(buf + len, "%c", '@'); 73 | assert(slen >= 0); 74 | len += (size_t) slen; 75 | } 76 | return print_string(buf, len, t); 77 | } 78 | 79 | const char* h5_type_to_string(enum html5_type x) 80 | { 81 | switch (x) { 82 | case DATA_TEXT: return "DATA_TEXT"; 83 | case TAG_NAME_OPEN: return "TAG_NAME_OPEN"; 84 | case TAG_NAME_CLOSE: return "TAG_NAME_CLOSE"; 85 | case TAG_NAME_SELFCLOSE: return "TAG_NAME_SELFCLOSE"; 86 | case TAG_DATA: return "TAG_DATA"; 87 | case TAG_CLOSE: return "TAG_CLOSE"; 88 | case ATTR_NAME: return "ATTR_NAME"; 89 | case ATTR_VALUE: return "ATTR_VALUE"; 90 | case TAG_COMMENT: return "TAG_COMMENT"; 91 | case DOCTYPE: return "DOCTYPE"; 92 | default: 93 | assert(0); 94 | } 95 | return ""; 96 | } 97 | 98 | size_t print_html5_token(char* buf, size_t len, h5_state_t* hs) 99 | { 100 | int slen; 101 | char* tmp = (char*) malloc(hs->token_len + 1); 102 | memcpy(tmp, hs->token_start, hs->token_len); 103 | /* TODO.. encode to be printable */ 104 | tmp[hs->token_len] = '\0'; 105 | 106 | slen = sprintf(buf + len, "%s,%d,%s\n", 107 | h5_type_to_string(hs->token_type), 108 | (int) hs->token_len, 109 | tmp); 110 | len += (size_t) slen; 111 | free(tmp); 112 | return len; 113 | } 114 | 115 | size_t print_token(char* buf, size_t len, stoken_t *t) 116 | { 117 | int slen; 118 | 119 | slen = sprintf(buf + len, "%c ", t->type); 120 | assert(slen >= 0); 121 | len += (size_t) slen; 122 | switch (t->type) { 123 | case 's': 124 | len = print_string(buf, len, t); 125 | break; 126 | case 'v': 127 | len = print_var(buf, len, t); 128 | break; 129 | default: 130 | slen = sprintf(buf + len, "%s", t->val); 131 | assert(slen >= 0); 132 | len += (size_t) slen; 133 | } 134 | slen = sprintf(buf + len, "%c", '\n'); 135 | assert(slen >= 0); 136 | len += (size_t) slen; 137 | return len; 138 | } 139 | 140 | int read_file(const char* fname, int flags, int testtype) 141 | { 142 | int count = 0; 143 | FILE *fp = NULL; 144 | char linebuf[8192]; 145 | char g_actual[8192]; 146 | char* bufptr = NULL; 147 | size_t slen; 148 | char* copy; 149 | sfilter sf; 150 | int ok = 1; 151 | int num_tokens; 152 | int issqli; 153 | int i; 154 | 155 | g_test[0] = '\0'; 156 | g_input[0] = '\0'; 157 | g_expected[0] = '\0'; 158 | 159 | fp = fopen(fname, "r"); 160 | while(fgets(linebuf, sizeof(linebuf), fp) != NULL) { 161 | if (count == 0 && strcmp(linebuf, "--TEST--\n") == 0) { 162 | bufptr = g_test; 163 | count = 1; 164 | } else if (count == 1 && strcmp(linebuf, "--INPUT--\n") == 0) { 165 | bufptr = g_input; 166 | count = 2; 167 | } else if (count == 2 && strcmp(linebuf, "--EXPECTED--\n") == 0) { 168 | bufptr = g_expected; 169 | count = 3; 170 | } else { 171 | assert(bufptr != NULL); 172 | strcat(bufptr, linebuf); 173 | } 174 | } 175 | fclose(fp); 176 | if (count != 3) { 177 | return 1; 178 | } 179 | 180 | g_expected[modp_rtrim(g_expected, strlen(g_expected))] = '\0'; 181 | g_input[modp_rtrim(g_input, strlen(g_input))] = '\0'; 182 | 183 | 184 | slen = strlen(g_input); 185 | copy = (char* ) malloc(slen); 186 | memcpy(copy, g_input, slen); 187 | 188 | g_actual[0] = '\0'; 189 | if (testtype == 0) { 190 | /* 191 | * print SQLi tokenization only 192 | */ 193 | libinjection_sqli_init(&sf, copy, slen, flags); 194 | libinjection_sqli_callback(&sf, NULL, NULL); 195 | slen =0; 196 | while (libinjection_sqli_tokenize(&sf) == 1) { 197 | slen = print_token(g_actual, slen, sf.current); 198 | } 199 | } else if (testtype == 1) { 200 | /* 201 | * testing tokenization + folding 202 | */ 203 | libinjection_sqli_init(&sf, copy, slen, flags); 204 | libinjection_sqli_callback(&sf, NULL, NULL); 205 | slen =0; 206 | num_tokens = libinjection_sqli_fold(&sf); 207 | for (i = 0; i < num_tokens; ++i) { 208 | slen = print_token(g_actual, slen, libinjection_sqli_get_token(&sf, i)); 209 | } 210 | } else if (testtype == 2) { 211 | /** 212 | * test SQLi detection 213 | */ 214 | char buf[100]; 215 | issqli = libinjection_sqli(copy, slen, buf); 216 | if (issqli) { 217 | sprintf(g_actual, "%s", buf); 218 | } 219 | } else if (testtype == 3) { 220 | /* 221 | * test HTML 5 tokenization only 222 | */ 223 | 224 | h5_state_t hs; 225 | libinjection_h5_init(&hs, copy, slen, DATA_STATE); 226 | slen = 0; 227 | while (libinjection_h5_next(&hs)) { 228 | slen = print_html5_token(g_actual, slen, &hs); 229 | } 230 | } else if (testtype == 4) { 231 | /* 232 | * test XSS detection 233 | */ 234 | sprintf(g_actual, "%d", libinjection_xss(copy, slen)); 235 | } else { 236 | fprintf(stderr, "Got strange testtype value of %d\n", testtype); 237 | assert(0); 238 | } 239 | 240 | g_actual[modp_rtrim(g_actual, strlen(g_actual))] = '\0'; 241 | 242 | if (strcmp(g_expected, g_actual) != 0) { 243 | printf("INPUT: \n%s\n==\n", g_input); 244 | printf("EXPECTED: \n%s\n==\n", g_expected); 245 | printf("GOT: \n%s\n==\n", g_actual); 246 | ok = 0; 247 | } 248 | 249 | free(copy); 250 | return ok; 251 | } 252 | 253 | int main(int argc, char** argv) 254 | { 255 | int offset = 1; 256 | int i; 257 | int ok; 258 | int count = 0; 259 | int count_fail = 0; 260 | int flags = 0; 261 | int testtype = 0; 262 | int quiet = 0; 263 | 264 | const char* fname; 265 | while (argc > offset) { 266 | if (strcmp(argv[offset], "-q") == 0 || strcmp(argv[offset], "--quiet") == 0) { 267 | quiet = 1; 268 | offset += 1; 269 | } else { 270 | break; 271 | } 272 | } 273 | 274 | printf("%s\n", libinjection_version()); 275 | 276 | for (i = offset; i < argc; ++i) { 277 | fname = argv[i]; 278 | count += 1; 279 | if (strstr(fname, "test-tokens-")) { 280 | flags = FLAG_QUOTE_NONE | FLAG_SQL_ANSI; 281 | testtype = 0; 282 | } else if (strstr(fname, "test-folding-")) { 283 | flags = FLAG_QUOTE_NONE | FLAG_SQL_ANSI; 284 | testtype = 1; 285 | } else if (strstr(fname, "test-sqli-")) { 286 | flags = FLAG_NONE; 287 | testtype = 2; 288 | } else if (strstr(fname, "test-html5-")) { 289 | flags = FLAG_NONE; 290 | testtype = 3; 291 | } else if (strstr(fname, "test-xss-")) { 292 | flags = FLAG_NONE; 293 | testtype = 4; 294 | } else { 295 | fprintf(stderr, "Unknown test type: %s, failing\n", fname); 296 | count_fail += 1; 297 | continue; 298 | } 299 | 300 | ok = read_file(fname, flags, testtype); 301 | if (ok) { 302 | if (! quiet) { 303 | fprintf(stderr, "%s: ok\n", fname); 304 | } 305 | } else { 306 | count_fail += 1; 307 | if (! quiet) { 308 | fprintf(stderr, "%s: fail\n", fname); 309 | } 310 | } 311 | } 312 | return count > 0 && count_fail > 0; 313 | } 314 | -------------------------------------------------------------------------------- /naxsi_src/naxsi_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NAXSI, a web application firewall for NGINX 3 | * Copyright (C) NBS System – All Rights Reserved 4 | * Licensed under GNU GPL v3.0 – See the LICENSE notice for details 5 | */ 6 | 7 | #ifndef __NAXSI_CONFIG_H__ 8 | #define __NAXSI_CONFIG_H__ 9 | 10 | /* custom match zones */ 11 | #define MZ_GET_VAR_T "$ARGS_VAR:" 12 | #define MZ_HEADER_VAR_T "$HEADERS_VAR:" 13 | #define MZ_POST_VAR_T "$BODY_VAR:" 14 | #define MZ_SPECIFIC_URL_T "$URL:" 15 | 16 | /* add support for regex-style match zones. 17 | ** this whole function should be rewritten as it's getting 18 | ** messy as hell 19 | */ 20 | #define MZ_GET_VAR_X "$ARGS_VAR_X:" 21 | #define MZ_HEADER_VAR_X "$HEADERS_VAR_X:" 22 | #define MZ_POST_VAR_X "$BODY_VAR_X:" 23 | #define MZ_SPECIFIC_URL_X "$URL_X:" 24 | 25 | #endif /* __NAXSI_CONFIG_H__ */ 26 | -------------------------------------------------------------------------------- /naxsi_src/naxsi_json.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NAXSI, a web application firewall for NGINX 3 | * Copyright (C) NBS System – All Rights Reserved 4 | * Licensed under GNU GPL v3.0 – See the LICENSE notice for details 5 | */ 6 | 7 | #include "naxsi.h" 8 | #include "naxsi_macros.h" 9 | 10 | #define json_char(x) ((x)->src + (x)->off) 11 | 12 | //#define _debug_json 1 13 | 14 | ngx_http_rule_t nx_int__invalid_json = { 15 | 0, /* type */ 16 | 0, /* whitelist flag */ 17 | NULL, /* wl_id ptr */ 18 | 15, /* rule_id */ 19 | NULL, /* log_msg */ 20 | 0, /* score */ 21 | NULL, /* sscores */ 22 | 1, /* sc_block */ 23 | 0, /* sc_allow */ 24 | 1, /* block */ 25 | 0, /* allow */ 26 | 0, /* drop */ 27 | 0, /* log */ 28 | NULL /* br ptrs */ 29 | }; 30 | 31 | ngx_int_t 32 | ngx_http_nx_json_forward(ngx_json_t* js) 33 | { 34 | while (js->off < js->len && is_whitespace(*json_char(js))) { 35 | js->off++; 36 | } 37 | js->c = *json_char(js); 38 | return (NGX_OK); 39 | } 40 | 41 | /* 42 | ** used to fast forward in json POSTS, 43 | ** we skip whitespaces/tab/CR/LF 44 | */ 45 | ngx_int_t 46 | ngx_http_nx_json_seek(ngx_json_t* js, unsigned char seek) 47 | { 48 | ngx_http_nx_json_forward(js); 49 | if (js->c != seek) { 50 | return (NGX_ERROR); 51 | } 52 | return (NGX_OK); 53 | } 54 | 55 | /* 56 | ** extract a quoted strings, 57 | ** JSON spec only supports double-quoted strings, 58 | ** so do we. 59 | */ 60 | ngx_int_t 61 | ngx_http_nx_json_quoted(ngx_json_t* js, ngx_str_t* ve) 62 | { 63 | u_char *vn_start, *vn_end; 64 | 65 | vn_start = vn_end = NULL; 66 | 67 | return_value_if(*json_char(js) != '"', NGX_ERROR); 68 | js->off++; 69 | vn_start = json_char(js); 70 | /* extract varname inbetween "..."*/ 71 | while (js->off < js->len) { 72 | /* skip next character if backslashed */ 73 | if (*json_char(js) == '\\') { 74 | js->off += 2; 75 | if (js->off >= js->len) 76 | break; 77 | continue; 78 | } 79 | if (*json_char(js) == '"') { 80 | vn_end = js->src + js->off; 81 | js->off++; 82 | break; 83 | } 84 | js->off++; 85 | } 86 | if (!vn_start || !vn_end) { 87 | return (NGX_ERROR); 88 | } 89 | if (!*vn_start || !*vn_end) { 90 | return (NGX_ERROR); 91 | } 92 | ve->data = vn_start; 93 | ve->len = vn_end - vn_start; 94 | return (NGX_OK); 95 | } 96 | 97 | /* 98 | ** an array is values separated by ',' 99 | */ 100 | ngx_int_t 101 | ngx_http_nx_json_array(ngx_json_t* js) 102 | { 103 | ngx_int_t rc; 104 | 105 | js->c = *(js->src + js->off); 106 | if (js->c != '[' || js->depth > JSON_MAX_DEPTH) 107 | return (NGX_ERROR); 108 | js->off++; 109 | do { 110 | rc = ngx_http_nx_json_val(js); 111 | /* if we cannot extract the value, 112 | we may have reached array end. */ 113 | if (rc != NGX_OK) { 114 | break; 115 | } 116 | ngx_http_nx_json_forward(js); 117 | if (js->c == ',') { 118 | js->off++; 119 | ngx_http_nx_json_forward(js); 120 | } else 121 | break; 122 | } while (rc == NGX_OK); 123 | if (js->c != ']') { 124 | return (NGX_ERROR); 125 | } 126 | return (NGX_OK); 127 | } 128 | 129 | ngx_int_t 130 | ngx_http_nx_json_val(ngx_json_t* js) 131 | { 132 | ngx_str_t val; 133 | ngx_int_t ret; 134 | ngx_str_t empty = ngx_string(""); 135 | 136 | val.data = NULL; 137 | val.len = 0; 138 | 139 | ngx_http_nx_json_forward(js); 140 | if (js->c == '"') { 141 | ret = ngx_http_nx_json_quoted(js, &val); 142 | if (ret == NGX_OK) { 143 | /* parse extracted values. */ 144 | if (js->loc_cf->body_rules) { 145 | ngx_http_basestr_ruleset_n( 146 | js->r->pool, &js->ckey, &val, js->loc_cf->body_rules, js->r, js->ctx, BODY); 147 | } 148 | if (js->main_cf->body_rules) { 149 | ngx_http_basestr_ruleset_n( 150 | js->r->pool, &js->ckey, &val, js->main_cf->body_rules, js->r, js->ctx, BODY); 151 | } 152 | NX_DEBUG(_debug_json, 153 | NGX_LOG_DEBUG_HTTP, 154 | js->r->connection->log, 155 | 0, 156 | "quoted-JSON '%V' : '%V'", 157 | &(js->ckey), 158 | &(val)); 159 | } 160 | return (ret); 161 | } 162 | if ((js->c >= '0' && js->c <= '9') || js->c == '-') { 163 | val.data = js->src + js->off; 164 | while (((*(js->src + js->off) >= '0' && *(js->src + js->off) <= '9') || 165 | *(js->src + js->off) == '.' || *(js->src + js->off) == '-' || 166 | *(js->src + js->off) == 'e') && 167 | js->off < js->len) { 168 | val.len++; 169 | js->off++; 170 | } 171 | /* parse extracted values. */ 172 | if (js->loc_cf->body_rules) { 173 | ngx_http_basestr_ruleset_n( 174 | js->r->pool, &js->ckey, &val, js->loc_cf->body_rules, js->r, js->ctx, BODY); 175 | } 176 | if (js->main_cf->body_rules) { 177 | ngx_http_basestr_ruleset_n( 178 | js->r->pool, &js->ckey, &val, js->main_cf->body_rules, js->r, js->ctx, BODY); 179 | } 180 | NX_DEBUG(_debug_json, 181 | NGX_LOG_DEBUG_HTTP, 182 | js->r->connection->log, 183 | 0, 184 | "JSON '%V' : '%V'", 185 | &(js->ckey), 186 | &(val)); 187 | return (NGX_OK); 188 | } 189 | if (!strncasecmp((const char*)(js->src + js->off), (const char*)"true", 4) || 190 | !strncasecmp((const char*)(js->src + js->off), (const char*)"false", 5) || 191 | !strncasecmp((const char*)(js->src + js->off), (const char*)"null", 4)) { 192 | js->c = *(js->src + js->off); 193 | /* we don't check static values, do we ?! */ 194 | val.data = js->src + js->off; 195 | if (js->c == 'F' || js->c == 'f') { 196 | js->off += 5; 197 | val.len = 5; 198 | } else { 199 | js->off += 4; 200 | val.len = 4; 201 | } 202 | /* parse extracted values. */ 203 | if (js->loc_cf->body_rules) { 204 | ngx_http_basestr_ruleset_n( 205 | js->r->pool, &js->ckey, &val, js->loc_cf->body_rules, js->r, js->ctx, BODY); 206 | } 207 | if (js->main_cf->body_rules) { 208 | ngx_http_basestr_ruleset_n( 209 | js->r->pool, &js->ckey, &val, js->main_cf->body_rules, js->r, js->ctx, BODY); 210 | } 211 | NX_DEBUG(_debug_json, 212 | NGX_LOG_DEBUG_HTTP, 213 | js->r->connection->log, 214 | 0, 215 | "JSON '%V' : '%V'", 216 | &(js->ckey), 217 | &(val)); 218 | return (NGX_OK); 219 | } 220 | 221 | if (js->c == '[') { 222 | ret = ngx_http_nx_json_array(js); 223 | if (js->c != ']') { 224 | return (NGX_ERROR); 225 | } 226 | js->off++; 227 | return (ret); 228 | } 229 | if (js->c == '{') { 230 | /* 231 | ** if sub-struct, parse key without value : 232 | ** "foobar" : { "bar" : [1,2,3]} => "foobar" parsed alone. 233 | ** this is to avoid "foobar" left unparsed, as we won't have 234 | ** key/value here with "foobar" as a key. 235 | */ 236 | if (js->loc_cf->body_rules) { 237 | ngx_http_basestr_ruleset_n( 238 | js->r->pool, &js->ckey, &empty, js->loc_cf->body_rules, js->r, js->ctx, BODY); 239 | } 240 | if (js->main_cf->body_rules) { 241 | ngx_http_basestr_ruleset_n( 242 | js->r->pool, &js->ckey, &empty, js->main_cf->body_rules, js->r, js->ctx, BODY); 243 | } 244 | ret = ngx_http_nx_json_obj(js); 245 | ngx_http_nx_json_forward(js); 246 | if (js->c != '}') { 247 | return (NGX_ERROR); 248 | } 249 | js->off++; 250 | return (ret); 251 | } 252 | return (NGX_ERROR); 253 | } 254 | 255 | ngx_int_t 256 | ngx_http_nx_json_obj(ngx_json_t* js) 257 | { 258 | js->c = *(js->src + js->off); 259 | 260 | if (js->c != '{' || js->depth > JSON_MAX_DEPTH) 261 | return (NGX_ERROR); 262 | js->off++; 263 | 264 | do { 265 | ngx_http_nx_json_forward(js); 266 | /* check subs (arrays, objects) */ 267 | switch (js->c) { 268 | case '[': /* array */ 269 | js->depth++; 270 | ngx_http_nx_json_array(js); 271 | if (ngx_http_nx_json_seek(js, ']')) 272 | return (NGX_ERROR); 273 | js->off++; 274 | js->depth--; 275 | break; 276 | case '{': /* sub-object */ 277 | js->depth++; 278 | ngx_http_nx_json_obj(js); 279 | if (js->c != '}') { 280 | return (NGX_ERROR); 281 | } 282 | js->off++; 283 | js->depth--; 284 | break; 285 | case '"': /* key : value, extract and parse. */ 286 | if (ngx_http_nx_json_quoted(js, &(js->ckey)) != NGX_OK) { 287 | return (NGX_ERROR); 288 | } 289 | if (ngx_http_nx_json_seek(js, ':')) { 290 | return (NGX_ERROR); 291 | } 292 | js->off++; 293 | ngx_http_nx_json_forward(js); 294 | if (ngx_http_nx_json_val(js) != NGX_OK) { 295 | return (NGX_ERROR); 296 | } 297 | } 298 | ngx_http_nx_json_forward(js); 299 | /* another element ? */ 300 | if (js->c == ',') { 301 | js->off++; 302 | ngx_http_nx_json_forward(js); 303 | continue; 304 | 305 | } else if (js->c == '}') { 306 | js->depth--; 307 | /* or maybe we just finished parsing this object */ 308 | return (NGX_OK); 309 | } else { 310 | /* nothing we expected, die. */ 311 | return (NGX_ERROR); 312 | } 313 | } while (js->off < js->len); 314 | 315 | return (NGX_ERROR); 316 | } 317 | 318 | /* 319 | ** Parse a JSON request 320 | */ 321 | void 322 | ngx_http_naxsi_json_parse(ngx_http_request_ctx_t* ctx, 323 | ngx_http_request_t* r, 324 | u_char* src, 325 | u_int len) 326 | { 327 | ngx_json_t* js; 328 | 329 | js = ngx_pcalloc(r->pool, sizeof(ngx_json_t)); 330 | if (!js) 331 | return; 332 | js->json.data = js->src = src; 333 | js->json.len = js->len = len; 334 | js->r = r; 335 | js->ctx = ctx; 336 | js->loc_cf = ngx_http_get_module_loc_conf(r, ngx_http_naxsi_module); 337 | js->main_cf = ngx_http_get_module_main_conf(r, ngx_http_naxsi_module); 338 | 339 | if (ngx_http_nx_json_val(js) != NGX_OK) { 340 | ngx_http_apply_rulematch_v_n(&nx_int__invalid_json, ctx, r, NULL, NULL, BODY, 1, 0); 341 | NX_DEBUG(_debug_json, 342 | NGX_LOG_DEBUG_HTTP, 343 | js->r->connection->log, 344 | 0, 345 | "nx_json_val returned error, apply invalid_json."); 346 | } 347 | ngx_http_nx_json_forward(js); 348 | if (js->off != js->len) { 349 | ngx_http_apply_rulematch_v_n(&nx_int__invalid_json, ctx, r, NULL, NULL, BODY, 1, 0); 350 | } 351 | return; 352 | } 353 | -------------------------------------------------------------------------------- /naxsi_src/naxsi_macros.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NAXSI, a web application firewall for NGINX 3 | * Copyright (C) NBS System – All Rights Reserved 4 | * Licensed under GNU GPL v3.0 – See the LICENSE notice for details 5 | */ 6 | 7 | #ifndef __NAXSI_MACROS_H__ 8 | #define __NAXSI_MACROS_H__ 9 | 10 | #define is_whitespace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r') 11 | #define is_printable(c) ((c) >= ' ' && (c) <= '~') 12 | #define is_numeric(c) ((c) >= '0' && (c) <= '9') 13 | #define const_len(s) (sizeof(s) - sizeof(s[0])) 14 | 15 | #define return_value_if(cond, val) \ 16 | if ((cond)) \ 17 | return (val) 18 | #define return_void_if(cond) \ 19 | if ((cond)) \ 20 | return 21 | #define break_if(cond) \ 22 | if ((cond)) \ 23 | break 24 | 25 | #endif /* __NAXSI_MACROS_H__ */ 26 | -------------------------------------------------------------------------------- /naxsi_src/naxsi_net.c: -------------------------------------------------------------------------------- 1 | #include "naxsi_net.h" 2 | 3 | int 4 | parse_ipv6(const char* addr, ip_t* ip, char* ip_str) 5 | { 6 | struct in6_addr ipv6 = { .s6_addr = { 0 } }; 7 | if (inet_pton(AF_INET6, addr, &ipv6) != 1) { 8 | return 0; 9 | } 10 | 11 | if (ip) { 12 | // ipv6 hi 13 | ip->v6[0] = ipv6.s6_addr[0]; 14 | ip->v6[0] = (ip->v6[0] << 8) | ipv6.s6_addr[1]; 15 | ip->v6[0] = (ip->v6[0] << 8) | ipv6.s6_addr[2]; 16 | ip->v6[0] = (ip->v6[0] << 8) | ipv6.s6_addr[3]; 17 | ip->v6[0] = (ip->v6[0] << 8) | ipv6.s6_addr[4]; 18 | ip->v6[0] = (ip->v6[0] << 8) | ipv6.s6_addr[5]; 19 | ip->v6[0] = (ip->v6[0] << 8) | ipv6.s6_addr[6]; 20 | ip->v6[0] = (ip->v6[0] << 8) | ipv6.s6_addr[7]; 21 | 22 | // ipv6 low 23 | ip->v6[1] = ipv6.s6_addr[8]; 24 | ip->v6[1] = (ip->v6[1] << 8) | ipv6.s6_addr[9]; 25 | ip->v6[1] = (ip->v6[1] << 8) | ipv6.s6_addr[10]; 26 | ip->v6[1] = (ip->v6[1] << 8) | ipv6.s6_addr[11]; 27 | ip->v6[1] = (ip->v6[1] << 8) | ipv6.s6_addr[12]; 28 | ip->v6[1] = (ip->v6[1] << 8) | ipv6.s6_addr[13]; 29 | ip->v6[1] = (ip->v6[1] << 8) | ipv6.s6_addr[14]; 30 | ip->v6[1] = (ip->v6[1] << 8) | ipv6.s6_addr[15]; 31 | } 32 | 33 | if (ip_str) { 34 | inet_ntop(AF_INET6, &ipv6, ip_str, INET6_ADDRSTRLEN); 35 | } 36 | return 1; 37 | } 38 | 39 | int 40 | parse_ipv4(const char* addr, ip_t* ip, char* ip_str) 41 | { 42 | struct in_addr ipv4 = { .s_addr = 0 }; 43 | if (inet_pton(AF_INET, addr, &ipv4) != 1) { 44 | return 0; 45 | } 46 | 47 | if (ip) { 48 | ip->v4 = htonl(ipv4.s_addr); 49 | } 50 | 51 | if (ip_str) { 52 | inet_ntop(AF_INET, &ipv4, ip_str, INET_ADDRSTRLEN); 53 | } 54 | return 1; 55 | } 56 | 57 | int 58 | is_in_subnet(const cidr_t* cidr, const ip_t* ip, int is_ipv6) 59 | { 60 | if ((cidr->version == IPv6 && !is_ipv6) || (cidr->version == IPv4 && is_ipv6)) { 61 | return 0; 62 | } 63 | if (cidr->version == IPv4) { 64 | return (ip->v4 & cidr->mask.v4) == (cidr->subnet.v4 & cidr->mask.v4); 65 | } else { 66 | return (ip->v6[0] & cidr->mask.v6[0]) == (cidr->subnet.v6[0] & cidr->mask.v6[0]) && 67 | (ip->v6[1] & cidr->mask.v6[1]) == (cidr->subnet.v6[1] & cidr->mask.v6[1]); 68 | } 69 | return 0; 70 | } -------------------------------------------------------------------------------- /naxsi_src/naxsi_net.h: -------------------------------------------------------------------------------- 1 | /* 2 | * NAXSI, a web application firewall for NGINX 3 | * Copyright (C) NBS System – All Rights Reserved 4 | * Licensed under GNU GPL v3.0 – See the LICENSE notice for details 5 | */ 6 | 7 | #ifndef __NAXSI_NET_H__ 8 | #define __NAXSI_NET_H__ 9 | 10 | #if defined(__FreeBSD__) || defined(__OpenBSD__) 11 | #include 12 | #include 13 | #include 14 | #endif 15 | 16 | #include 17 | #include 18 | #include 19 | 20 | typedef union 21 | { 22 | uint64_t v6[2]; 23 | uint32_t v4; 24 | } ip_t; 25 | 26 | typedef enum 27 | { 28 | IPv4 = 0, 29 | IPv6 30 | } ip_type_t; 31 | 32 | typedef struct 33 | { 34 | uint32_t version; 35 | ip_t mask; 36 | ip_t subnet; 37 | } cidr_t; 38 | 39 | int 40 | parse_ipv6(const char* addr, ip_t* ip, char* ip_str); 41 | int 42 | parse_ipv4(const char* addr, ip_t* ip, char* ip_str); 43 | 44 | int 45 | is_in_subnet(const cidr_t* cidr, const ip_t* ip, int is_ipv6); 46 | 47 | #endif /* __NAXSI_NET_H__ */ 48 | -------------------------------------------------------------------------------- /naxsi_src/naxsi_raw.c: -------------------------------------------------------------------------------- 1 | /* 2 | * NAXSI, a web application firewall for NGINX 3 | * Copyright (C) NBS System – All Rights Reserved 4 | * Licensed under GNU GPL v3.0 – See the LICENSE notice for details 5 | */ 6 | 7 | #include "naxsi.h" 8 | 9 | void 10 | ngx_http_naxsi_rawbody_parse(ngx_http_request_ctx_t* ctx, 11 | ngx_http_request_t* r, 12 | u_char* src, 13 | u_int len) 14 | { 15 | ngx_http_naxsi_loc_conf_t* cf; 16 | ngx_str_t body; 17 | ngx_http_naxsi_main_conf_t* main_cf; 18 | ngx_str_t empty = ngx_string(""); 19 | 20 | NX_DEBUG( 21 | _debug_rawbody, NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "XX-RAWBODY CALLED len:%d", len); 22 | if (len <= 0 || !src) 23 | return; 24 | cf = ngx_http_get_module_loc_conf(r, ngx_http_naxsi_module); 25 | main_cf = ngx_http_get_module_main_conf(r, ngx_http_naxsi_module); 26 | 27 | body.data = src; 28 | body.len = len; 29 | 30 | naxsi_unescape(&body); 31 | 32 | /* here we got val name + val content !*/ 33 | if (cf->raw_body_rules) { 34 | NX_DEBUG( 35 | _debug_rawbody, NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "XX-(local) RAW BODY RULES"); 36 | ngx_http_basestr_ruleset_n(r->pool, &empty, &body, cf->raw_body_rules, r, ctx, BODY); 37 | } 38 | 39 | if (main_cf->raw_body_rules) { 40 | NX_DEBUG( 41 | _debug_rawbody, NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "XX-(global) RAW BODY RULES"); 42 | ngx_http_basestr_ruleset_n(r->pool, &empty, &body, main_cf->raw_body_rules, r, ctx, BODY); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nxapi/naxsi_kibana.dash: -------------------------------------------------------------------------------- 1 | { 2 | "title": "naxsi-current+inspect (last 1 hour)", 3 | "services": { 4 | "query": { 5 | "idQueue": [ 6 | 1, 7 | 2, 8 | 3, 9 | 4 10 | ], 11 | "list": { 12 | "0": { 13 | "id": 0, 14 | "type": "topN", 15 | "query": "*", 16 | "alias": "", 17 | "color": "#6ED0E0", 18 | "pin": false, 19 | "enable": true, 20 | "field": "server", 21 | "size": 10, 22 | "union": "AND" 23 | } 24 | }, 25 | "ids": [ 26 | 0 27 | ] 28 | }, 29 | "filter": { 30 | "idQueue": [ 31 | 0, 32 | 1, 33 | 2 34 | ], 35 | "list": { 36 | "0": { 37 | "type": "time", 38 | "field": "date", 39 | "from": "now-1h", 40 | "to": "now", 41 | "mandate": "must", 42 | "active": true, 43 | "alias": "", 44 | "id": 0 45 | }, 46 | "1": { 47 | "type": "querystring", 48 | "query": "*preprod*", 49 | "mandate": "mustNot", 50 | "active": true, 51 | "alias": "", 52 | "id": 1 53 | } 54 | }, 55 | "ids": [ 56 | 0, 57 | 1 58 | ] 59 | } 60 | }, 61 | "rows": [ 62 | { 63 | "title": "events", 64 | "height": "250px", 65 | "editable": true, 66 | "collapse": false, 67 | "collapsable": true, 68 | "panels": [ 69 | { 70 | "error": false, 71 | "span": 3, 72 | "editable": true, 73 | "type": "terms", 74 | "loadingEditor": false, 75 | "queries": { 76 | "mode": "all", 77 | "ids": [ 78 | 0 79 | ] 80 | }, 81 | "field": "server", 82 | "exclude": [], 83 | "missing": true, 84 | "other": true, 85 | "size": 30, 86 | "order": "count", 87 | "style": { 88 | "font-size": "10pt" 89 | }, 90 | "donut": false, 91 | "tilt": false, 92 | "labels": true, 93 | "arrangement": "vertical", 94 | "chart": "bar", 95 | "counter_pos": "below", 96 | "spyable": true, 97 | "title": "sites", 98 | "tmode": "terms", 99 | "tstat": "total", 100 | "valuefield": "" 101 | }, 102 | { 103 | "span": 9, 104 | "editable": true, 105 | "type": "histogram", 106 | "loadingEditor": false, 107 | "mode": "count", 108 | "time_field": "date", 109 | "queries": { 110 | "mode": "all", 111 | "ids": [ 112 | 0 113 | ] 114 | }, 115 | "value_field": null, 116 | "auto_int": false, 117 | "resolution": 100, 118 | "interval": "1m", 119 | "intervals": [ 120 | "auto", 121 | "1s", 122 | "1m", 123 | "5m", 124 | "10m", 125 | "30m", 126 | "1h", 127 | "3h", 128 | "12h", 129 | "1d", 130 | "1w", 131 | "1M", 132 | "1y" 133 | ], 134 | "fill": 1, 135 | "linewidth": 3, 136 | "timezone": "browser", 137 | "spyable": true, 138 | "zoomlinks": true, 139 | "bars": true, 140 | "stack": false, 141 | "points": false, 142 | "lines": false, 143 | "legend": true, 144 | "x-axis": true, 145 | "y-axis": true, 146 | "percentage": false, 147 | "interactive": false, 148 | "options": true, 149 | "tooltip": { 150 | "value_type": "individual", 151 | "query_as_alias": true 152 | }, 153 | "title": "history", 154 | "scale": 1, 155 | "y_format": "none", 156 | "grid": { 157 | "max": null, 158 | "min": 0 159 | }, 160 | "annotate": { 161 | "enable": false, 162 | "query": "*", 163 | "size": 20, 164 | "field": "_type", 165 | "sort": [ 166 | "_score", 167 | "desc" 168 | ] 169 | }, 170 | "pointradius": 5, 171 | "show_query": true, 172 | "legend_counts": true, 173 | "zerofill": true, 174 | "derivative": false 175 | } 176 | ], 177 | "notice": false 178 | }, 179 | { 180 | "title": "timelines", 181 | "height": "150px", 182 | "editable": true, 183 | "collapse": false, 184 | "collapsable": true, 185 | "panels": [ 186 | { 187 | "error": false, 188 | "span": 12, 189 | "editable": true, 190 | "type": "table", 191 | "loadingEditor": false, 192 | "size": 100, 193 | "pages": 5, 194 | "offset": 0, 195 | "sort": [ 196 | "date", 197 | "desc" 198 | ], 199 | "overflow": "min-height", 200 | "fields": [ 201 | "server", 202 | "uri", 203 | "zone", 204 | "var_name", 205 | "ip", 206 | "id", 207 | "content", 208 | "date" 209 | ], 210 | "highlight": [ 211 | null 212 | ], 213 | "sortable": true, 214 | "header": true, 215 | "paging": true, 216 | "field_list": false, 217 | "all_fields": false, 218 | "trimFactor": 300, 219 | "localTime": false, 220 | "timeField": "date", 221 | "spyable": true, 222 | "queries": { 223 | "mode": "all", 224 | "ids": [ 225 | 0 226 | ] 227 | }, 228 | "style": { 229 | "font-size": "9pt" 230 | }, 231 | "normTimes": true 232 | } 233 | ], 234 | "notice": false 235 | } 236 | ], 237 | "editable": true, 238 | "failover": false, 239 | "index": { 240 | "interval": "none", 241 | "pattern": "[logstash-]YYYY.MM.DD", 242 | "default": "nxapi", 243 | "warm_fields": true 244 | }, 245 | "style": "dark", 246 | "panel_hints": true, 247 | "pulldowns": [ 248 | { 249 | "type": "query", 250 | "collapse": true, 251 | "notice": false, 252 | "enable": true, 253 | "query": "*", 254 | "pinned": true, 255 | "history": [ 256 | "*", 257 | "www.forum-fic.com" 258 | ], 259 | "remember": 10 260 | }, 261 | { 262 | "type": "filtering", 263 | "collapse": false, 264 | "notice": true, 265 | "enable": true 266 | } 267 | ], 268 | "nav": [ 269 | { 270 | "type": "timepicker", 271 | "collapse": false, 272 | "notice": false, 273 | "enable": true, 274 | "status": "Stable", 275 | "time_options": [ 276 | "5m", 277 | "15m", 278 | "1h", 279 | "6h", 280 | "12h", 281 | "24h", 282 | "2d", 283 | "7d", 284 | "30d" 285 | ], 286 | "refresh_intervals": [ 287 | "5s", 288 | "10s", 289 | "30s", 290 | "1m", 291 | "5m", 292 | "15m", 293 | "30m", 294 | "1h", 295 | "2h", 296 | "1d" 297 | ], 298 | "timefield": "date", 299 | "now": true, 300 | "filter_id": 0 301 | } 302 | ], 303 | "loader": { 304 | "save_gist": true, 305 | "save_elasticsearch": true, 306 | "save_local": true, 307 | "save_default": true, 308 | "save_temp": true, 309 | "save_temp_ttl_enable": true, 310 | "save_temp_ttl": "30d", 311 | "load_gist": false, 312 | "load_elasticsearch": true, 313 | "load_elasticsearch_size": 20, 314 | "load_local": false, 315 | "hide": false 316 | }, 317 | "refresh": "10s" 318 | } -------------------------------------------------------------------------------- /nxapi/nx_datas/country2coords.txt: -------------------------------------------------------------------------------- 1 | AD:42.5462450,1.6015540 2 | AE:23.4240760,53.8478180 3 | AF:33.939110,67.7099530 4 | AG:47.38766640,8.25542950 5 | AI:18.2205540,-63.06861499999999 6 | AL:32.31823140,-86.9022980 7 | AM:-3.41684270,-65.85606460 8 | AN:12.2260790,-69.0600870 9 | AO:47.5162310,14.5500720 10 | AQ:-82.86275189999999,-135.0 11 | AR:35.201050,-91.83183339999999 12 | AS:-14.2709720,-170.1322170 13 | AT:47.5162310,14.5500720 14 | AU:-25.2743980,133.7751360 15 | AW:12.521110,-69.9683380 16 | AX:60.33854850,20.27125850 17 | AZ:34.04892810,-111.09373110 18 | BA:43.9158860,17.6790760 19 | BB:13.1938870,-59.5431980 20 | BD:23.6849940,90.3563310 21 | BE:50.5038870,4.4699360 22 | BF:12.2383330,-1.5615930 23 | BG:42.7338830,25.485830 24 | BH:-19.91906770,-43.93857470 25 | BI:-3.3730560,29.9188860 26 | BJ:9.307689999999999,2.3158340 27 | BM:32.3213840,-64.75736999999999 28 | BN:4.5352770,114.7276690 29 | BO:7.95517910,-11.74099460 30 | BR:-14.2350040,-51.925280 31 | BS:25.034280,-77.39627999999999 32 | BT:27.5141620,90.4336010 33 | BV:47.65806030,-94.87917419999999 34 | BW:-22.3284740,24.6848660 35 | BY:53.7098070,27.9533890 36 | BZ:17.1898770,-88.49764999999999 37 | CA:36.7782610,-119.41793240 38 | CC:-26.58576560,-60.95400730 39 | CD:-4.0383330,21.7586640 40 | CF:6.611110999999999,20.9394440 41 | CG:-0.2280210,15.8276590 42 | CH:46.8181880,8.227511999999999 43 | CI:7.539988999999999,-5.547079999999999 44 | CK:-21.2367360,-159.7776710 45 | CL:-35.6751470,-71.5429690 46 | CM:7.369721999999999,12.3547220 47 | CN:35.861660,104.1953970 48 | CO:39.55005070,-105.78206740 49 | CR:9.748916999999999,-83.7534280 50 | CS:39.56441050,16.25221430 51 | CU:21.5217570,-77.7811670 52 | CV:16.0020820,-24.0131970 53 | CX:-10.4475250,105.6904490 54 | CY:35.1264130,33.4298590 55 | CZ:49.81749199999999,15.4729620 56 | DE:51.165691,10.451526 57 | DJ:11.8251380,42.5902750 58 | DK:56.263920,9.5017850 59 | DM:15.4149990,-61.37097600000001 60 | DO:18.7356930,-70.1626510 61 | DZ:28.0338860,1.6596260 62 | EC:-32.29684020,26.4193890 63 | EE:58.5952720,25.0136070 64 | EG:26.8205530,30.8024980 65 | EH:24.2155270,-12.8858340 66 | ER:15.1793840,39.7823340 67 | ES:-19.18342290,-40.30886260 68 | ET:9.145000000000001,40.4896730 69 | FI:61.92410999999999,25.7481510 70 | FJ:-17.7133710,178.0650320 71 | FK:-51.7962530,-59.5236130 72 | FM:-25.39459690,-58.73736339999999 73 | FO:-25.39459690,-58.73736339999999 74 | FR:46.2276380,2.2137490 75 | FX:27.9026210,-82.7447310 76 | GA:32.15743510,-82.90712300000001 77 | GB:55.3780510,-3.4359730 78 | GD:12.11650,-61.67899999999999 79 | GE:52.0451550,5.871823399999999 80 | GF:3.9338890,-53.1257820 81 | GH:7.9465270,-1.0231940 82 | GI:36.1377410,-5.3453740 83 | GL:71.7069360,-42.6043030 84 | GM:13.4431820,-15.3101390 85 | GN:9.9455870,-9.6966450 86 | GP:-26.27075930,28.11226790 87 | GQ:1.6508010,10.2678950 88 | GR:39.0742080,21.8243120 89 | GS:-54.4295790,-36.5879090 90 | GT:15.7834710,-90.23075899999999 91 | GU:13.4443040,144.7937310 92 | GW:11.8037490,-15.1804130 93 | GY:4.8604160,-58.930180 94 | HK:22.3964280,114.1094970 95 | HM:-53.081810,73.50415799999999 96 | HN:15.1999990,-86.2419050 97 | HR:45.10,15.20 98 | HT:18.9711870,-72.28521499999999 99 | HU:47.1624940,19.5033040 100 | ID:44.06820190,-114.74204080 101 | IE:53.412910,-8.243890 102 | IL:40.63312490,-89.39852830 103 | IN:40.26719410,-86.13490190 104 | IO:-6.3431940,71.8765190 105 | IQ:33.2231910,43.6792910 106 | IR:32.4279080,53.6880460 107 | IS:64.96305099999999,-19.0208350 108 | IT:41.871940,12.567380 109 | JM:18.1095810,-77.29750799999999 110 | JO:30.5851640,36.2384140 111 | JP:36.2048240,138.2529240 112 | KE:-0.0235590,37.9061930 113 | KG:41.204380,74.7660980 114 | KH:12.5656790,104.9909630 115 | KI:-3.3704170,-168.7340390 116 | KM:-11.8750010,43.8722190 117 | KN:17.3578220,-62.7829980 118 | KP:40.3398520,127.5100930 119 | KR:35.9077570,127.7669220 120 | KW:29.311660,47.4817660 121 | KY:37.83933320,-84.27001790 122 | KZ:48.0195730,66.92368399999999 123 | LA:31.24482340,-92.14502449999999 124 | LB:33.8547210,35.8622850 125 | LC:45.93829410,9.3857290 126 | LI:51.44272380,6.06087260 127 | LK:7.873053999999999,80.77179699999999 128 | LR:6.4280550,-9.429499000000002 129 | LS:-29.6099880,28.2336080 130 | LT:55.1694380,23.8812750 131 | LU:49.8152730,6.129582999999999 132 | LV:56.8796350,24.6031890 133 | LY:26.33510,17.2283310 134 | MA:42.40721070,-71.38243740 135 | MC:43.73841760000001,7.424615799999999 136 | MD:39.04575490,-76.64127119999999 137 | MG:-17.9301780,-43.79084530 138 | MH:19.75147980,75.71388840 139 | MK:41.6086350,21.7452750 140 | ML:17.5706920,-3.9961660 141 | MM:21.9139650,95.95622299999999 142 | MN:46.7295530,-94.68589980 143 | MO:37.96425290,-91.83183339999999 144 | MP:-25.5653360,30.52790960 145 | MQ:14.6415280,-61.0241740 146 | MR:21.007890,-10.9408350 147 | MS:32.35466790,-89.39852830 148 | MT:46.87968220,-110.36256580 149 | MU:-20.3484040,57.55215200000001 150 | MV:3.2027780,73.220680 151 | MW:-13.2543080,34.3015250 152 | MX:23.6345010,-102.5527840 153 | MY:4.2104840,101.9757660 154 | MZ:-18.6656950,35.5295620 155 | NA:-22.957640,18.490410 156 | NC:35.75957310,-79.01929969999999 157 | NE:41.49253740,-99.90181310 158 | NF:-29.0408350,167.9547120 159 | NG:9.0819990,8.675276999999999 160 | NI:12.8654160,-85.2072290 161 | NL:53.13550910,-57.66043640 162 | NO:48.10807699999999,15.80495580 163 | NP:28.3948570,84.12400799999999 164 | NR:-0.5227780,166.9315030 165 | NU:70.29977110,-83.10757690 166 | NZ:-40.9005570,174.8859710 167 | OM:21.5125830,55.9232550 168 | PA:41.20332160,-77.19452470 169 | PE:46.5107120,-63.41681359999999 170 | PF:-17.6797420,-149.4068430 171 | PG:5.263234100000001,100.48462270 172 | PH:12.8797210,121.7740170 173 | PK:30.3753210,69.34511599999999 174 | PL:51.9194380,19.1451360 175 | PM:46.9419360,-56.271110 176 | PN:-24.7036150,-127.4393080 177 | PR:-25.25208880,-52.02154150 178 | PS:31.9521620,35.2331540 179 | PT:39.39987199999999,-8.2244540 180 | PW:7.514979999999999,134.582520 181 | PY:-23.4425030,-58.4438320 182 | QA:25.3548260,51.1838840 183 | RE:-21.1151410,55.5363840 184 | RO:45.9431610,24.966760 185 | RU:61.524010,105.3187560 186 | RW:-1.9402780,29.8738880 187 | SA:23.8859420,45.0791620 188 | SB:-9.645709999999999,160.1561940 189 | SC:33.8360810,-81.16372450 190 | SD:43.96951480,-99.90181310 191 | SE:60.12816100000001,18.6435010 192 | SG:1.3520830,103.8198360 193 | SH:54.20907680,9.5889410 194 | SI:46.1512410,14.9954630 195 | SJ:-30.87245870,-68.52471489999999 196 | SK:52.93991590,-106.45086390 197 | SL:-33.87690180,-66.23671720 198 | SM:43.942360,12.4577770 199 | SN:14.4974010,-14.4523620 200 | SO:5.1521490,46.1996160 201 | SR:3.9193050,-56.0277830 202 | ST:0.186360,6.613080999999999 203 | SU:30.6516520,104.0759310 204 | SV:46.8181880,8.227511999999999 205 | SY:34.80207499999999,38.9968150 206 | SZ:-26.5225030,31.4658660 207 | TC:21.6940250,-71.7979280 208 | TD:15.4541660,18.7322070 209 | TF:-53.86711170,-69.2972140 210 | TG:8.6195430,0.8247820 211 | TH:15.8700320,100.9925410 212 | TJ:38.8610340,71.2760930 213 | TK:-8.967362999999999,-171.8558810 214 | TL:-8.8742170,125.7275390 215 | TM:38.9697190,59.5562780 216 | TN:35.51749130,-86.58044730 217 | TO:-11.40987370,-48.71914229999999 218 | TP:37.87774020,12.71351210 219 | TR:38.9637450,35.2433220 220 | TT:10.6918030,-61.2225030 221 | TV:45.78572920,12.19702880 222 | TW:23.697810,120.9605150 223 | TZ:-6.3690280,34.8888220 224 | UA:48.3794330,31.165580 225 | UG:1.3733330,32.2902750 226 | UK:55.3780510,-3.4359730 227 | UM:14.00451050,-176.70562750 228 | US:37.090240,-95.7128910 229 | UY:-32.5227790,-55.7658350 230 | UZ:41.3774910,64.5852620 231 | VA:37.43157340,-78.65689420 232 | VC:12.9843050,-61.2872280 233 | VE:6.423750,-66.589730 234 | VG:18.4206950,-64.6399680 235 | VI:18.3357650,-64.89633499999999 236 | VN:14.0583240,108.2771990 237 | VU:-15.3767060,166.9591580 238 | WF:-13.7687520,-177.1560970 239 | WS:-13.7590290,-172.1046290 240 | YE:15.5527270,48.5163880 241 | YT:64.28232740,-135.0 242 | YU:39.8408430,114.5889030 243 | ZA:-30.5594820,22.9375060 244 | ZM:-13.1338970,27.8493320 245 | ZR:51.80736570,5.70867610 246 | ZW:-19.0154380,29.1548570 247 | BIZ:42.91333330,44.17611110 248 | COM:45.81203170,9.085614999999999 249 | EDU:38.5333020,-121.7879780 250 | GOV:-12.27130120,136.82331380 251 | INT:36.13685970,-80.22767949999999 252 | MIL:60.164480,132.6396450 253 | NET:58.05874000000001,138.2498550 254 | ORG:30.06971249999999,-93.79811680 255 | PRO:41.82904250,-94.15938679999999 256 | AERO:54.85890260,10.38748130 257 | ARPA:39.70400050000001,45.12065270000001 258 | COOP:34.14125450,-118.37270070 259 | INFO:3.134430,101.686250 260 | NAME:27.70287990,85.32163220 261 | NATO:50.8762830,4.4219710 262 | -------------------------------------------------------------------------------- /nxapi/nxapi.json: -------------------------------------------------------------------------------- 1 | { 2 | "elastic" : { 3 | "host" : "127.0.0.1:9200", 4 | "use_ssl" : false, 5 | "index" : "nxapi", 6 | "number_of_shards" : "4", 7 | "number_of_replicas" : "0", 8 | "doctype" : "events", 9 | "default_ttl" : "7200", 10 | "max_size" : "1000", 11 | "version" : "5" 12 | }, 13 | "syslogd": { 14 | "host" : "0.0.0.0", 15 | "port" : "51400" 16 | }, 17 | "global_filters" : { 18 | "whitelisted" : "false" 19 | }, 20 | "global_warning_rules" : { 21 | "rule_ip" : ["<=", 10 ], 22 | "global_rule_ip_ratio" : ["<", 5] 23 | }, 24 | "global_success_rules" : { 25 | "global_rule_ip_ratio" : [">=", 10], 26 | "rule_ip" : [">=", 10] 27 | }, 28 | "global_deny_rules" : { 29 | "global_rule_ip_ratio" : ["<", 2] 30 | }, 31 | "naxsi" : { 32 | "rules_path" : "/etc/nginx/naxsi_core.rules", 33 | "template_path" : [ "tpl/"], 34 | "geoipdb_path" : "nx_datas/country2coords.txt" 35 | }, 36 | "output" : { 37 | "colors" : "true", 38 | "verbosity" : "5" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /nxapi/nxapi/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nbs-system/naxsi/a59462b8c2f9c2c0c0fbc3ceb287ee5d60b652c3/nxapi/nxapi/__init__.py -------------------------------------------------------------------------------- /nxapi/nxapi/nxtypificator.py: -------------------------------------------------------------------------------- 1 | ''' 2 | This modules generate types for url parameters. 3 | ''' 4 | import re 5 | import sys 6 | import collections 7 | from elasticsearch import Elasticsearch 8 | 9 | # Each regexp is a subset of the next one 10 | REGEXPS = [ 11 | [r'^$', 'empty'], 12 | [r'^[01]$', 'boolean'], 13 | [r'^\d+$', 'integer'], 14 | [r'^#[0-9a-f]+$', 'colour'], # hex + '#' 15 | [r'^[0-9a-f]+$', 'hexadecimal'], 16 | [r'^[0-9a-z]+$', 'alphanum'], 17 | [r'^https?://([0-9a-z-.]+\.)+[\w?+-=&/ ]+$', 'url'], # like http://pouet.net?hello=1&id=3 18 | [r'^\w+$', 'alphanumdash'], 19 | [r'^[0-9a-z?&=+_-]+$', 'url parameter'], 20 | [r'^[\w[] ,&=+-]+$', 'array'], 21 | [r'^[' + r'\s\w' + r'!$%^&*()[]:;@~#?/.,' + r']+$', 'plaintext'], 22 | [r'', 'none'], # untypables parameters 23 | ] 24 | 25 | 26 | class Typificator(object): 27 | ''' Classes that: 28 | 1. Fetch data from ES 29 | 2. Generate types for parameters 30 | 3. Returns a dict of dict 31 | ''' 32 | def __init__(self, es, cfg): 33 | self.es_instance = es 34 | self.cfg = cfg 35 | 36 | def __get_data(self, nb_samples=1e5): 37 | ''' Get (in a lazy way) data from the ES instance 38 | ''' 39 | data = set() 40 | position = 0 41 | size = min(10000, nb_samples) # if nb_samples if inferiour to our size, we'll get it in a single request. 42 | while nb_samples: 43 | if not data: 44 | body = {'query': {}} 45 | for k,v in self.cfg['global_filters'].iteritems(): 46 | body['query'].update({'match':{k:v}}) 47 | data = self.es_instance.search(index=self.cfg["elastic"]["index"], doc_type='events', 48 | size=size, from_=position, 49 | body=body) 50 | data = data['hits']['hits'] # we don't care about metadata 51 | if not data: # we got all data from ES 52 | return 53 | position += size 54 | nb_samples -= size 55 | for log in data: 56 | yield log['_source'] 57 | 58 | def get_rules(self, nb_samples=1e5): 59 | ''' Generate (in a lazy way) types for parameters 60 | ''' 61 | # Thank you defaultdict <3 62 | # rules = {zone1: {var1:0, var2:0}, zone2: {var6:0, ...}, ...} 63 | rules = collections.defaultdict(lambda: collections.defaultdict(int)) 64 | 65 | # Compile regexp for speed 66 | regexps = [re.compile(reg, re.IGNORECASE) for reg, _ in REGEXPS] 67 | 68 | for line in self.__get_data(nb_samples): 69 | try: # some events are fucked up^w^w empty 70 | #naxsi inverts the var_name and the content 71 | #when a rule match on var_name 72 | if line['zone'].endswith('|NAME'): 73 | continue 74 | zone = line['zone'] 75 | content = line['content'] 76 | var_name = line['var_name'] 77 | except KeyError as e: 78 | print 'Error with : {0} ({1})'.format(line, e) 79 | continue 80 | 81 | if not var_name: # No types for empty varnames. 82 | continue 83 | 84 | # Bump regexps until one matches 85 | # Since every regexp is a subset of the next one, 86 | # this works great. 87 | while not regexps[rules[zone][var_name]].match(content): 88 | rules[zone][var_name] += 1 89 | 90 | for zone, zone_data in rules.iteritems(): 91 | for var_name, index in zone_data.iteritems(): 92 | if index < len(REGEXPS) - 1: # Don't return untyped things 93 | yield [REGEXPS[index][0], REGEXPS[index][1], zone, var_name] 94 | 95 | 96 | if __name__ == '__main__': 97 | 98 | nb_samples = 1e6 if len(sys.argv) == 1 else int(sys.argv[1]) 99 | 100 | for rule in Typificator().get_rules(nb_samples): 101 | print 'TypeRule "rx:{0}" "msg:typed ({1}) parameter" "mz:${2}_VAR:{3}"'.format(rule[0], rule[1], rule[2], rule[3]) 102 | -------------------------------------------------------------------------------- /nxapi/requirements.txt: -------------------------------------------------------------------------------- 1 | elasticsearch==5.5.3 2 | GeoIP 3 | -------------------------------------------------------------------------------- /nxapi/sample/nginx.log: -------------------------------------------------------------------------------- 1 | 2019/04/17 11:37:19 [error] 11495#11495: *323360 NAXSI_EXLOG: ip=172.18.13.136&server=myexample.org&uri=%2F&id=1302&zone=ARGS&var_name=q&content=%3C%3E, client: 172.18.13.136, server: myexample.org, request: "GET /?q=%3C%3E HTTP/2.0", host: "myexample.org" 2 | 2019/04/17 11:37:19 [error] 11495#11495: *323360 NAXSI_FMT: ip=172.18.13.136&server=myexample.org&uri=/&learning=0&vers=0.56&total_processed=5&total_blocked=1&block=1&cscore0=$XSS&score0=8&zone0=ARGS&id0=1302&var_name0=q, client: 172.18.13.136, server: myexample.org, request: "GET /?q=%3C%3E HTTP/2.0", host: "myexample.org" 3 | 2019/04/17 11:37:46 [error] 11495#11495: *323360 NAXSI_EXLOG: ip=216.208.239.171&server=myexample.org&uri=%2F&id=1000&zone=ARGS&var_name=q&content=%22update%20table%20%28%29%22, client: 216.208.239.171, server: myexample.org, request: "GET /?q=%22update%20table%20()%22 HTTP/2.0", host: "myexample.org" 4 | 2019/04/17 11:37:46 [error] 11495#11495: *323360 NAXSI_FMT: ip=216.208.239.171&server=myexample.org&uri=/&learning=0&vers=0.56&total_processed=7&total_blocked=2&block=1&cscore0=$SQL&score0=8&zone0=ARGS&id0=1000&var_name0=q, client: 216.208.239.171, server: myexample.org, request: "GET /?q=%22update%20table%20()%22 HTTP/2.0", host: "myexample.org" 5 | -------------------------------------------------------------------------------- /nxapi/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from distutils.core import setup 4 | import os 5 | import glob 6 | import pprint 7 | 8 | f = {} 9 | data_files = [('/usr/local/nxapi/', ['nx_datas/country2coords.txt']), 10 | ('/usr/local/etc/', ['nxapi.json'])] 11 | #modules = [] 12 | for dirname, dirnames, filenames in os.walk('tpl/'): 13 | for filename in filenames: 14 | if filename.endswith(".tpl"): 15 | print dirname+"#"+filename 16 | if "/usr/local/nxapi/"+dirname not in f.keys(): 17 | 18 | f["/usr/local/nxapi/"+dirname] = [] 19 | 20 | f["/usr/local/nxapi/"+dirname].append(os.path.join(dirname, filename)) 21 | 22 | for z in f.keys(): 23 | data_files.append( (z, f[z])) 24 | 25 | 26 | setup(name='nxtool', 27 | version='1.0', 28 | description='Naxsi log parser, whitelist & report generator', 29 | author='Naxsi Dev Team', 30 | author_email='thibault.koechlin@nbs-system.com', 31 | url='http://github.com/nbs-system/naxsi', 32 | scripts=['nxtool.py'], 33 | packages=['nxapi'], 34 | data_files=data_files 35 | ) 36 | 37 | -------------------------------------------------------------------------------- /nxapi/tpl/APPS/google_analytics-ARGS.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "var_name" : "__utmz", 3 | "id" : "1009 or 1010 or 1005 or 1011", 4 | "zone" : "ARGS", 5 | "_statics" : { 6 | "id" : "1009,1010,1005,1011" 7 | }, 8 | "_msg" : "google analytics, __utmz var in ARGS" 9 | } 10 | 11 | 12 | -------------------------------------------------------------------------------- /nxapi/tpl/ARGS/precise-id.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_msg" : "A generic, precise wl tpl (url+var+id)", 3 | "zone" : "ARGS", 4 | "var_name" : "?", 5 | "id" : "?", 6 | "uri" : "?", 7 | "_warnings" : { "template_uri" : [ ">=", "5"]} 8 | } 9 | -------------------------------------------------------------------------------- /nxapi/tpl/ARGS/site-wide-id.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_msg" : "A generic, wide (id+zone) wl", 3 | "_success" : { "template_uri" : [ ">", "5"], 4 | "rule_uri" : [ ">", "5"]}, 5 | 6 | "_warnings" : { "rule_var_name" : [ "<=", "5" ], 7 | "rule_uri" : [ "<=", "5" ] }, 8 | "_deny" : { "rule_var_name" : [ "<", "10" ] }, 9 | "zone" : "ARGS", 10 | "id" : "?" 11 | } 12 | -------------------------------------------------------------------------------- /nxapi/tpl/ARGS/url-wide-id-NAME.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_msg" : "A generic whitelist, true for the whole uri", 3 | "zone" : "ARGS|NAME", 4 | "uri" : "?", 5 | "id" : "?", 6 | "_warnings" : { "template_uri" : [ ">", "5" ] }, 7 | "_success" : { "rule_var_name" : [ ">", "5" ] } 8 | } 9 | -------------------------------------------------------------------------------- /nxapi/tpl/ARGS/url-wide-id.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_msg" : "A generic whitelist, true for the whole uri", 3 | "zone" : "ARGS", 4 | "uri" : "?", 5 | "id" : "?", 6 | "_deny" : { "rule_var_name" : [ "<=", "3" ]}, 7 | "_success" : { "rule_var_name" : [ ">", "3" ]} 8 | } 9 | -------------------------------------------------------------------------------- /nxapi/tpl/BODY/precise-id.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_msg" : "A generic, precise wl tpl (url+var+id)", 3 | "zone" : "BODY", 4 | "var_name" : "?", 5 | "id" : "?", 6 | "uri" : "?", 7 | "_warnings" : { "template_uri" : [ "<", "5"], 8 | "template_var_name" : [ "<", "5"]} 9 | } 10 | -------------------------------------------------------------------------------- /nxapi/tpl/BODY/site-wide-id.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_msg" : "A generic, wide (id+zone) wl", 3 | "zone" : "BODY", 4 | "id" : "?", 5 | "_success" : { "template_uri" : [ ">", "5"], 6 | "template_var_name" : [ ">", "5"]}, 7 | "_deny" : { "rule_var_name" : [ "<", "10" ] } 8 | } 9 | -------------------------------------------------------------------------------- /nxapi/tpl/BODY/url-wide-id-BODY-NAME.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_msg" : "A generic whitelist, true for the whole uri, BODY|NAME", 3 | "zone" : "BODY|NAME", 4 | "uri" : "?", 5 | "id" : "?", 6 | "_warnings" : { "template_uri" : [ ">", "5"] } 7 | } 8 | -------------------------------------------------------------------------------- /nxapi/tpl/BODY/url-wide-id.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_warnings" : { "template_uri" : [ ">", "5"]}, 3 | "_deny" : {"rule_var_name" : ["<", "5"]}, 4 | "_msg" : "A generic whitelist, true for the whole uri", 5 | "zone" : "BODY", 6 | "uri" : "?", 7 | "id" : "?" 8 | } 9 | -------------------------------------------------------------------------------- /nxapi/tpl/BODY/var_name-wide-id.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "zone" : "BODY", 3 | "var_name" : "?", 4 | "id" : "?", 5 | "_msg" : "A generic rule to spot var-name specific WL", 6 | "_success" : { "rule_uri" : [ ">", "2"]}, 7 | "_deny" : { "rule_uri" : ["<", "2"]} 8 | } 9 | -------------------------------------------------------------------------------- /nxapi/tpl/HEADERS/cookies.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_success" : { "template_uri" : [ ">=", "5"] }, 3 | "zone" : "HEADERS", 4 | "var_name" : "cookie", 5 | "id" : "?"} 6 | -------------------------------------------------------------------------------- /nxapi/tpl/URI/global-url-0x_in_pircutres.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "id" : "1002", 3 | "zone" : "URL", 4 | "_success" : { "template_uri" : [ ">", "5"], 5 | "rule_uri" : [ ">", "5"]} 6 | } 7 | -------------------------------------------------------------------------------- /nxapi/tpl/URI/site-wide-id.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_success" : { "template_uri" : [ ">=", "5"], 3 | "rule_uri" : [ ">=", "5"]}, 4 | "zone" : "URL", 5 | "id" : "?" 6 | } 7 | 8 | -------------------------------------------------------------------------------- /nxapi/tpl/URI/url-wide-id.tpl: -------------------------------------------------------------------------------- 1 | { 2 | "_deny" : { "template_uri" : [ ">", "5" ] }, 3 | "uri" : "?", 4 | "zone" : "URL", 5 | "id" : "?" 6 | } 7 | -------------------------------------------------------------------------------- /t/02naxsi_bypass.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | plan tests => repeat_each(2) * blocks(); 12 | no_root_location(); 13 | no_long_string(); 14 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 15 | run_tests(); 16 | 17 | 18 | __DATA__ 19 | === TEST 1: Basic GET request 20 | --- main_config 21 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 22 | --- http_config 23 | include /tmp/naxsi_ut/naxsi_core.rules; 24 | --- config 25 | location / { 26 | #LearningMode; 27 | SecRulesEnabled; 28 | DeniedUrl "/RequestDenied"; 29 | CheckRule "$SQL >= 8" BLOCK; 30 | CheckRule "$RFI >= 8" BLOCK; 31 | CheckRule "$TRAVERSAL >= 4" BLOCK; 32 | CheckRule "$XSS >= 8" BLOCK; 33 | root $TEST_NGINX_SERVROOT/html/; 34 | index index.html index.htm; 35 | } 36 | location /RequestDenied { 37 | return 412; 38 | } 39 | --- request 40 | GET /?a=buibui 41 | --- error_code: 200 42 | === TEST 2: DENY : XSS bypass vector 1 (basic url encode) 43 | --- main_config 44 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 45 | --- http_config 46 | include /tmp/naxsi_ut/naxsi_core.rules; 47 | --- config 48 | location / { 49 | #LearningMode; 50 | SecRulesEnabled; 51 | DeniedUrl "/RequestDenied"; 52 | CheckRule "$SQL >= 8" BLOCK; 53 | CheckRule "$RFI >= 8" BLOCK; 54 | CheckRule "$TRAVERSAL >= 4" BLOCK; 55 | CheckRule "$XSS >= 8" BLOCK; 56 | root $TEST_NGINX_SERVROOT/html/; 57 | index index.html index.htm; 58 | } 59 | location /RequestDenied { 60 | return 412; 61 | } 62 | --- request 63 | GET /?a=%2f%3cSc%3E 64 | --- error_code: 412 65 | === TEST 2.1: DENY : XSS bypass vector 2 (\x encode) 66 | --- main_config 67 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 68 | --- http_config 69 | include /tmp/naxsi_ut/naxsi_core.rules; 70 | --- config 71 | location / { 72 | #LearningMode; 73 | SecRulesEnabled; 74 | DeniedUrl "/RequestDenied"; 75 | CheckRule "$SQL >= 8" BLOCK; 76 | CheckRule "$RFI >= 2" BLOCK; 77 | CheckRule "$TRAVERSAL >= 4" BLOCK; 78 | CheckRule "$XSS >= 8" BLOCK; 79 | root $TEST_NGINX_SERVROOT/html/; 80 | index index.html index.htm; 81 | } 82 | location /RequestDenied { 83 | return 412; 84 | } 85 | --- request 86 | GET /?a=\x2f\x3cSc\x3E 87 | --- error_code: 412 88 | 89 | === TEST 2.2: DENY : XSS bypass vector %00 (nullbyte) 90 | --- main_config 91 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 92 | --- http_config 93 | include /tmp/naxsi_ut/naxsi_core.rules; 94 | --- config 95 | location / { 96 | #LearningMode; 97 | SecRulesEnabled; 98 | DeniedUrl "/RequestDenied"; 99 | CheckRule "$SQL >= 8" BLOCK; 100 | CheckRule "$RFI >= 2" BLOCK; 101 | CheckRule "$TRAVERSAL >= 4" BLOCK; 102 | CheckRule "$XSS >= 8" BLOCK; 103 | root $TEST_NGINX_SERVROOT/html/; 104 | index index.html index.htm; 105 | } 106 | location /RequestDenied { 107 | return 412; 108 | } 109 | --- request 110 | GET /?a=a%00<%00script 111 | --- error_code: 412 112 | 113 | === TEST 2.3: DENY : XSS bypass vector %00 (nullbyte) URL 114 | --- main_config 115 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 116 | --- http_config 117 | include /tmp/naxsi_ut/naxsi_core.rules; 118 | --- config 119 | location / { 120 | #LearningMode; 121 | SecRulesEnabled; 122 | DeniedUrl "/RequestDenied"; 123 | CheckRule "$SQL >= 8" BLOCK; 124 | CheckRule "$RFI >= 2" BLOCK; 125 | CheckRule "$TRAVERSAL >= 4" BLOCK; 126 | CheckRule "$XSS >= 8" BLOCK; 127 | root $TEST_NGINX_SERVROOT/html/; 128 | index index.html index.htm; 129 | } 130 | location /RequestDenied { 131 | return 412; 132 | } 133 | --- request 134 | GET /a%00aaa 135 | --- error_code: 400 136 | === TEST 3.0: DENY : bypass vector ? (multi arg break) 137 | --- main_config 138 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 139 | --- http_config 140 | include /tmp/naxsi_ut/naxsi_core.rules; 141 | --- config 142 | location / { 143 | #LearningMode; 144 | SecRulesEnabled; 145 | DeniedUrl "/RequestDenied"; 146 | CheckRule "$SQL >= 8" BLOCK; 147 | CheckRule "$RFI >= 2" BLOCK; 148 | CheckRule "$TRAVERSAL >= 4" BLOCK; 149 | CheckRule "$XSS >= 8" BLOCK; 150 | root $TEST_NGINX_SERVROOT/html/; 151 | index index.html index.htm; 152 | } 153 | location /RequestDenied { 154 | return 412; 155 | } 156 | --- request 157 | GET /?a=a?= 8" BLOCK; 170 | CheckRule "$RFI >= 2" BLOCK; 171 | CheckRule "$TRAVERSAL >= 4" BLOCK; 172 | CheckRule "$XSS >= 8" BLOCK; 173 | root $TEST_NGINX_SERVROOT/html/; 174 | index index.html index.htm; 175 | } 176 | location /RequestDenied { 177 | return 412; 178 | } 179 | --- request 180 | GET /?a== 8" BLOCK; 193 | CheckRule "$RFI >= 2" BLOCK; 194 | CheckRule "$TRAVERSAL >= 4" BLOCK; 195 | CheckRule "$XSS >= 8" BLOCK; 196 | root $TEST_NGINX_SERVROOT/html/; 197 | index index.html index.htm; 198 | } 199 | location /RequestDenied { 200 | return 412; 201 | } 202 | --- request 203 | GET /?&&val 204 | --- error_code: 200 205 | === TEST 4.01: malformed URIs 206 | --- main_config 207 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 208 | --- http_config 209 | include /tmp/naxsi_ut/naxsi_core.rules; 210 | --- config 211 | location / { 212 | #LearningMode; 213 | SecRulesEnabled; 214 | DeniedUrl "/RequestDenied"; 215 | CheckRule "$SQL >= 8" BLOCK; 216 | CheckRule "$RFI >= 2" BLOCK; 217 | CheckRule "$TRAVERSAL >= 4" BLOCK; 218 | CheckRule "$XSS >= 8" BLOCK; 219 | root $TEST_NGINX_SERVROOT/html/; 220 | index index.html index.htm; 221 | } 222 | location /RequestDenied { 223 | return 412; 224 | } 225 | --- request 226 | GET /?&&va= 8" BLOCK; 239 | CheckRule "$RFI >= 2" BLOCK; 240 | CheckRule "$TRAVERSAL >= 4" BLOCK; 241 | CheckRule "$XSS >= 8" BLOCK; 242 | root $TEST_NGINX_SERVROOT/html/; 243 | index index.html index.htm; 244 | } 245 | location /RequestDenied { 246 | return 412; 247 | } 248 | --- request 249 | GET /?val&& 250 | --- error_code: 412 251 | === TEST 4.2: malformed URIs 252 | --- main_config 253 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 254 | --- http_config 255 | include /tmp/naxsi_ut/naxsi_core.rules; 256 | --- config 257 | location / { 258 | #LearningMode; 259 | SecRulesEnabled; 260 | DeniedUrl "/RequestDenied"; 261 | CheckRule "$SQL >= 8" BLOCK; 262 | CheckRule "$RFI >= 2" BLOCK; 263 | CheckRule "$TRAVERSAL >= 4" BLOCK; 264 | CheckRule "$XSS >= 8" BLOCK; 265 | root $TEST_NGINX_SERVROOT/html/; 266 | index index.html index.htm; 267 | } 268 | location /RequestDenied { 269 | return 412; 270 | } 271 | --- request 272 | GET /?&val 273 | --- error_code: 200 274 | === TEST 4.21: malformed URIs 275 | --- main_config 276 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 277 | --- http_config 278 | include /tmp/naxsi_ut/naxsi_core.rules; 279 | --- config 280 | location / { 281 | #LearningMode; 282 | SecRulesEnabled; 283 | DeniedUrl "/RequestDenied"; 284 | CheckRule "$SQL >= 8" BLOCK; 285 | CheckRule "$RFI >= 2" BLOCK; 286 | CheckRule "$TRAVERSAL >= 4" BLOCK; 287 | CheckRule "$XSS >= 8" BLOCK; 288 | root $TEST_NGINX_SERVROOT/html/; 289 | index index.html index.htm; 290 | } 291 | location /RequestDenied { 292 | return 412; 293 | } 294 | --- request 295 | GET /?&va= 8" BLOCK; 308 | CheckRule "$RFI >= 2" BLOCK; 309 | CheckRule "$TRAVERSAL >= 4" BLOCK; 310 | CheckRule "$XSS >= 8" BLOCK; 311 | root $TEST_NGINX_SERVROOT/html/; 312 | index index.html index.htm; 313 | } 314 | location /RequestDenied { 315 | return 412; 316 | } 317 | --- request 318 | GET /?val& 319 | --- error_code: 412 320 | === TEST 5.1: DENY : XSS bypass vector true nullbyte 321 | --- main_config 322 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 323 | --- http_config 324 | include /tmp/naxsi_ut/naxsi_core.rules; 325 | --- config 326 | location / { 327 | #LearningMode; 328 | SecRulesEnabled; 329 | DeniedUrl "/RequestDenied"; 330 | CheckRule "$SQL >= 8" BLOCK; 331 | CheckRule "$RFI >= 2" BLOCK; 332 | CheckRule "$TRAVERSAL >= 4" BLOCK; 333 | CheckRule "$XSS >= 8" BLOCK; 334 | root $TEST_NGINX_SERVROOT/html/; 335 | index index.html index.htm; 336 | } 337 | location /RequestDenied { 338 | return 412; 339 | } 340 | --- more_headers 341 | Content-Type: application/x-www-form-urlencoded 342 | --- request eval 343 | use URI::Escape; 344 | "POST /foobar 345 | a=a<><><>" 346 | --- error_code: 412 347 | -------------------------------------------------------------------------------- /t/03naxsi_profile.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | plan tests => repeat_each(2) * blocks(); 12 | no_root_location(); 13 | no_long_string(); 14 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 15 | run_tests(); 16 | 17 | 18 | __DATA__ 19 | === TEST 1: Basic GET request 20 | --- main_config 21 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 22 | --- http_config 23 | include /tmp/naxsi_ut/naxsi_core.rules; 24 | --- config 25 | location / { 26 | #LearningMode; 27 | SecRulesEnabled; 28 | DeniedUrl "/RequestDenied"; 29 | CheckRule "$SQL >= 8" BLOCK; 30 | CheckRule "$RFI >= 8" BLOCK; 31 | CheckRule "$TRAVERSAL >= 4" BLOCK; 32 | CheckRule "$XSS >= 8" BLOCK; 33 | root $TEST_NGINX_SERVROOT/html/; 34 | index index.html index.htm; 35 | } 36 | location /RequestDenied { 37 | return 412; 38 | } 39 | --- request 40 | GET /?a=buibui 41 | --- error_code: 200 42 | === TEST 2: DENY : Obvious GET XSS 43 | --- main_config 44 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 45 | --- http_config 46 | include /tmp/naxsi_ut/naxsi_core.rules; 47 | --- config 48 | location / { 49 | #LearningMode; 50 | SecRulesEnabled; 51 | DeniedUrl "/RequestDenied"; 52 | CheckRule "$SQL >= 8" BLOCK; 53 | CheckRule "$RFI >= 8" BLOCK; 54 | CheckRule "$TRAVERSAL >= 4" BLOCK; 55 | CheckRule "$XSS >= 8" BLOCK; 56 | root $TEST_NGINX_SERVROOT/html/; 57 | index index.html index.htm; 58 | } 59 | location /RequestDenied { 60 | return 412; 61 | } 62 | --- request 63 | GET /?a="> 64 | --- error_code: 412 65 | === TEST 2.1: DENY : Obvious RFI 66 | --- main_config 67 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 68 | --- http_config 69 | include /tmp/naxsi_ut/naxsi_core.rules; 70 | --- config 71 | location / { 72 | #LearningMode; 73 | SecRulesEnabled; 74 | DeniedUrl "/RequestDenied"; 75 | CheckRule "$SQL >= 8" BLOCK; 76 | CheckRule "$RFI >= 2" BLOCK; 77 | CheckRule "$TRAVERSAL >= 4" BLOCK; 78 | CheckRule "$XSS >= 8" BLOCK; 79 | root $TEST_NGINX_SERVROOT/html/; 80 | index index.html index.htm; 81 | } 82 | location /RequestDenied { 83 | return 412; 84 | } 85 | --- request 86 | GET /?a=http://evil.com/eva.txt 87 | --- error_code: 412 88 | === TEST 2.3: DENY : Obvious LFI 89 | --- main_config 90 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 91 | --- http_config 92 | include /tmp/naxsi_ut/naxsi_core.rules; 93 | --- config 94 | location / { 95 | #LearningMode; 96 | SecRulesEnabled; 97 | DeniedUrl "/RequestDenied"; 98 | CheckRule "$SQL >= 8" BLOCK; 99 | CheckRule "$RFI >= 2" BLOCK; 100 | CheckRule "$TRAVERSAL >= 4" BLOCK; 101 | CheckRule "$XSS >= 8" BLOCK; 102 | root $TEST_NGINX_SERVROOT/html/; 103 | index index.html index.htm; 104 | } 105 | location /RequestDenied { 106 | return 412; 107 | } 108 | --- request 109 | GET /?a=../../../../../bar.txt 110 | --- error_code: 412 111 | === TEST 3: OBVIOUS GET SQL INJECTION 112 | --- main_config 113 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 114 | --- http_config 115 | include /tmp/naxsi_ut/naxsi_core.rules; 116 | --- config 117 | location / { 118 | #LearningMode; 119 | SecRulesEnabled; 120 | DeniedUrl "/RequestDenied"; 121 | CheckRule "$SQL >= 8" BLOCK; 122 | CheckRule "$RFI >= 8" BLOCK; 123 | CheckRule "$TRAVERSAL >= 4" BLOCK; 124 | CheckRule "$XSS >= 8" BLOCK; 125 | root $TEST_NGINX_SERVROOT/html/; 126 | index index.html index.htm; 127 | } 128 | location /RequestDenied { 129 | return 412; 130 | } 131 | --- request 132 | GET /?a=1'+Or+'1'='1 133 | --- error_code: 412 134 | === TEST 3bis: OBVIOUS (quoteless) GET SQL INJECTION 135 | --- main_config 136 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 137 | --- http_config 138 | include /tmp/naxsi_ut/naxsi_core.rules; 139 | --- config 140 | location / { 141 | #LearningMode; 142 | SecRulesEnabled; 143 | DeniedUrl "/RequestDenied"; 144 | CheckRule "$SQL >= 8" BLOCK; 145 | CheckRule "$RFI >= 8" BLOCK; 146 | CheckRule "$TRAVERSAL >= 4" BLOCK; 147 | CheckRule "$XSS >= 8" BLOCK; 148 | root $TEST_NGINX_SERVROOT/html/; 149 | index index.html index.htm; 150 | } 151 | location /RequestDenied { 152 | return 412; 153 | } 154 | --- request 155 | GET /?a=1+UnIoN+SeLeCt+1 156 | --- error_code: 412 157 | -------------------------------------------------------------------------------- /t/06naxsi_weirds.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | use lib 'lib'; 5 | use Test::Nginx::Socket; 6 | 7 | plan tests => repeat_each(2) * blocks(); 8 | no_root_location(); 9 | no_long_string(); 10 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 11 | run_tests(); 12 | __DATA__ 13 | === WL TEST 1.0: weird request in URL 14 | --- main_config 15 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 16 | --- http_config 17 | include /tmp/naxsi_ut/naxsi_core.rules; 18 | --- config 19 | location / { 20 | SecRulesEnabled; 21 | DeniedUrl "/RequestDenied"; 22 | CheckRule "$SQL >= 8" BLOCK; 23 | CheckRule "$RFI >= 8" BLOCK; 24 | CheckRule "$TRAVERSAL >= 4" BLOCK; 25 | CheckRule "$XSS >= 8" BLOCK; 26 | root $TEST_NGINX_SERVROOT/html/; 27 | index index.html index.htm; 28 | } 29 | location /RequestDenied { 30 | return 412; 31 | } 32 | --- request 33 | GET /?&&&&a&&&&& 34 | --- error_code: 412 35 | 36 | === WL TEST 1.01: weird request in URL (wl on fullzone) 37 | --- main_config 38 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 39 | --- http_config 40 | include /tmp/naxsi_ut/naxsi_core.rules; 41 | --- config 42 | location / { 43 | SecRulesEnabled; 44 | DeniedUrl "/RequestDenied"; 45 | CheckRule "$SQL >= 8" BLOCK; 46 | CheckRule "$RFI >= 8" BLOCK; 47 | CheckRule "$TRAVERSAL >= 4" BLOCK; 48 | CheckRule "$XSS >= 8" BLOCK; 49 | root $TEST_NGINX_SERVROOT/html/; 50 | index index.html index.htm; 51 | BasicRule wl:12 "mz:ARGS"; 52 | } 53 | location /RequestDenied { 54 | return 412; 55 | } 56 | --- request 57 | GET /?&&&&a&&&&& 58 | --- error_code: 200 59 | 60 | === WL TEST 1.02: weird request in URL (wl on zone+URL) 61 | --- main_config 62 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 63 | --- http_config 64 | include /tmp/naxsi_ut/naxsi_core.rules; 65 | --- config 66 | location / { 67 | SecRulesEnabled; 68 | DeniedUrl "/RequestDenied"; 69 | CheckRule "$SQL >= 8" BLOCK; 70 | CheckRule "$RFI >= 8" BLOCK; 71 | CheckRule "$TRAVERSAL >= 4" BLOCK; 72 | CheckRule "$XSS >= 8" BLOCK; 73 | root $TEST_NGINX_SERVROOT/html/; 74 | index index.html index.htm; 75 | BasicRule wl:12 "mz:$URL:/|ARGS"; 76 | } 77 | location /RequestDenied { 78 | return 412; 79 | } 80 | --- request 81 | GET /?&&&&a&&&&& 82 | --- error_code: 200 83 | 84 | === WL TEST 1.03: weird request in URL (fail wl on zone+bad URL) 85 | --- main_config 86 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 87 | --- http_config 88 | include /tmp/naxsi_ut/naxsi_core.rules; 89 | --- config 90 | location / { 91 | SecRulesEnabled; 92 | DeniedUrl "/RequestDenied"; 93 | CheckRule "$SQL >= 8" BLOCK; 94 | CheckRule "$RFI >= 8" BLOCK; 95 | CheckRule "$TRAVERSAL >= 4" BLOCK; 96 | CheckRule "$XSS >= 8" BLOCK; 97 | root $TEST_NGINX_SERVROOT/html/; 98 | index index.html index.htm; 99 | BasicRule wl:12 "mz:$URL:/a|ARGS"; 100 | } 101 | location /RequestDenied { 102 | return 412; 103 | } 104 | --- request 105 | GET /?&&&&a&&&&& 106 | --- error_code: 412 107 | 108 | === WL TEST 1.04: weird request in URL (fail wl on bad zone+URL) 109 | --- main_config 110 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 111 | --- http_config 112 | include /tmp/naxsi_ut/naxsi_core.rules; 113 | --- config 114 | location / { 115 | SecRulesEnabled; 116 | DeniedUrl "/RequestDenied"; 117 | CheckRule "$SQL >= 8" BLOCK; 118 | CheckRule "$RFI >= 8" BLOCK; 119 | CheckRule "$TRAVERSAL >= 4" BLOCK; 120 | CheckRule "$XSS >= 8" BLOCK; 121 | root $TEST_NGINX_SERVROOT/html/; 122 | index index.html index.htm; 123 | BasicRule wl:12 "mz:$URL:/|URL"; 124 | } 125 | location /RequestDenied { 126 | return 412; 127 | } 128 | --- request 129 | GET /?&&&&a&&&&& 130 | --- error_code: 412 131 | -------------------------------------------------------------------------------- /t/08negative_whitelists.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | plan tests => repeat_each(2) * blocks(); 12 | no_root_location(); 13 | no_long_string(); 14 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 15 | run_tests(); 16 | 17 | __DATA__ 18 | 19 | === WL TEST 1.0 20 | --- main_config 21 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 22 | --- http_config 23 | include /tmp/naxsi_ut/naxsi_core.rules; 24 | MainRule negative "str:foobar" "msg:foobar test pattern" "mz:$ARGS_VAR:b" "s:$SQL:42" id:1999; 25 | --- config 26 | location / { 27 | #LearningMode; 28 | SecRulesEnabled; 29 | DeniedUrl "/RequestDenied"; 30 | CheckRule "$SQL >= 8" BLOCK; 31 | CheckRule "$RFI >= 8" BLOCK; 32 | CheckRule "$TRAVERSAL >= 4" BLOCK; 33 | CheckRule "$XSS >= 8" BLOCK; 34 | root $TEST_NGINX_SERVROOT/html/; 35 | index index.html index.htm; 36 | } 37 | location /RequestDenied { 38 | return 412; 39 | } 40 | --- request 41 | GET /?b=toto 42 | --- error_code: 412 43 | 44 | === WL TEST 1.01 45 | --- main_config 46 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 47 | --- http_config 48 | include /tmp/naxsi_ut/naxsi_core.rules; 49 | MainRule negative "str:foobar" "msg:foobar test pattern" "mz:$ARGS_VAR:b" "s:$SQL:42" id:1999; 50 | --- config 51 | location / { 52 | #LearningMode; 53 | SecRulesEnabled; 54 | DeniedUrl "/RequestDenied"; 55 | CheckRule "$SQL >= 8" BLOCK; 56 | CheckRule "$RFI >= 8" BLOCK; 57 | CheckRule "$TRAVERSAL >= 4" BLOCK; 58 | CheckRule "$XSS >= 8" BLOCK; 59 | root $TEST_NGINX_SERVROOT/html/; 60 | index index.html index.htm; 61 | } 62 | location /RequestDenied { 63 | return 412; 64 | } 65 | --- request 66 | GET /?b=foobar 67 | --- error_code: 200 68 | 69 | === WL TEST 1.03 70 | --- main_config 71 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 72 | --- http_config 73 | include /tmp/naxsi_ut/naxsi_core.rules; 74 | MainRule negative "str:foobar" "msg:foobar test pattern" "mz:$URL:/|$ARGS_VAR:b" "s:$SQL:42" id:1999; 75 | --- config 76 | location / { 77 | #LearningMode; 78 | SecRulesEnabled; 79 | DeniedUrl "/RequestDenied"; 80 | CheckRule "$SQL >= 8" BLOCK; 81 | CheckRule "$RFI >= 8" BLOCK; 82 | CheckRule "$TRAVERSAL >= 4" BLOCK; 83 | CheckRule "$XSS >= 8" BLOCK; 84 | root $TEST_NGINX_SERVROOT/html/; 85 | index index.html index.htm; 86 | } 87 | location /RequestDenied { 88 | return 412; 89 | } 90 | --- request 91 | GET /a?b=foobar 92 | --- error_code: 404 93 | 94 | === WL TEST 1.04 95 | --- main_config 96 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 97 | --- http_config 98 | include /tmp/naxsi_ut/naxsi_core.rules; 99 | MainRule negative "str:foobar" "msg:foobar test pattern" "mz:$URL:/a|$ARGS_VAR:b" "s:$SQL:42" id:1999; 100 | --- config 101 | location / { 102 | #LearningMode; 103 | SecRulesEnabled; 104 | DeniedUrl "/RequestDenied"; 105 | CheckRule "$SQL >= 8" BLOCK; 106 | CheckRule "$RFI >= 8" BLOCK; 107 | CheckRule "$TRAVERSAL >= 4" BLOCK; 108 | CheckRule "$XSS >= 8" BLOCK; 109 | root $TEST_NGINX_SERVROOT/html/; 110 | index index.html index.htm; 111 | } 112 | location /RequestDenied { 113 | return 412; 114 | } 115 | --- request 116 | GET /a?b=foobrar 117 | --- error_code: 412 118 | 119 | 120 | 121 | === WL TEST 2.0 122 | --- main_config 123 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 124 | --- http_config 125 | include /tmp/naxsi_ut/naxsi_core.rules; 126 | MainRule negative "rx:foobar" "msg:foobar test pattern" "mz:$URL:/a|$ARGS_VAR:b" "s:$SQL:42" id:1999; 127 | --- config 128 | location / { 129 | #LearningMode; 130 | SecRulesEnabled; 131 | DeniedUrl "/RequestDenied"; 132 | CheckRule "$SQL >= 8" BLOCK; 133 | CheckRule "$RFI >= 8" BLOCK; 134 | CheckRule "$TRAVERSAL >= 4" BLOCK; 135 | CheckRule "$XSS >= 8" BLOCK; 136 | root $TEST_NGINX_SERVROOT/html/; 137 | index index.html index.htm; 138 | } 139 | location /RequestDenied { 140 | return 412; 141 | } 142 | --- request 143 | GET /a?b=foobrar 144 | --- error_code: 412 145 | 146 | 147 | 148 | === WL TEST 2.01 149 | --- main_config 150 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 151 | --- http_config 152 | include /tmp/naxsi_ut/naxsi_core.rules; 153 | MainRule negative "rx:foobar" "msg:foobar test pattern" "mz:$URL:/a|$ARGS_VAR:b" "s:$SQL:42" id:1999; 154 | --- config 155 | location / { 156 | #LearningMode; 157 | SecRulesEnabled; 158 | DeniedUrl "/RequestDenied"; 159 | CheckRule "$SQL >= 8" BLOCK; 160 | CheckRule "$RFI >= 8" BLOCK; 161 | CheckRule "$TRAVERSAL >= 4" BLOCK; 162 | CheckRule "$XSS >= 8" BLOCK; 163 | root $TEST_NGINX_SERVROOT/html/; 164 | index index.html index.htm; 165 | } 166 | location /RequestDenied { 167 | return 412; 168 | } 169 | --- request 170 | GET /a?b=foobar 171 | --- error_code: 404 172 | 173 | 174 | === WL TEST 2.02 175 | --- main_config 176 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 177 | --- http_config 178 | include /tmp/naxsi_ut/naxsi_core.rules; 179 | MainRule negative "rx:^foobar" "msg:foobar test pattern" "mz:$URL:/a|$ARGS_VAR:b" "s:$SQL:42" id:1999; 180 | --- config 181 | location / { 182 | #LearningMode; 183 | SecRulesEnabled; 184 | DeniedUrl "/RequestDenied"; 185 | CheckRule "$SQL >= 8" BLOCK; 186 | CheckRule "$RFI >= 8" BLOCK; 187 | CheckRule "$TRAVERSAL >= 4" BLOCK; 188 | CheckRule "$XSS >= 8" BLOCK; 189 | root $TEST_NGINX_SERVROOT/html/; 190 | index index.html index.htm; 191 | } 192 | location /RequestDenied { 193 | return 412; 194 | } 195 | --- request 196 | GET /?b=foobar 197 | --- error_code: 200 198 | 199 | === WL TEST 2.03 200 | --- main_config 201 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 202 | --- http_config 203 | include /tmp/naxsi_ut/naxsi_core.rules; 204 | MainRule negative "rx:^foobar" "msg:foobar test pattern" "mz:$URL:/a|$ARGS_VAR:b" "s:$SQL:42" id:1999; 205 | --- config 206 | location / { 207 | #LearningMode; 208 | SecRulesEnabled; 209 | DeniedUrl "/RequestDenied"; 210 | CheckRule "$SQL >= 8" BLOCK; 211 | CheckRule "$RFI >= 8" BLOCK; 212 | CheckRule "$TRAVERSAL >= 4" BLOCK; 213 | CheckRule "$XSS >= 8" BLOCK; 214 | root $TEST_NGINX_SERVROOT/html/; 215 | index index.html index.htm; 216 | } 217 | location /RequestDenied { 218 | return 412; 219 | } 220 | --- request 221 | GET /a?b=rfoobar 222 | --- error_code: 412 223 | 224 | 225 | 226 | 227 | 228 | === WL TEST 2.04 229 | --- main_config 230 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 231 | --- http_config 232 | include /tmp/naxsi_ut/naxsi_core.rules; 233 | MainRule negative "rx:^foobar" "msg:foobar test pattern" "mz:$URL:/a|$ARGS_VAR:b" "s:$SQL:42" id:1999; 234 | --- config 235 | location / { 236 | #LearningMode; 237 | SecRulesEnabled; 238 | DeniedUrl "/RequestDenied"; 239 | CheckRule "$SQL >= 8" BLOCK; 240 | CheckRule "$RFI >= 8" BLOCK; 241 | CheckRule "$TRAVERSAL >= 4" BLOCK; 242 | CheckRule "$XSS >= 8" BLOCK; 243 | root $TEST_NGINX_SERVROOT/html/; 244 | index index.html index.htm; 245 | } 246 | location /RequestDenied { 247 | return 412; 248 | } 249 | --- request 250 | GET /a?b=foobar 251 | --- error_code: 404 252 | 253 | 254 | 255 | 256 | 257 | 258 | === WL TEST 2.05 259 | --- main_config 260 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 261 | --- http_config 262 | include /tmp/naxsi_ut/naxsi_core.rules; 263 | MainRule negative "rx:^foobar$" "msg:foobar test pattern" "mz:$URL:/a|$ARGS_VAR:b" "s:$SQL:42" id:1999; 264 | --- config 265 | location / { 266 | #LearningMode; 267 | SecRulesEnabled; 268 | DeniedUrl "/RequestDenied"; 269 | CheckRule "$SQL >= 8" BLOCK; 270 | CheckRule "$RFI >= 8" BLOCK; 271 | CheckRule "$TRAVERSAL >= 4" BLOCK; 272 | CheckRule "$XSS >= 8" BLOCK; 273 | root $TEST_NGINX_SERVROOT/html/; 274 | index index.html index.htm; 275 | } 276 | location /RequestDenied { 277 | return 412; 278 | } 279 | --- request 280 | GET /a?b=foobar 281 | --- error_code: 404 282 | 283 | 284 | 285 | 286 | 287 | === WL TEST 2.06 288 | --- main_config 289 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 290 | --- http_config 291 | include /tmp/naxsi_ut/naxsi_core.rules; 292 | MainRule negative "rx:^foobar$" "msg:foobar test pattern" "mz:$URL:/a|$ARGS_VAR:b" "s:$SQL:42" id:1999; 293 | --- config 294 | location / { 295 | #LearningMode; 296 | SecRulesEnabled; 297 | DeniedUrl "/RequestDenied"; 298 | CheckRule "$SQL >= 8" BLOCK; 299 | CheckRule "$RFI >= 8" BLOCK; 300 | CheckRule "$TRAVERSAL >= 4" BLOCK; 301 | CheckRule "$XSS >= 8" BLOCK; 302 | root $TEST_NGINX_SERVROOT/html/; 303 | index index.html index.htm; 304 | } 305 | location /RequestDenied { 306 | return 412; 307 | } 308 | --- request 309 | GET /a?b=foobara 310 | --- error_code: 412 311 | 312 | 313 | 314 | 315 | 316 | === WL TEST 2.07 317 | --- main_config 318 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 319 | --- http_config 320 | include /tmp/naxsi_ut/naxsi_core.rules; 321 | MainRule negative "rx:^[0-9]+$" "msg:foobar test pattern" "mz:$URL:/a|$ARGS_VAR:b" "s:$SQL:42" id:1999; 322 | --- config 323 | location / { 324 | #LearningMode; 325 | SecRulesEnabled; 326 | DeniedUrl "/RequestDenied"; 327 | CheckRule "$SQL >= 8" BLOCK; 328 | CheckRule "$RFI >= 8" BLOCK; 329 | CheckRule "$TRAVERSAL >= 4" BLOCK; 330 | CheckRule "$XSS >= 8" BLOCK; 331 | root $TEST_NGINX_SERVROOT/html/; 332 | index index.html index.htm; 333 | } 334 | location /RequestDenied { 335 | return 412; 336 | } 337 | --- request 338 | GET /a?b=foobara 339 | --- error_code: 412 340 | 341 | 342 | 343 | === WL TEST 2.08 344 | --- main_config 345 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 346 | --- http_config 347 | include /tmp/naxsi_ut/naxsi_core.rules; 348 | MainRule negative "rx:^[0-9]+$" "msg:foobar test pattern" "mz:$URL:/a|$ARGS_VAR:b" "s:$SQL:42" id:1999; 349 | --- config 350 | location / { 351 | #LearningMode; 352 | SecRulesEnabled; 353 | DeniedUrl "/RequestDenied"; 354 | CheckRule "$SQL >= 8" BLOCK; 355 | CheckRule "$RFI >= 8" BLOCK; 356 | CheckRule "$TRAVERSAL >= 4" BLOCK; 357 | CheckRule "$XSS >= 8" BLOCK; 358 | root $TEST_NGINX_SERVROOT/html/; 359 | index index.html index.htm; 360 | } 361 | location /RequestDenied { 362 | return 412; 363 | } 364 | --- request 365 | GET /a?b=1234 366 | --- error_code: 404 367 | 368 | 369 | 370 | 371 | 372 | 373 | -------------------------------------------------------------------------------- /t/12naxsi_argnames_extended.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | plan tests => repeat_each(2) * blocks(); 12 | no_root_location(); 13 | no_long_string(); 14 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 15 | run_tests(); 16 | __DATA__ 17 | === WL TEST 1.0: Obvious test in arg 18 | --- main_config 19 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 20 | --- http_config 21 | include /tmp/naxsi_ut/naxsi_core.rules; 22 | MainRule "str:foobar" "msg:foobar test pattern" "mz:ARGS" "s:$SQL:42" id:1999; 23 | --- config 24 | location / { 25 | #LearningMode; 26 | SecRulesEnabled; 27 | DeniedUrl "/RequestDenied"; 28 | CheckRule "$SQL >= 8" BLOCK; 29 | CheckRule "$RFI >= 8" BLOCK; 30 | CheckRule "$TRAVERSAL >= 4" BLOCK; 31 | CheckRule "$XSS >= 8" BLOCK; 32 | root $TEST_NGINX_SERVROOT/html/; 33 | index index.html index.htm; 34 | } 35 | location /RequestDenied { 36 | return 412; 37 | } 38 | --- request 39 | GET /?foobar=a 40 | --- error_code: 412 41 | 42 | === WL TEST 1.1: Obvious test in arg 43 | --- main_config 44 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 45 | --- http_config 46 | include /tmp/naxsi_ut/naxsi_core.rules; 47 | MainRule "str:foobar" "msg:foobar test pattern" "mz:ARGS" "s:$SQL:42" id:1999; 48 | --- config 49 | location / { 50 | #LearningMode; 51 | SecRulesEnabled; 52 | DeniedUrl "/RequestDenied"; 53 | CheckRule "$SQL >= 8" BLOCK; 54 | CheckRule "$RFI >= 8" BLOCK; 55 | CheckRule "$TRAVERSAL >= 4" BLOCK; 56 | CheckRule "$XSS >= 8" BLOCK; 57 | root $TEST_NGINX_SERVROOT/html/; 58 | index index.html index.htm; 59 | BasicRule wl:1999 "mz:$ARGS_VAR:foobar|NAME"; 60 | } 61 | location /RequestDenied { 62 | return 412; 63 | } 64 | --- request 65 | GET /?foobar=a 66 | --- error_code: 200 67 | 68 | -------------------------------------------------------------------------------- /t/13test.t: -------------------------------------------------------------------------------- 1 | # This File is used for broken tests. 2 | 3 | 4 | use lib 'lib'; 5 | use Test::Nginx::Socket; 6 | 7 | plan tests => repeat_each(2) * blocks(); 8 | no_root_location(); 9 | no_long_string(); 10 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 11 | run_tests(); 12 | __DATA__ 13 | # This one should actually return 200, but a hashtable collision happens 14 | === WL TEST 6.1: Whitelist provoking collision 15 | --- user_files 16 | >>> buixor 17 | eh yo 18 | >>> bla 19 | eh yo 20 | --- main_config 21 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 22 | --- http_config 23 | include /tmp/naxsi_ut/naxsi_core.rules; 24 | MainRule "str:1998" "msg:foobar test pattern" "mz:ARGS" "s:$SQL:42" id:1998; 25 | MainRule "str:1999" "msg:foobar test pattern #2" "mz:ARGS" "s:$SQL:42" id:1999; 26 | --- config 27 | location / { 28 | #LearningMode; 29 | SecRulesEnabled; 30 | DeniedUrl "/RequestDenied"; 31 | CheckRule "$SQL >= 8" BLOCK; 32 | CheckRule "$RFI >= 8" BLOCK; 33 | CheckRule "$TRAVERSAL >= 4" BLOCK; 34 | CheckRule "$XSS >= 8" BLOCK; 35 | root $TEST_NGINX_SERVROOT/html/; 36 | index index.html index.htm; 37 | BasicRule wl:1999 "mz:$URL:/bla|ARGS|NAME"; 38 | BasicRule wl:1998 "mz:$URL:/bla|ARGS"; 39 | } 40 | location /RequestDenied { 41 | return 412; 42 | } 43 | --- request 44 | GET /bla?blx=1998&1999=bla 45 | --- error_code: 200 46 | 47 | === WL TEST 6.2: Trigger multi-line logs 48 | --- user_files 49 | >>> buixor 50 | eh yo 51 | >>> bla 52 | eh yo 53 | --- main_config 54 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 55 | --- http_config 56 | include /tmp/naxsi_ut/naxsi_core.rules; 57 | MainRule "str:1998" "msg:foobar test pattern" "mz:ARGS" "s:$SQL:42" id:1998; 58 | MainRule "str:1999" "msg:foobar test pattern #2" "mz:ARGS" "s:$SQL:42" id:1999; 59 | --- config 60 | location / { 61 | LearningMode; 62 | SecRulesEnabled; 63 | DeniedUrl "/RequestDenied"; 64 | CheckRule "$SQL >= 8" BLOCK; 65 | CheckRule "$RFI >= 8" BLOCK; 66 | CheckRule "$TRAVERSAL >= 4" BLOCK; 67 | CheckRule "$XSS >= 8" BLOCK; 68 | root $TEST_NGINX_SERVROOT/html/; 69 | index index.html index.htm; 70 | BasicRule wl:1999 "mz:$URL:/bla|ARGS|NAME"; 71 | BasicRule wl:1998 "mz:$URL:/bla|ARGS"; 72 | } 73 | location /RequestDenied { 74 | return 412; 75 | } 76 | --- request 77 | GET /?AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA2=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA3=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA5=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA7=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA10=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA11=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA12=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA13=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA14=1998&AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA15=1998 78 | --- error_code: 200 79 | 80 | 81 | -------------------------------------------------------------------------------- /t/17case.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | plan tests => repeat_each(2) * blocks(); 12 | no_root_location(); 13 | no_long_string(); 14 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 15 | run_tests(); 16 | __DATA__ 17 | === WL TEST X.0: URL case sensitive wl 18 | --- main_config 19 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 20 | --- http_config 21 | include /tmp/naxsi_ut/naxsi_core.rules; 22 | MainRule "str:foobar" "msg:foobar test pattern" "mz:ARGS" "s:$SQL:42" id:1999; 23 | --- config 24 | location / { 25 | #LearningMode; 26 | SecRulesEnabled; 27 | DeniedUrl "/RequestDenied"; 28 | CheckRule "$SQL >= 8" BLOCK; 29 | CheckRule "$RFI >= 8" BLOCK; 30 | CheckRule "$TRAVERSAL >= 4" BLOCK; 31 | CheckRule "$XSS >= 8" BLOCK; 32 | root $TEST_NGINX_SERVROOT/html/; 33 | index index.html index.htm; 34 | BasicRule wl:1999,1000 "mz:$URL:/foobar/tableDropdown|URL"; 35 | } 36 | location /RequestDenied { 37 | return 412; 38 | } 39 | --- request 40 | GET /foobar/tableDropdown 41 | --- error_code: 404 42 | 43 | === WL TEST X.1: URL case sensitive wl 44 | --- main_config 45 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 46 | --- http_config 47 | include /tmp/naxsi_ut/naxsi_core.rules; 48 | MainRule "str:foobar" "msg:foobar test pattern" "mz:ARGS" "s:$SQL:42" id:1999; 49 | --- config 50 | location / { 51 | #LearningMode; 52 | SecRulesEnabled; 53 | DeniedUrl "/RequestDenied"; 54 | CheckRule "$SQL >= 8" BLOCK; 55 | CheckRule "$RFI >= 8" BLOCK; 56 | CheckRule "$TRAVERSAL >= 4" BLOCK; 57 | CheckRule "$XSS >= 8" BLOCK; 58 | root $TEST_NGINX_SERVROOT/html/; 59 | index index.html index.htm; 60 | BasicRule wl:1000 "mz:$URL:/wp-content/plugins/ultimate-tinymce/tableDropdown/editor_plugin.js|URL"; 61 | } 62 | location /RequestDenied { 63 | return 412; 64 | } 65 | --- request 66 | GET /wp-content/plugins/ultimate-tinymce/tableDropdown/editor_plugin.js 67 | --- error_code: 404 68 | === WL TEST 6.3: Whitelists trying to provoke collisions 69 | --- user_files 70 | >>> buixor 71 | eh yo 72 | >>> bla 73 | eh yo 74 | --- main_config 75 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 76 | --- http_config 77 | include /tmp/naxsi_ut/naxsi_core.rules; 78 | MainRule "str:1998" "msg:foobar test pattern" "mz:ARGS" "s:$SQL:42" id:1998; 79 | MainRule "str:1999" "msg:foobar test pattern #2" "mz:ARGS" "s:$SQL:42" id:1999; 80 | --- config 81 | location / { 82 | #LearningMode; 83 | SecRulesEnabled; 84 | DeniedUrl "/RequestDenied"; 85 | CheckRule "$SQL >= 8" BLOCK; 86 | CheckRule "$RFI >= 8" BLOCK; 87 | CheckRule "$TRAVERSAL >= 4" BLOCK; 88 | CheckRule "$XSS >= 8" BLOCK; 89 | root $TEST_NGINX_SERVROOT/html/; 90 | index index.html index.htm; 91 | BasicRule wl:1999 "mz:$ARGS_VAR:/bla"; 92 | BasicRule wl:1998 "mz:$URL:/bla|ARGS"; 93 | } 94 | location /RequestDenied { 95 | return 412; 96 | } 97 | --- request 98 | GET /bla?/bla=1999&bu=1998 99 | --- error_code: 200 100 | -------------------------------------------------------------------------------- /t/22libinjection-base.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | repeat_each(3); 12 | 13 | plan tests => repeat_each(1) * blocks(); 14 | no_root_location(); 15 | no_long_string(); 16 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 17 | run_tests(); 18 | 19 | 20 | __DATA__ 21 | === TEST 2 : Check libinjection_xss is disabled by default 22 | --- main_config 23 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 24 | --- http_config 25 | include /tmp/naxsi_ut/naxsi_core.rules; 26 | --- config 27 | location / { 28 | SecRulesEnabled; 29 | DeniedUrl "/RequestDenied"; 30 | CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; 31 | root $TEST_NGINX_SERVROOT/html/; 32 | index index.html index.htm; 33 | } 34 | location /RequestDenied { 35 | return 412; 36 | # return 412; 37 | } 38 | --- raw_request eval 39 | "GET /?x=a' onmouseover='alert(1) HTTP/1.0 40 | 41 | " 42 | --- error_code: 200 43 | 44 | 45 | === TEST 2.1 : Check libinjection_xss can be enabled 46 | --- main_config 47 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 48 | --- http_config 49 | include /tmp/naxsi_ut/naxsi_core.rules; 50 | --- config 51 | location / { 52 | SecRulesEnabled; 53 | LibInjectionXss; 54 | DeniedUrl "/RequestDenied"; 55 | CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; 56 | root $TEST_NGINX_SERVROOT/html/; 57 | index index.html index.htm; 58 | } 59 | location /RequestDenied { 60 | return 412; 61 | # return 412; 62 | } 63 | --- raw_request eval 64 | "GET /?x= HTTP/1.0 65 | 66 | " 67 | --- error_code: 412 68 | 69 | 70 | === TEST 2.2 : Check libinjection_xss can be enabled and dyn disabled 71 | --- main_config 72 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 73 | --- http_config 74 | include /tmp/naxsi_ut/naxsi_core.rules; 75 | --- config 76 | set $naxsi_flag_libinjection_xss 0; 77 | location / { 78 | SecRulesEnabled; 79 | LibInjectionXss; 80 | DeniedUrl "/RequestDenied"; 81 | CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; 82 | root $TEST_NGINX_SERVROOT/html/; 83 | index index.html index.htm; 84 | } 85 | location /RequestDenied { 86 | return 412; 87 | # return 412; 88 | } 89 | --- raw_request eval 90 | "GET /?x= HTTP/1.0 91 | 92 | " 93 | --- error_code: 200 94 | 95 | 96 | === TEST 2.3 : Check libinjection_xss can be disabled and dyn enabled 97 | --- main_config 98 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 99 | --- http_config 100 | include /tmp/naxsi_ut/naxsi_core.rules; 101 | --- config 102 | set $naxsi_flag_libinjection_xss 1; 103 | location / { 104 | SecRulesEnabled; 105 | DeniedUrl "/RequestDenied"; 106 | CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; 107 | root $TEST_NGINX_SERVROOT/html/; 108 | index index.html index.htm; 109 | } 110 | location /RequestDenied { 111 | return 412; 112 | # return 412; 113 | } 114 | --- raw_request eval 115 | "GET /?x= HTTP/1.0 116 | 117 | " 118 | --- error_code: 412 119 | 120 | === TEST 3 : Check libinjection_sql is disabled by default 121 | --- main_config 122 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 123 | --- http_config 124 | include /tmp/naxsi_ut/naxsi_core.rules; 125 | --- config 126 | location / { 127 | SecRulesEnabled; 128 | DeniedUrl "/RequestDenied"; 129 | CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; 130 | root $TEST_NGINX_SERVROOT/html/; 131 | index index.html index.htm; 132 | } 133 | location /RequestDenied { 134 | return 412; 135 | # return 412; 136 | } 137 | --- raw_request eval 138 | "GET /?x=1' OR '1'='1 HTTP/1.0 139 | 140 | " 141 | --- error_code: 200 142 | 143 | 144 | === TEST 3.1 : Check libinjection_sql can be enabled 145 | --- main_config 146 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 147 | --- http_config 148 | include /tmp/naxsi_ut/naxsi_core.rules; 149 | --- config 150 | location / { 151 | SecRulesEnabled; 152 | LibInjectionSql; 153 | DeniedUrl "/RequestDenied"; 154 | CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; 155 | root $TEST_NGINX_SERVROOT/html/; 156 | index index.html index.htm; 157 | } 158 | location /RequestDenied { 159 | return 412; 160 | # return 412; 161 | } 162 | --- raw_request eval 163 | "GET /?x=1' OR '1'='1 HTTP/1.0 164 | 165 | " 166 | --- error_code: 412 167 | 168 | 169 | === TEST 3.2 : Check libinjection_sql can be enabled and dyn disabled 170 | --- main_config 171 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 172 | --- http_config 173 | include /tmp/naxsi_ut/naxsi_core.rules; 174 | --- config 175 | set $naxsi_flag_libinjection_sql 0; 176 | location / { 177 | SecRulesEnabled; 178 | LibInjectionSql; 179 | DeniedUrl "/RequestDenied"; 180 | CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; 181 | root $TEST_NGINX_SERVROOT/html/; 182 | index index.html index.htm; 183 | } 184 | location /RequestDenied { 185 | return 412; 186 | # return 412; 187 | } 188 | --- raw_request eval 189 | "GET /?x=1' OR '1'='1 HTTP/1.0 190 | 191 | " 192 | --- error_code: 200 193 | === TEST 3.3 : Check libinjection_sql can be disabled and dyn enabled 194 | --- main_config 195 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 196 | --- http_config 197 | include /tmp/naxsi_ut/naxsi_core.rules; 198 | --- config 199 | set $naxsi_flag_libinjection_sql 1; 200 | location / { 201 | SecRulesEnabled; 202 | DeniedUrl "/RequestDenied"; 203 | CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; 204 | root $TEST_NGINX_SERVROOT/html/; 205 | index index.html index.htm; 206 | } 207 | location /RequestDenied { 208 | return 412; 209 | # return 412; 210 | } 211 | --- raw_request eval 212 | "GET /?x=1' OR '1'='1 HTTP/1.0 213 | 214 | " 215 | --- error_code: 412 216 | === TEST 4.0 : whitelist libinjection_sql 217 | --- main_config 218 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 219 | --- http_config 220 | include /tmp/naxsi_ut/naxsi_core.rules; 221 | --- config 222 | set $naxsi_flag_libinjection_sql 1; 223 | location / { 224 | BasicRule wl:17 "mz:$URL:/|$ARGS_VAR:x"; 225 | SecRulesEnabled; 226 | DeniedUrl "/RequestDenied"; 227 | CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; 228 | root $TEST_NGINX_SERVROOT/html/; 229 | index index.html index.htm; 230 | } 231 | location /RequestDenied { 232 | return 412; 233 | } 234 | --- raw_request eval 235 | "GET /?x=1' OR '1'='1 HTTP/1.0 236 | 237 | " 238 | --- error_code: 200 239 | === TEST 4.1 : whitelist libinjection_xss 240 | --- main_config 241 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 242 | --- http_config 243 | include /tmp/naxsi_ut/naxsi_core.rules; 244 | --- config 245 | set $naxsi_flag_libinjection_xss 1; 246 | location / { 247 | BasicRule wl:18 "mz:$URL:/|$ARGS_VAR:x"; 248 | SecRulesEnabled; 249 | DeniedUrl "/RequestDenied"; 250 | CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; 251 | root $TEST_NGINX_SERVROOT/html/; 252 | index index.html index.htm; 253 | } 254 | location /RequestDenied { 255 | return 412; 256 | } 257 | --- raw_request eval 258 | "GET /?x= HTTP/1.0 259 | 260 | " 261 | --- error_code: 200 262 | 263 | === TEST 4.2 : whitelist libinjection_xss (|NAME) 264 | --- main_config 265 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 266 | --- http_config 267 | include /tmp/naxsi_ut/naxsi_core.rules; 268 | --- config 269 | set $naxsi_flag_libinjection_xss 1; 270 | location / { 271 | BasicRule wl:18 "mz:$URL:/|ARGS|NAME"; 272 | SecRulesEnabled; 273 | DeniedUrl "/RequestDenied"; 274 | CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; 275 | root $TEST_NGINX_SERVROOT/html/; 276 | index index.html index.htm; 277 | } 278 | location /RequestDenied { 279 | return 412; 280 | } 281 | --- raw_request eval 282 | "GET /?=1 HTTP/1.0 283 | 284 | " 285 | --- error_code: 200 286 | 287 | 288 | === TEST 4.3 : whitelist libinjection_sql (|NAME) 289 | --- main_config 290 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 291 | --- http_config 292 | include /tmp/naxsi_ut/naxsi_core.rules; 293 | --- config 294 | set $naxsi_flag_libinjection_sql 1; 295 | location / { 296 | BasicRule wl:17 "mz:$URL:/|ARGS|NAME"; 297 | SecRulesEnabled; 298 | DeniedUrl "/RequestDenied"; 299 | CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; 300 | root $TEST_NGINX_SERVROOT/html/; 301 | index index.html index.htm; 302 | } 303 | location /RequestDenied { 304 | return 412; 305 | } 306 | --- raw_request eval 307 | "GET /?a/**/UNION+SELECT+1,1=1 HTTP/1.0 308 | 309 | " 310 | --- error_code: 200 311 | 312 | 313 | === TEST 4.3.1 : whitelist fail libinjection_sql (|NAME) 314 | --- main_config 315 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 316 | --- http_config 317 | include /tmp/naxsi_ut/naxsi_core.rules; 318 | --- config 319 | set $naxsi_flag_libinjection_sql 1; 320 | location / { 321 | BasicRule wl:17 "mz:$URL:/x|ARGS|NAME"; 322 | SecRulesEnabled; 323 | DeniedUrl "/RequestDenied"; 324 | CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; 325 | root $TEST_NGINX_SERVROOT/html/; 326 | index index.html index.htm; 327 | } 328 | location /RequestDenied { 329 | return 412; 330 | } 331 | --- raw_request eval 332 | "GET /?a' UNION SELECT 1,1=1 HTTP/1.0 333 | 334 | " 335 | --- error_code: 412 336 | 337 | 338 | === TEST 4.3.2 : whitelist fail libinjection_xss (|NAME) 339 | --- main_config 340 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 341 | --- http_config 342 | include /tmp/naxsi_ut/naxsi_core.rules; 343 | --- config 344 | set $naxsi_flag_libinjection_xss 1; 345 | location / { 346 | BasicRule wl:18 "mz:$URL:/x|ARGS|NAME"; 347 | SecRulesEnabled; 348 | DeniedUrl "/RequestDenied"; 349 | CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; 350 | root $TEST_NGINX_SERVROOT/html/; 351 | index index.html index.htm; 352 | } 353 | location /RequestDenied { 354 | return 412; 355 | } 356 | --- raw_request eval 357 | "GET /?a>=1 HTTP/1.0 358 | 359 | " 360 | --- error_code: 412 361 | 362 | 363 | -------------------------------------------------------------------------------- /t/25extra-coverage.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | repeat_each(3); 12 | 13 | plan tests => repeat_each(1) * blocks(); 14 | no_root_location(); 15 | no_long_string(); 16 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 17 | run_tests(); 18 | 19 | 20 | __DATA__ 21 | === TEST 1.0: Basic GET request, with allow rule (useless, just for coverage. ALLOW should be killed) 22 | --- main_config 23 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 24 | --- http_config 25 | include /tmp/naxsi_ut/naxsi_core.rules; 26 | MainRule id:4241 "str:ratata" "mz:ARGS" "s:$TEST:42"; 27 | #MainRule id:4242 "str:XXX" "s:$SQL:8" "mz:ARGS"; 28 | --- config 29 | location / { 30 | SecRulesEnabled; 31 | DeniedUrl "/RequestDenied"; 32 | CheckRule "$SQL >= 8" BLOCK; 33 | CheckRule "$RFI >= 8" BLOCK; 34 | CheckRule "$TRAVERSAL >= 4" BLOCK; 35 | CheckRule "$XSS >= 8" BLOCK; 36 | CheckRule "$TEST >= 8" ALLOW; 37 | 38 | root $TEST_NGINX_SERVROOT/html/; 39 | index index.html index.htm; 40 | } 41 | location /RequestDenied { 42 | return 412; 43 | # return 412; 44 | } 45 | --- request 46 | GET /?a=ratataXXX 47 | --- error_code: 200 48 | === TEST 1.1: Basic GET request, with global score increase 49 | --- main_config 50 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 51 | --- http_config 52 | include /tmp/naxsi_ut/naxsi_core.rules; 53 | MainRule id:4241 "str:ratata" "mz:ARGS" "s:42"; 54 | --- config 55 | location / { 56 | SecRulesEnabled; 57 | DeniedUrl "/RequestDenied"; 58 | CheckRule "$SQL >= 8" BLOCK; 59 | CheckRule "$RFI >= 8" BLOCK; 60 | CheckRule "$TRAVERSAL >= 4" BLOCK; 61 | CheckRule "$XSS >= 8" BLOCK; 62 | CheckRule "$TEST >= 8" ALLOW; 63 | 64 | root $TEST_NGINX_SERVROOT/html/; 65 | index index.html index.htm; 66 | } 67 | location /RequestDenied { 68 | return 412; 69 | # return 412; 70 | } 71 | --- request 72 | GET /?a=ratataXXX 73 | --- error_code: 200 74 | === TEST 1.2: rule on headers 75 | --- main_config 76 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 77 | --- http_config 78 | include /tmp/naxsi_ut/naxsi_core.rules; 79 | --- config 80 | location / { 81 | SecRulesEnabled; 82 | BasicRule id:4241 "str:ratata" "mz:HEADERS" "s:BLOCK"; 83 | DeniedUrl "/RequestDenied"; 84 | CheckRule "$SQL >= 8" BLOCK; 85 | CheckRule "$RFI >= 8" BLOCK; 86 | CheckRule "$TRAVERSAL >= 4" BLOCK; 87 | CheckRule "$XSS >= 8" BLOCK; 88 | CheckRule "$TEST >= 8" ALLOW; 89 | 90 | root $TEST_NGINX_SERVROOT/html/; 91 | index index.html index.htm; 92 | } 93 | location /RequestDenied { 94 | return 412; 95 | # return 412; 96 | } 97 | --- more_headers 98 | headertest: ratata 99 | --- request 100 | GET /?a=XXX 101 | --- error_code: 412 102 | === TEST 1.2: extensive log while targeting name 103 | --- main_config 104 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 105 | --- http_config 106 | include /tmp/naxsi_ut/naxsi_core.rules; 107 | --- config 108 | set $naxsi_extensive_log 1; 109 | location / { 110 | SecRulesEnabled; 111 | LearningMode; 112 | BasicRule id:4241 "str:ratata" "mz:ARGS" "s:BLOCK"; 113 | DeniedUrl "/RequestDenied"; 114 | CheckRule "$SQL >= 8" BLOCK; 115 | CheckRule "$RFI >= 8" BLOCK; 116 | CheckRule "$TRAVERSAL >= 4" BLOCK; 117 | CheckRule "$XSS >= 8" BLOCK; 118 | CheckRule "$TEST >= 8" ALLOW; 119 | 120 | root $TEST_NGINX_SERVROOT/html/; 121 | index index.html index.htm; 122 | } 123 | location /RequestDenied { 124 | return 412; 125 | # return 412; 126 | } 127 | --- request 128 | GET /?ratata=tututu 129 | --- error_code: 200 130 | === TEST 1.2: extensive log while targeting name 131 | --- main_config 132 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 133 | --- http_config 134 | include /tmp/naxsi_ut/naxsi_core.rules; 135 | --- config 136 | set $naxsi_extensive_log 1; 137 | location / { 138 | SecRulesEnabled; 139 | LearningMode; 140 | BasicRule id:4241 "str:ratata" "mz:ARGS" "s:LOG"; 141 | DeniedUrl "/RequestDenied"; 142 | CheckRule "$SQL >= 8" BLOCK; 143 | CheckRule "$RFI >= 8" BLOCK; 144 | CheckRule "$TRAVERSAL >= 4" BLOCK; 145 | CheckRule "$XSS >= 8" BLOCK; 146 | CheckRule "$TEST >= 8" ALLOW; 147 | 148 | root $TEST_NGINX_SERVROOT/html/; 149 | index index.html index.htm; 150 | } 151 | location /RequestDenied { 152 | return 412; 153 | # return 412; 154 | } 155 | --- request 156 | GET /?ratata=tututu 157 | --- error_code: 200 158 | === TEST 1.3: rule on url 159 | --- main_config 160 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 161 | --- http_config 162 | include /tmp/naxsi_ut/naxsi_core.rules; 163 | --- config 164 | set $naxsi_extensive_log 1; 165 | location / { 166 | SecRulesEnabled; 167 | BasicRule id:4241 "str:ratata" "mz:URL" "s:BLOCK"; 168 | DeniedUrl "/RequestDenied"; 169 | CheckRule "$SQL >= 8" BLOCK; 170 | CheckRule "$RFI >= 8" BLOCK; 171 | CheckRule "$TRAVERSAL >= 4" BLOCK; 172 | CheckRule "$XSS >= 8" BLOCK; 173 | CheckRule "$TEST >= 8" ALLOW; 174 | 175 | root $TEST_NGINX_SERVROOT/html/; 176 | index index.html index.htm; 177 | } 178 | location /RequestDenied { 179 | return 412; 180 | # return 412; 181 | } 182 | --- request 183 | GET /ratata?x=tututu 184 | --- error_code: 412 185 | === TEST 1.4: add post action as dynamic flag 186 | --- main_config 187 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 188 | --- http_config 189 | include /tmp/naxsi_ut/naxsi_core.rules; 190 | --- config 191 | set $naxsi_extensive_log 1; 192 | set $naxsi_flag_post_acton 1; 193 | location / { 194 | SecRulesEnabled; 195 | BasicRule id:4241 "str:ratata" "mz:URL" "s:BLOCK"; 196 | DeniedUrl "/RequestDenied"; 197 | CheckRule "$SQL >= 8" BLOCK; 198 | CheckRule "$RFI >= 8" BLOCK; 199 | CheckRule "$TRAVERSAL >= 4" BLOCK; 200 | CheckRule "$XSS >= 8" BLOCK; 201 | CheckRule "$TEST >= 8" ALLOW; 202 | 203 | root $TEST_NGINX_SERVROOT/html/; 204 | index index.html index.htm; 205 | } 206 | location /RequestDenied { 207 | return 412; 208 | # return 412; 209 | } 210 | --- request 211 | GET /ratata?x=tututu 212 | --- error_code: 412 213 | === TEST 1.5.0: HEADER_VAR_X 214 | --- main_config 215 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 216 | --- http_config 217 | MainRule id:4241 "str:ratata" "mz:$HEADERS_VAR_X:ruuu" "s:BLOCK"; 218 | include /tmp/naxsi_ut/naxsi_core.rules; 219 | --- config 220 | set $naxsi_extensive_log 1; 221 | set $naxsi_flag_post_acton 1; 222 | location / { 223 | SecRulesEnabled; 224 | # BasicRule id:4241 "str:ratata" "mz:URL" "s:BLOCK"; 225 | DeniedUrl "/RequestDenied"; 226 | CheckRule "$SQL >= 8" BLOCK; 227 | CheckRule "$RFI >= 8" BLOCK; 228 | CheckRule "$TRAVERSAL >= 4" BLOCK; 229 | CheckRule "$XSS >= 8" BLOCK; 230 | CheckRule "$TEST >= 8" ALLOW; 231 | 232 | root $TEST_NGINX_SERVROOT/html/; 233 | index index.html index.htm; 234 | } 235 | location /RequestDenied { 236 | return 412; 237 | # return 412; 238 | } 239 | --- more_headers 240 | ruuu: ratata1 241 | --- request 242 | GET /ratata?x=tututu 243 | --- error_code: 412 244 | === TEST 1.5.1: HEADER_VAR_X 245 | --- main_config 246 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 247 | --- http_config 248 | MainRule id:4241 "str:ratata" "mz:$HEADERS_VAR_X:ruuu|$URL_X:^/fufu" "s:BLOCK"; 249 | include /tmp/naxsi_ut/naxsi_core.rules; 250 | --- config 251 | set $naxsi_extensive_log 1; 252 | set $naxsi_flag_post_acton 1; 253 | location / { 254 | SecRulesEnabled; 255 | # BasicRule id:4241 "str:ratata" "mz:URL" "s:BLOCK"; 256 | DeniedUrl "/RequestDenied"; 257 | CheckRule "$SQL >= 8" BLOCK; 258 | CheckRule "$RFI >= 8" BLOCK; 259 | CheckRule "$TRAVERSAL >= 4" BLOCK; 260 | CheckRule "$XSS >= 8" BLOCK; 261 | CheckRule "$TEST >= 8" ALLOW; 262 | 263 | root $TEST_NGINX_SERVROOT/html/; 264 | index index.html index.htm; 265 | } 266 | location /RequestDenied { 267 | return 412; 268 | # return 412; 269 | } 270 | --- more_headers 271 | ruuu: ratata1 272 | --- request 273 | GET /fufu?x=tututu 274 | --- error_code: 412 275 | === TEST 1.5.2: HEADER_VAR_X 276 | --- main_config 277 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 278 | --- http_config 279 | MainRule id:4241 "str:ratata" "mz:$HEADERS_VAR_X:ruuu|$URL_X:^/fufu" "s:BLOCK"; 280 | include /tmp/naxsi_ut/naxsi_core.rules; 281 | --- config 282 | set $naxsi_extensive_log 1; 283 | set $naxsi_flag_post_acton 1; 284 | location / { 285 | SecRulesEnabled; 286 | # BasicRule id:4241 "str:ratata" "mz:URL" "s:BLOCK"; 287 | DeniedUrl "/RequestDenied"; 288 | CheckRule "$SQL >= 8" BLOCK; 289 | CheckRule "$RFI >= 8" BLOCK; 290 | CheckRule "$TRAVERSAL >= 4" BLOCK; 291 | CheckRule "$XSS >= 8" BLOCK; 292 | CheckRule "$TEST >= 8" ALLOW; 293 | 294 | root $TEST_NGINX_SERVROOT/html/; 295 | index index.html index.htm; 296 | } 297 | location /RequestDenied { 298 | return 412; 299 | # return 412; 300 | } 301 | --- more_headers 302 | ruuu: ratata1 303 | --- request 304 | GET /fuf?x=tututu 305 | --- error_code: 404 306 | === TEST 1.6.0: URL + URL wl 307 | --- main_config 308 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 309 | --- http_config 310 | MainRule id:4241 "str:ratata" "mz:URL" "s:BLOCK"; 311 | include /tmp/naxsi_ut/naxsi_core.rules; 312 | --- config 313 | set $naxsi_extensive_log 1; 314 | set $naxsi_flag_post_acton 1; 315 | location / { 316 | SecRulesEnabled; 317 | BasicRule wl:4241 "mz:URL"; 318 | DeniedUrl "/RequestDenied"; 319 | CheckRule "$SQL >= 8" BLOCK; 320 | CheckRule "$RFI >= 8" BLOCK; 321 | CheckRule "$TRAVERSAL >= 4" BLOCK; 322 | CheckRule "$XSS >= 8" BLOCK; 323 | CheckRule "$TEST >= 8" ALLOW; 324 | 325 | root $TEST_NGINX_SERVROOT/html/; 326 | index index.html index.htm; 327 | } 328 | location /RequestDenied { 329 | return 412; 330 | # return 412; 331 | } 332 | --- request 333 | GET /ratata 334 | --- error_code: 404 335 | === TEST 1.6.1: URL + URL wl 336 | --- main_config 337 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 338 | --- http_config 339 | MainRule id:4241 "str:ratata" "mz:URL" "s:BLOCK"; 340 | include /tmp/naxsi_ut/naxsi_core.rules; 341 | --- config 342 | set $naxsi_extensive_log 1; 343 | set $naxsi_flag_post_acton 1; 344 | location / { 345 | SecRulesEnabled; 346 | BasicRule wl:4241 "mz:BODY"; 347 | DeniedUrl "/RequestDenied"; 348 | CheckRule "$SQL >= 8" BLOCK; 349 | CheckRule "$RFI >= 8" BLOCK; 350 | CheckRule "$TRAVERSAL >= 4" BLOCK; 351 | CheckRule "$XSS >= 8" BLOCK; 352 | CheckRule "$TEST >= 8" ALLOW; 353 | 354 | root $TEST_NGINX_SERVROOT/html/; 355 | index index.html index.htm; 356 | } 357 | location /RequestDenied { 358 | return 412; 359 | # return 412; 360 | } 361 | --- request 362 | GET /ratata 363 | --- error_code: 412 364 | 365 | 366 | 367 | 368 | 369 | -------------------------------------------------------------------------------- /t/27libinjection-blacklist.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | repeat_each(3); 12 | 13 | plan tests => repeat_each(1) * blocks(); 14 | no_root_location(); 15 | no_long_string(); 16 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 17 | run_tests(); 18 | 19 | 20 | __DATA__ 21 | === TEST 1 : Enable libinjection s:DROP on named var 22 | --- main_config 23 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 24 | --- http_config 25 | include /tmp/naxsi_ut/naxsi_core.rules; 26 | MainRule "d:libinj_xss" "s:DROP" "mz:$ARGS_VAR:ruuu" id:41231; 27 | --- config 28 | location / { 29 | SecRulesEnabled; 30 | LearningMode; 31 | DeniedUrl "/RequestDenied"; 32 | root $TEST_NGINX_SERVROOT/html/; 33 | index index.html index.htm; 34 | } 35 | location /RequestDenied { 36 | return 412; 37 | } 38 | --- raw_request eval 39 | "GET /?ruuu=a' onmouseover='alert(1) HTTP/1.0 40 | 41 | " 42 | --- error_code: 412 43 | === TEST 1.1 : Enable libinjection s:DROP on (bad) named var 44 | --- main_config 45 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 46 | --- http_config 47 | include /tmp/naxsi_ut/naxsi_core.rules; 48 | MainRule "d:libinj_xss" "s:DROP" "mz:$ARGS_VAR:ruuuu" id:41231; 49 | --- config 50 | location / { 51 | SecRulesEnabled; 52 | LearningMode; 53 | DeniedUrl "/RequestDenied"; 54 | root $TEST_NGINX_SERVROOT/html/; 55 | index index.html index.htm; 56 | } 57 | location /RequestDenied { 58 | return 412; 59 | } 60 | --- raw_request eval 61 | "GET /?ruuu=a' onmouseover='alert(1) HTTP/1.0 62 | 63 | " 64 | --- error_code: 200 65 | === TEST 1.2 : Enable libinjection s:DROP on (bad) named var 66 | --- main_config 67 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 68 | --- http_config 69 | include /tmp/naxsi_ut/naxsi_core.rules; 70 | MainRule "d:libinj_xss" "s:DROP" "mz:$ARGS_VAR:ruu" id:41231; 71 | --- config 72 | location / { 73 | SecRulesEnabled; 74 | LearningMode; 75 | DeniedUrl "/RequestDenied"; 76 | root $TEST_NGINX_SERVROOT/html/; 77 | index index.html index.htm; 78 | } 79 | location /RequestDenied { 80 | return 412; 81 | } 82 | --- raw_request eval 83 | "GET /?ruuu=a' onmouseover='alert(1) HTTP/1.0 84 | 85 | " 86 | --- error_code: 200 87 | === TEST 2.1 : Enable libinjection s:$FOOBAR on named var 88 | --- main_config 89 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 90 | --- http_config 91 | include /tmp/naxsi_ut/naxsi_core.rules; 92 | MainRule "d:libinj_xss" "s:$FOOBAR:8" "mz:$ARGS_VAR_X:^fuu[0-9]+$" id:41231; 93 | --- config 94 | location / { 95 | SecRulesEnabled; 96 | LearningMode; 97 | CheckRule "$FOOBAR >= 8" DROP; 98 | DeniedUrl "/RequestDenied"; 99 | root $TEST_NGINX_SERVROOT/html/; 100 | index index.html index.htm; 101 | } 102 | location /RequestDenied { 103 | return 412; 104 | } 105 | --- raw_request eval 106 | "GET /?fuu4242424=a' onmouseover='alert(1) HTTP/1.0 107 | 108 | " 109 | --- error_code: 412 110 | 111 | === TEST 3.0 : Enable libinjection (sql) s:DROP on named var+url 112 | --- main_config 113 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 114 | --- http_config 115 | include /tmp/naxsi_ut/naxsi_core.rules; 116 | MainRule "d:libinj_sql" "s:$FOOBAR:8" "mz:$ARGS_VAR_X:^fuu[0-9]+$|$URL_X:^/foobar/$" id:41231; 117 | --- config 118 | location / { 119 | SecRulesEnabled; 120 | LearningMode; 121 | CheckRule "$FOOBAR >= 8" DROP; 122 | DeniedUrl "/RequestDenied"; 123 | root $TEST_NGINX_SERVROOT/html/; 124 | index index.html index.htm; 125 | } 126 | location /RequestDenied { 127 | return 412; 128 | } 129 | --- raw_request eval 130 | "GET /foobar/?fuu4242424=1' OR '1'='1 HTTP/1.0 131 | 132 | " 133 | --- error_code: 412 134 | === TEST 3.0 : Enable libinjection (sql) s:DROP on named var+url (not a valid sqli) 135 | --- main_config 136 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 137 | --- http_config 138 | include /tmp/naxsi_ut/naxsi_core.rules; 139 | MainRule "d:libinj_sql" "s:$FOOBAR:8" "mz:$ARGS_VAR_X:^fuu[0-9]+$|$URL_X:^/foobar/$" id:41231; 140 | --- config 141 | location / { 142 | SecRulesEnabled; 143 | LearningMode; 144 | CheckRule "$FOOBAR >= 8" DROP; 145 | DeniedUrl "/RequestDenied"; 146 | root $TEST_NGINX_SERVROOT/html/; 147 | index index.html index.htm; 148 | } 149 | location /RequestDenied { 150 | return 412; 151 | } 152 | --- raw_request eval 153 | "GET /foobar/?fuu4242424=1' OR \"1\"= HTTP/1.0 154 | 155 | " 156 | --- error_code: 404 157 | 158 | -------------------------------------------------------------------------------- /t/30regr.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | repeat_each(3); 12 | 13 | plan tests => repeat_each(1) * blocks(); 14 | no_root_location(); 15 | no_long_string(); 16 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 17 | run_tests(); 18 | 19 | 20 | __DATA__ 21 | === TEST 1: rule target body|name 22 | --- main_config 23 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 24 | --- http_config 25 | include /tmp/naxsi_ut/naxsi_core.rules; 26 | --- config 27 | location / { 28 | SecRulesEnabled; 29 | LearningMode; 30 | BasicRule id:100054 "msg:Weird binary content" "rx:[^-0-9a-z_+.\[\]]" "mz:BODY|NAME" "s:$TEST_LOG:8"; 31 | DeniedUrl "/RequestDenied"; 32 | CheckRule "$SQL >= 8" BLOCK; 33 | CheckRule "$RFI >= 8" BLOCK; 34 | CheckRule "$TRAVERSAL >= 4" BLOCK; 35 | CheckRule "$XSS >= 8" BLOCK; 36 | CheckRule "$TEST_LOG >= 8" DROP; 37 | root $TEST_NGINX_SERVROOT/html/; 38 | index index.html index.htm; 39 | error_page 405 = $uri; 40 | } 41 | location /RequestDenied { 42 | return 412; 43 | # return 412; 44 | } 45 | --- more_headers 46 | Content-Type: application/x-www-form-urlencoded 47 | --- request eval 48 | use URI::Escape; 49 | "POST / 50 | 9p7jslna,ire(ul\)v`2q8u]h)bfuzpcgsa_3`s\twfw)gy)\%3Fc=]@&foo2=bar2" 51 | --- error_code: 412 52 | 53 | === TEST 1: rule target body|name 54 | --- main_config 55 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 56 | --- http_config 57 | include /tmp/naxsi_ut/naxsi_core.rules; 58 | --- config 59 | location / { 60 | SecRulesEnabled; 61 | LearningMode; 62 | BasicRule id:100054 "msg:Weird binary content" "rx:[^-0-9a-z_+.\[\]]" "mz:BODY|NAME" "s:$TEST_LOG:8"; 63 | DeniedUrl "/RequestDenied"; 64 | CheckRule "$SQL >= 8" BLOCK; 65 | CheckRule "$RFI >= 8" BLOCK; 66 | CheckRule "$TRAVERSAL >= 4" BLOCK; 67 | CheckRule "$XSS >= 8" BLOCK; 68 | CheckRule "$TEST_LOG >= 8" DROP; 69 | root $TEST_NGINX_SERVROOT/html/; 70 | index index.html index.htm; 71 | error_page 405 = $uri; 72 | } 73 | location /RequestDenied { 74 | return 412; 75 | # return 412; 76 | } 77 | --- more_headers 78 | Content-Type: application/x-www-form-urlencoded 79 | --- request eval 80 | use URI::Escape; 81 | "POST / 82 | 9p7jslna,ire(ul\)v`2q8u]h)bfuzpcgsa_3`s\twfw)gy)\%3Fc=ww&foo2=bar2" 83 | --- error_code: 412 84 | 85 | 86 | === TEST 1: rule target body|name 87 | --- main_config 88 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 89 | --- http_config 90 | include /tmp/naxsi_ut/naxsi_core.rules; 91 | --- config 92 | location / { 93 | SecRulesEnabled; 94 | LearningMode; 95 | BasicRule id:100054 "msg:Weird binary content" "rx:[^-0-9a-z_+.\[\]]" "mz:BODY|NAME" "s:$TEST_LOG:8"; 96 | DeniedUrl "/RequestDenied"; 97 | CheckRule "$SQL >= 8" BLOCK; 98 | CheckRule "$RFI >= 8" BLOCK; 99 | CheckRule "$TRAVERSAL >= 4" BLOCK; 100 | CheckRule "$XSS >= 8" BLOCK; 101 | CheckRule "$TEST_LOG >= 8" DROP; 102 | root $TEST_NGINX_SERVROOT/html/; 103 | index index.html index.htm; 104 | error_page 405 = $uri; 105 | } 106 | location /RequestDenied { 107 | return 412; 108 | # return 412; 109 | } 110 | --- more_headers 111 | Content-Type: application/x-www-form-urlencoded 112 | --- request eval 113 | use URI::Escape; 114 | "POST / 115 | ww=9p7jslna,ire(ul\)v`2q8u]h)bfuzpcgsa_3`s\twfw)gy)\%3Fc&foo2=bar2" 116 | --- error_code: 200 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /t/31norules.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | repeat_each(3); 12 | 13 | plan tests => repeat_each(1) * blocks(); 14 | no_root_location(); 15 | no_long_string(); 16 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 17 | run_tests(); 18 | 19 | 20 | __DATA__ 21 | === TEST 1: Basic GET request with no rules, drop 22 | --- main_config 23 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 24 | --- config 25 | location / { 26 | SecRulesEnabled; 27 | LearningMode; 28 | DeniedUrl "/RequestDenied"; 29 | CheckRule "$SQL >= 8" BLOCK; 30 | CheckRule "$RFI >= 8" BLOCK; 31 | CheckRule "$TRAVERSAL >= 4" BLOCK; 32 | CheckRule "$XSS >= 8" BLOCK; 33 | LibInjectionXss; 34 | CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; 35 | LibInjectionSql; 36 | CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; 37 | 38 | root $TEST_NGINX_SERVROOT/html/; 39 | index index.html index.htm; 40 | } 41 | location /RequestDenied { 42 | return 412; 43 | } 44 | --- request 45 | GET /?a=buibui 46 | --- error_code: 412 47 | === TEST 1.1: Basic GET request with no rules, whitelist the special rule. 48 | --- main_config 49 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 50 | --- config 51 | location / { 52 | SecRulesEnabled; 53 | BasicRule wl:19; 54 | LearningMode; 55 | DeniedUrl "/RequestDenied"; 56 | CheckRule "$SQL >= 8" BLOCK; 57 | CheckRule "$RFI >= 8" BLOCK; 58 | CheckRule "$TRAVERSAL >= 4" BLOCK; 59 | CheckRule "$XSS >= 8" BLOCK; 60 | LibInjectionXss; 61 | CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; 62 | LibInjectionSql; 63 | CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; 64 | 65 | root $TEST_NGINX_SERVROOT/html/; 66 | index index.html index.htm; 67 | } 68 | location /RequestDenied { 69 | return 412; 70 | } 71 | --- request 72 | GET /?a=buibui 73 | --- error_code: 200 74 | -------------------------------------------------------------------------------- /t/32utf8.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | 4 | # A AJOUTER : 5 | # TEST CASE AVEC UNE REGLE SUR UN HEADER GENERIQUE 6 | # La même sur des arguments :) 7 | 8 | use lib 'lib'; 9 | use Test::Nginx::Socket; 10 | 11 | repeat_each(3); 12 | 13 | plan tests => repeat_each(1) * blocks(); 14 | no_root_location(); 15 | no_long_string(); 16 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 17 | run_tests(); 18 | 19 | 20 | __DATA__ 21 | === TEST 2.0: utf8 overlong 22 | --- main_config 23 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 24 | --- http_config 25 | include /tmp/naxsi_ut/naxsi_core.rules; 26 | --- config 27 | location / { 28 | SecRulesEnabled; 29 | DeniedUrl "/RequestDenied"; 30 | CheckRule "$SQL >= 8" BLOCK; 31 | CheckRule "$RFI >= 8" BLOCK; 32 | CheckRule "$TRAVERSAL >= 4" BLOCK; 33 | CheckRule "$XSS >= 8" BLOCK; 34 | CheckRule "$TEST_LOG >= 8" DROP; 35 | root $TEST_NGINX_SERVROOT/html/; 36 | index index.html index.htm; 37 | error_page 405 = $uri; 38 | } 39 | location /RequestDenied { 40 | return 412; 41 | # return 412; 42 | } 43 | --- more_headers 44 | Content-Type: application/x-www-form-urlencoded; charset=UTF-8 45 | --- request eval 46 | use URI::Escape; 47 | "POST / 48 | ww=%2F%C0%AE%2E%2F&foo2=bar2" 49 | --- error_code: 412 50 | === TEST 2.1: utf8 overlong 51 | --- main_config 52 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 53 | --- http_config 54 | include /tmp/naxsi_ut/naxsi_core.rules; 55 | --- config 56 | location / { 57 | SecRulesEnabled; 58 | DeniedUrl "/RequestDenied"; 59 | CheckRule "$SQL >= 8" BLOCK; 60 | CheckRule "$RFI >= 8" BLOCK; 61 | CheckRule "$TRAVERSAL >= 4" BLOCK; 62 | CheckRule "$XSS >= 8" BLOCK; 63 | CheckRule "$TEST_LOG >= 8" DROP; 64 | root $TEST_NGINX_SERVROOT/html/; 65 | index index.html index.htm; 66 | error_page 405 = $uri; 67 | } 68 | location /RequestDenied { 69 | return 412; 70 | # return 412; 71 | } 72 | --- more_headers 73 | Content-Type: application/x-www-form-urlencoded; charset=UTF-8 74 | --- request eval 75 | use URI::Escape; 76 | "POST / 77 | ww=%c0%80" 78 | --- error_code: 412 79 | === TEST 2.2: valid utf8 80 | --- main_config 81 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 82 | --- http_config 83 | include /tmp/naxsi_ut/naxsi_core.rules; 84 | --- config 85 | location / { 86 | SecRulesEnabled; 87 | DeniedUrl "/RequestDenied"; 88 | CheckRule "$SQL >= 8" BLOCK; 89 | CheckRule "$RFI >= 8" BLOCK; 90 | CheckRule "$TRAVERSAL >= 4" BLOCK; 91 | CheckRule "$XSS >= 8" BLOCK; 92 | CheckRule "$TEST_LOG >= 8" DROP; 93 | root $TEST_NGINX_SERVROOT/html/; 94 | index index.html index.htm; 95 | error_page 405 = $uri; 96 | } 97 | location /RequestDenied { 98 | return 412; 99 | # return 412; 100 | } 101 | --- more_headers 102 | Content-Type: application/x-www-form-urlencoded; charset=UTF-8 103 | --- request eval 104 | use URI::Escape; 105 | "POST / 106 | ww=%61%73%64%c3%a9%c3%a9%c3%a9%c3%a9%c3%a9%71%c3%b9%c3%b9%c3%b9%c3%a2%c3%a2" 107 | --- error_code: 200 108 | -------------------------------------------------------------------------------- /t/33ignoreip.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | use lib 'lib'; 4 | use Test::Nginx::Socket; 5 | 6 | repeat_each(1); 7 | 8 | plan tests => repeat_each(1) * blocks(); 9 | no_root_location(); 10 | no_long_string(); 11 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 12 | run_tests(); 13 | 14 | __DATA__ 15 | === TEST 1: IgnoreIP defined 16 | --- main_config 17 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 18 | --- http_config 19 | include /tmp/naxsi_ut/naxsi_core.rules; 20 | --- config 21 | location / { 22 | SecRulesEnabled; 23 | IgnoreIP "1.1.1.1"; 24 | DeniedUrl "/RequestDenied"; 25 | CheckRule "$SQL >= 8" BLOCK; 26 | CheckRule "$RFI >= 8" BLOCK; 27 | CheckRule "$TRAVERSAL >= 4" BLOCK; 28 | CheckRule "$XSS >= 8" BLOCK; 29 | root $TEST_NGINX_SERVROOT/html/; 30 | index index.html index.htm; 31 | } 32 | location /RequestDenied { 33 | return 412; 34 | } 35 | --- request 36 | GET /?a=buibui 37 | --- error_code: 200 38 | 39 | === TEST 1.1: IgnoreIP request 40 | --- main_config 41 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 42 | --- http_config 43 | include /tmp/naxsi_ut/naxsi_core.rules; 44 | --- config 45 | location / { 46 | SecRulesEnabled; 47 | IgnoreIP "1.1.1.1"; 48 | DeniedUrl "/RequestDenied"; 49 | CheckRule "$SQL >= 8" BLOCK; 50 | CheckRule "$RFI >= 8" BLOCK; 51 | CheckRule "$TRAVERSAL >= 4" BLOCK; 52 | CheckRule "$XSS >= 8" BLOCK; 53 | root $TEST_NGINX_SERVROOT/html/; 54 | index index.html index.htm; 55 | } 56 | location /RequestDenied { 57 | return 412; 58 | } 59 | --- request 60 | GET /?a=buibui 61 | --- error_code: 200 62 | 63 | === TEST 1.2: IgnoreIP request with X-Forwarded-For allow (ipv4) 64 | --- main_config 65 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 66 | --- http_config 67 | include /tmp/naxsi_ut/naxsi_core.rules; 68 | --- config 69 | location / { 70 | SecRulesEnabled; 71 | IgnoreIP "1.1.1.1"; 72 | DeniedUrl "/RequestDenied"; 73 | CheckRule "$SQL >= 8" BLOCK; 74 | CheckRule "$RFI >= 8" BLOCK; 75 | CheckRule "$TRAVERSAL >= 4" BLOCK; 76 | CheckRule "$XSS >= 8" BLOCK; 77 | root $TEST_NGINX_SERVROOT/html/; 78 | index index.html index.htm; 79 | } 80 | location /RequestDenied { 81 | return 412; 82 | } 83 | --- more_headers 84 | X-Forwarded-For: 1.1.1.1 85 | --- request 86 | GET /?a=buibui 87 | --- error_code: 200 88 | 89 | === TEST 1.3: IgnoreIP request with X-Forwarded-For allow (ipv6) 90 | --- main_config 91 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 92 | --- http_config 93 | include /tmp/naxsi_ut/naxsi_core.rules; 94 | --- config 95 | location / { 96 | SecRulesEnabled; 97 | IgnoreIP "2001:4860:4860::8844"; 98 | DeniedUrl "/RequestDenied"; 99 | CheckRule "$SQL >= 8" BLOCK; 100 | CheckRule "$RFI >= 8" BLOCK; 101 | CheckRule "$TRAVERSAL >= 4" BLOCK; 102 | CheckRule "$XSS >= 8" BLOCK; 103 | root $TEST_NGINX_SERVROOT/html/; 104 | index index.html index.htm; 105 | } 106 | location /RequestDenied { 107 | return 412; 108 | } 109 | --- more_headers 110 | X-Forwarded-For: 2001:4860:4860::8844 111 | --- request 112 | GET /?a=buibui 113 | --- error_code: 200 114 | 115 | === TEST 1.4: IgnoreIP request with X-Forwarded-For deny (ipv4) 116 | --- main_config 117 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 118 | --- http_config 119 | include /tmp/naxsi_ut/naxsi_core.rules; 120 | --- config 121 | location / { 122 | SecRulesEnabled; 123 | IgnoreIP "1.1.1.1"; 124 | DeniedUrl "/RequestDenied"; 125 | CheckRule "$SQL >= 8" BLOCK; 126 | CheckRule "$RFI >= 8" BLOCK; 127 | CheckRule "$TRAVERSAL >= 4" BLOCK; 128 | CheckRule "$XSS >= 8" BLOCK; 129 | root $TEST_NGINX_SERVROOT/html/; 130 | index index.html index.htm; 131 | } 132 | location /RequestDenied { 133 | return 412; 134 | } 135 | --- more_headers 136 | X-Forwarded-For: 2.2.2.2 137 | --- request 138 | GET /?a=<> 139 | --- error_code: 412 140 | 141 | === TEST 1.5: IgnoreIP request with X-Forwarded-For deny (ipv6) 142 | --- main_config 143 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 144 | --- http_config 145 | include /tmp/naxsi_ut/naxsi_core.rules; 146 | --- config 147 | location / { 148 | SecRulesEnabled; 149 | IgnoreIP "2001:4860:4860::8844"; 150 | DeniedUrl "/RequestDenied"; 151 | CheckRule "$SQL >= 8" BLOCK; 152 | CheckRule "$RFI >= 8" BLOCK; 153 | CheckRule "$TRAVERSAL >= 4" BLOCK; 154 | CheckRule "$XSS >= 8" BLOCK; 155 | root $TEST_NGINX_SERVROOT/html/; 156 | index index.html index.htm; 157 | } 158 | location /RequestDenied { 159 | return 412; 160 | } 161 | --- more_headers 162 | X-Forwarded-For: 2001:4860:4860::8888 163 | --- request 164 | GET /?a=<> 165 | --- error_code: 412 166 | 167 | === TEST 1.6: Multiple IgnoreIP defined 168 | --- main_config 169 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 170 | --- http_config 171 | include /tmp/naxsi_ut/naxsi_core.rules; 172 | --- config 173 | location / { 174 | SecRulesEnabled; 175 | IgnoreIP "1.1.1.1"; 176 | IgnoreIP "1.2.3.4"; 177 | IgnoreIP "2.3.4.1"; 178 | IgnoreIP "2606:4700:4700::1111"; 179 | IgnoreIP "2606:4700:4700::1001"; 180 | DeniedUrl "/RequestDenied"; 181 | CheckRule "$SQL >= 8" BLOCK; 182 | CheckRule "$RFI >= 8" BLOCK; 183 | CheckRule "$TRAVERSAL >= 4" BLOCK; 184 | CheckRule "$XSS >= 8" BLOCK; 185 | root $TEST_NGINX_SERVROOT/html/; 186 | index index.html index.htm; 187 | } 188 | location /RequestDenied { 189 | return 412; 190 | } 191 | --- request 192 | GET /?a=buibui 193 | --- error_code: 200 194 | 195 | === TEST 1.7: Verify IgnoreIP (IPv4) works 196 | --- user_files 197 | >>> foobar 198 | foobar text 199 | --- main_config 200 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 201 | --- http_config 202 | include /tmp/naxsi_ut/naxsi_core.rules; 203 | MainRule "str:/foobar" "mz:URL" "s:$TRAVERSAL:4" id:123456; 204 | --- config 205 | location / { 206 | SecRulesEnabled; 207 | IgnoreIP "127.0.0.1"; 208 | #IgnoreIP "2606:4700:4700::1001"; # IPv6 can't be tested. 209 | DeniedUrl "/RequestDenied"; 210 | CheckRule "$TRAVERSAL >= 4" BLOCK; 211 | root $TEST_NGINX_SERVROOT/html/; 212 | index index.html index.htm; 213 | } 214 | location /RequestDenied { 215 | return 412; 216 | } 217 | --- request 218 | GET /foobar 219 | --- error_code: 200 220 | -------------------------------------------------------------------------------- /t/34ignorecidr.t: -------------------------------------------------------------------------------- 1 | #vi:filetype=perl 2 | 3 | use lib 'lib'; 4 | use Test::Nginx::Socket; 5 | 6 | repeat_each(1); 7 | 8 | plan tests => repeat_each(1) * blocks(); 9 | no_root_location(); 10 | no_long_string(); 11 | $ENV{TEST_NGINX_SERVROOT} = server_root(); 12 | run_tests(); 13 | 14 | __DATA__ 15 | === TEST 1: IgnoreCIDR defined (no file) 16 | --- main_config 17 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 18 | --- http_config 19 | include /tmp/naxsi_ut/naxsi_core.rules; 20 | --- config 21 | location / { 22 | SecRulesEnabled; 23 | IgnoreCIDR "1.1.1.0/24"; 24 | DeniedUrl "/RequestDenied"; 25 | CheckRule "$SQL >= 8" BLOCK; 26 | CheckRule "$RFI >= 8" BLOCK; 27 | CheckRule "$TRAVERSAL >= 4" BLOCK; 28 | CheckRule "$XSS >= 8" BLOCK; 29 | root $TEST_NGINX_SERVROOT/html/; 30 | index index.html index.htm; 31 | } 32 | location /RequestDenied { 33 | return 412; 34 | } 35 | --- request 36 | GET /?a=buibui 37 | --- error_code: 200 38 | 39 | === TEST 1.1: IgnoreCIDR request (no file) 40 | --- main_config 41 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 42 | --- http_config 43 | include /tmp/naxsi_ut/naxsi_core.rules; 44 | --- config 45 | location / { 46 | SecRulesEnabled; 47 | IgnoreCIDR "1.1.1.0/24"; 48 | DeniedUrl "/RequestDenied"; 49 | CheckRule "$SQL >= 8" BLOCK; 50 | CheckRule "$RFI >= 8" BLOCK; 51 | CheckRule "$TRAVERSAL >= 4" BLOCK; 52 | CheckRule "$XSS >= 8" BLOCK; 53 | root $TEST_NGINX_SERVROOT/html/; 54 | index index.html index.htm; 55 | } 56 | location /RequestDenied { 57 | return 412; 58 | } 59 | --- request 60 | GET /?a=buibui 61 | --- error_code: 200 62 | 63 | === TEST 1.2: IgnoreCIDR request with X-Forwarded-For allow (no file) 64 | --- main_config 65 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 66 | --- http_config 67 | include /tmp/naxsi_ut/naxsi_core.rules; 68 | --- config 69 | location / { 70 | SecRulesEnabled; 71 | IgnoreCIDR "1.1.1.0/24"; 72 | DeniedUrl "/RequestDenied"; 73 | CheckRule "$SQL >= 8" BLOCK; 74 | CheckRule "$RFI >= 8" BLOCK; 75 | CheckRule "$TRAVERSAL >= 4" BLOCK; 76 | CheckRule "$XSS >= 8" BLOCK; 77 | root $TEST_NGINX_SERVROOT/html/; 78 | index index.html index.htm; 79 | } 80 | location /RequestDenied { 81 | return 412; 82 | } 83 | --- more_headers 84 | X-Forwarded-For: 1.1.1.1 85 | --- request 86 | GET /?a=buibui 87 | --- error_code: 200 88 | 89 | === TEST 1.3: IgnoreCIDR request with X-Forwarded-For deny (no file) 90 | --- main_config 91 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 92 | --- http_config 93 | include /tmp/naxsi_ut/naxsi_core.rules; 94 | --- config 95 | location / { 96 | SecRulesEnabled; 97 | IgnoreCIDR "1.1.1.0/24"; 98 | DeniedUrl "/RequestDenied"; 99 | CheckRule "$SQL >= 8" BLOCK; 100 | CheckRule "$RFI >= 8" BLOCK; 101 | CheckRule "$TRAVERSAL >= 4" BLOCK; 102 | CheckRule "$XSS >= 8" BLOCK; 103 | root $TEST_NGINX_SERVROOT/html/; 104 | index index.html index.htm; 105 | } 106 | location /RequestDenied { 107 | return 412; 108 | } 109 | --- more_headers 110 | X-Forwarded-For: 2.2.2.2 111 | --- request 112 | GET /?a=<> 113 | --- error_code: 412 114 | 115 | === TEST 1.4: Verify IgnoreCIDR works 116 | --- user_files 117 | >>> foobar 118 | foobar text 119 | --- main_config 120 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 121 | --- http_config 122 | include /tmp/naxsi_ut/naxsi_core.rules; 123 | MainRule "str:/foobar" "mz:URL" "s:$TRAVERSAL:4" id:123456; 124 | --- config 125 | location / { 126 | SecRulesEnabled; 127 | IgnoreCIDR "127.0.0.0/24"; 128 | DeniedUrl "/RequestDenied"; 129 | CheckRule "$TRAVERSAL >= 4" BLOCK; 130 | root $TEST_NGINX_SERVROOT/html/; 131 | index index.html index.htm; 132 | } 133 | location /RequestDenied { 134 | return 412; 135 | } 136 | --- request 137 | GET /foobar 138 | --- error_code: 200 139 | 140 | 141 | === TEST 1.5: Verify IgnoreCIDR x.x.x.x./32 is converted to IgnoreIP 142 | --- user_files 143 | >>> foobar 144 | foobar text 145 | --- main_config 146 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 147 | --- http_config 148 | include /tmp/naxsi_ut/naxsi_core.rules; 149 | MainRule "str:/foobar" "mz:URL" "s:$TRAVERSAL:4" id:123456; 150 | --- config 151 | location / { 152 | SecRulesEnabled; 153 | IgnoreCIDR "127.0.0.1/32"; 154 | DeniedUrl "/RequestDenied"; 155 | CheckRule "$TRAVERSAL >= 4" BLOCK; 156 | root $TEST_NGINX_SERVROOT/html/; 157 | index index.html index.htm; 158 | } 159 | location /RequestDenied { 160 | return 412; 161 | } 162 | --- request 163 | GET /foobar 164 | --- error_code: 200 165 | 166 | 167 | -------------------------------------------------------------------------------- /t/confs/nginx.conf.example: -------------------------------------------------------------------------------- 1 | master_process off; 2 | #worker_processes 1; 3 | daemon off; 4 | 5 | load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 6 | events { 7 | worker_connections 1024; 8 | use select; 9 | } 10 | http { 11 | include /tmp/naxsi_ut/naxsi_core.rules; 12 | include mime.types; 13 | default_type application/octet-stream; 14 | sendfile on; 15 | keepalive_timeout 65; 16 | server { 17 | listen 4242 ssl http2; 18 | ssl_certificate /tmp/nginx.crt; 19 | ssl_certificate_key /tmp/nginx.key; 20 | server_name localhost; 21 | set $naxsi_extensive_log 1; 22 | location / { 23 | LearningMode; 24 | SecRulesEnabled; 25 | DeniedUrl "/50x.html"; 26 | CheckRule "$SQL >= 8" BLOCK; 27 | CheckRule "$RFI >= 8" BLOCK; 28 | CheckRule "$TRAVERSAL >= 4" BLOCK; 29 | CheckRule "$EVADE >= 4" BLOCK; 30 | CheckRule "$XSS >= 8" BLOCK; 31 | return 200; 32 | # error_log /tmp/ngx_error.log debug; 33 | # access_log /tmp/ngx_access.log; 34 | # root html; 35 | # index index.html index.htm; 36 | } 37 | error_page 500 502 503 504 /50x.html; 38 | location = /50x.html { 39 | return 500; 40 | # root html; 41 | } 42 | } 43 | } 44 | 45 | -------------------------------------------------------------------------------- /t/confs/nginx_fuzz.conf.example: -------------------------------------------------------------------------------- 1 | master_process off; 2 | daemon off; 3 | 4 | #load_module /tmp/naxsi_ut/modules/ngx_http_naxsi_module.so; 5 | events { 6 | worker_connections 1024; 7 | use select; 8 | } 9 | http { 10 | MainRule "rx:select|union|update|delete|insert|table|from|ascii|hex|unhex|drop" "msg:sql keywords" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1000; 11 | MainRule "str:\"" "msg:double quote" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8,$XSS:8" id:1001; 12 | MainRule "str:0x" "msg:0x, possible hex encoding" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:2" id:1002; 13 | ## Hardcore rules 14 | MainRule "str:/*" "msg:mysql comment (/*)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8" id:1003; 15 | MainRule "str:*/" "msg:mysql comment (*/)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8" id:1004; 16 | MainRule "str:|" "msg:mysql keyword (|)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:8" id:1005; 17 | MainRule "str:`" "msg:grave accent (`)" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1314; 18 | MainRule "rx:%[23]." "msg:double encoding" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1315; 19 | MainRule "str:&#" "msg:utf7/8 encoding" "mz:ARGS|BODY|URL|$HEADERS_VAR:Cookie" "s:$EVADE:4" id:1400; 20 | MainRule "str:%U" "msg:M$ encoding" "mz:ARGS|BODY|URL|$HEADERS_VAR:Cookie" "s:$EVADE:4" id:1401; 21 | MainRule "rx:\.ph|\.asp|\.ht" "msg:asp/php file upload" "mz:FILE_EXT" "s:$UPLOAD:8" id:1500; 22 | 23 | # include /tmp/naxsi_ut/naxsi_core.rules; 24 | # include mime.types; 25 | default_type application/octet-stream; 26 | sendfile on; 27 | keepalive_timeout 65; 28 | server { 29 | listen 4242; 30 | server_name localhost; 31 | location / { 32 | LearningMode; 33 | SecRulesEnabled; 34 | DeniedUrl "/50x.html"; 35 | CheckRule "$SQL >= 8" BLOCK; 36 | CheckRule "$RFI >= 8" BLOCK; 37 | CheckRule "$TRAVERSAL >= 4" BLOCK; 38 | CheckRule "$EVADE >= 4" BLOCK; 39 | CheckRule "$XSS >= 8" BLOCK; 40 | return 200; 41 | } 42 | error_page 500 502 503 504 /50x.html; 43 | location = /50x.html { 44 | return 500; 45 | } 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /t/confs/ngx_cycle.patch: -------------------------------------------------------------------------------- 1 | --- a/src/core/ngx_cycle.c.orig 2016-02-09 15:11:57.000000000 +0100 2 | +++ b/src/core/ngx_cycle.c 2016-12-12 18:05:53.832725017 +0100 3 | --- nginx/src/core/ngx_cycle.c 2016-02-09 15:11:57.000000000 +0100 4 | +++ ngx_cycle.c 2016-12-13 09:49:47.762221499 +0100 5 | @@ -602,6 +602,8 @@ 6 | } 7 | } 8 | 9 | + __AFL_INIT(); 10 | + 11 | if (ngx_open_listening_sockets(cycle) != NGX_OK) { 12 | goto failed; 13 | } 14 | -------------------------------------------------------------------------------- /t/confs/ngx_process_cycle.patch: -------------------------------------------------------------------------------- 1 | --- a/src/os/unix/ngx_process_cycle.c.orig 2016-02-09 15:11:58.000000000 +0100 2 | +++ a/src/os/unix/ngx_process_cycle.c 2016-12-12 15:05:21.000000000 +0100 3 | @@ -303,7 +303,11 @@ 4 | } 5 | } 6 | 7 | + 8 | + int ran_once=0; 9 | + 10 | for ( ;; ) { 11 | + 12 | ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); 13 | 14 | ngx_process_events_and_timers(cycle); 15 | @@ -337,6 +341,11 @@ 16 | ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); 17 | ngx_reopen_files(cycle, (ngx_uid_t) -1); 18 | } 19 | + 20 | + ran_once += 1; 21 | + //printf("ran : %d\n", ran_once); 22 | + if (ran_once == 2) exit(0); 23 | + 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /t/fuzz/big-json-post: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | Content-Type: application/json 5 | Content-Length: 542 6 | 7 | { 8 | "glossary": { 9 | "title": "example glossary", 10 | "GlossDiv": { 11 | "title": "S", 12 | "GlossList": { 13 | "GlossEntry": { 14 | "ID": "SGML", 15 | "SortAs": "SGML", 16 | "GlossTerm": "Standard Generalized Markup Language", 17 | "Acronym": "SGML", 18 | "Abbrev": "ISO 8879:1986", 19 | "GlossDef": { 20 | "para": "A meta-markup language used to create markup languages such as DocBook.", 21 | "GlossSeeAlso": ["GML", "XML"] 22 | }, 23 | "GlossSee": "markup" 24 | } 25 | } 26 | } 27 | } 28 | 29 | }} 30 | 31 | -------------------------------------------------------------------------------- /t/fuzz/big-multipart-post: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | Content-Type: multipart/form-data; boundary=---------------------------103832778631715 5 | Content-Length: 4449 6 | 7 | -----------------------------103832778631715 8 | Content-Disposition: form-data; name="name" 9 | 10 | azzzo 11 | 12 | 13 | -----------------------------103832778631715 14 | Content-Disposition: form-data; name="married" 15 | 16 | not single 17 | -----------------------------103832778631715 18 | Content-Disposition: form-data; name="male" 19 | 20 | AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 21 | -----------------------------103832778631715-- 22 | 23 | -------------------------------------------------------------------------------- /t/fuzz/med-get-bad-format: -------------------------------------------------------------------------------- 1 | GET /?a=1%23PTTmJopxdWJ%0AAND%23cWfcVRPV%0A9227=9227 HTTP/1.0 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /t/fuzz/med-get-with-path: -------------------------------------------------------------------------------- 1 | GET /bla?/bla=1999&bu=1998 HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /t/fuzz/med-json-post: -------------------------------------------------------------------------------- 1 | POST /test_uri HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | Content-Type: application/json 5 | Content-Length: 183 6 | 7 | { 8 | "oh" : ["there", "is", "no", "way"], 9 | "this" : { "will" : ["work", "does"], 10 | "it" : "??" }, 11 | "trigger" : {"test_1234" : ["foobar", "will", "trigger", "it"]}, 12 | "foo" : "baar" 13 | } 14 | 15 | -------------------------------------------------------------------------------- /t/fuzz/med-multipart-file-post: -------------------------------------------------------------------------------- 1 | POST /foobar HTTP/1.1 2 | Host: 127.0.0.1 3 | Connection: Close 4 | User-Agent: Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10 5 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 6 | Accept-Language: en-us,en;q=0.5 7 | Accept-Encoding: gzip, deflate 8 | Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 9 | Referer: http://127.0.0.1/ 10 | Content-Type: multipart/form-data; boundary=---------------------------1919886344942015258287623957 11 | Content-Length: 394 12 | 13 | -----------------------------1919886344942015258287623957 14 | Content-Disposition: form-data; name="textline" 15 | 16 | valid text and small file 17 | -----------------------------1919886344942015258287623957 18 | Content-Disposition: form-data; name="datafile"; filename="bla.txt"; name="bla.txt" 19 | Content-Type: text/plain 20 | 21 | buibuibubi 22 | buibuibuib 23 | 24 | -----------------------------1919886344942015258287623957-- 25 | 26 | 27 | -------------------------------------------------------------------------------- /t/fuzz/med-multipart-post: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | Content-Type: multipart/form-data; boundary=---------------------------103832778631715 5 | Content-Length: 42 6 | 7 | -----------------------------103832778631715 8 | Content-Disposition: form-data; name="name" 9 | 10 | MyName 11 | -----------------------------103832778631715 12 | Content-Disposition: form-data; name="married" 13 | 14 | not single 15 | -----------------------------103832778631715 16 | Content-Disposition: form-data; name="male" 17 | 18 | yes 19 | -----------------------------103832778631715-- 20 | 21 | 22 | -------------------------------------------------------------------------------- /t/fuzz/med-post-non-ascii: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | Content-Type: RAFARAFA 5 | Content-Length: 214 6 | 7 |  8 | 9 | -------------------------------------------------------------------------------- /t/fuzz/mini-get-nohost: -------------------------------------------------------------------------------- 1 | GET /?a=1%20UnioN%20SeLEct%201 HTTP/1.0 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /t/fuzz/mini-get-sig: -------------------------------------------------------------------------------- 1 | GET /?a=1+/*!30000AND+2>1*/-- HTTP/1.0 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /t/fuzz/mini-json-post: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | Content-Type: application/json 5 | Content-Length: 18 6 | 7 | { 8 | "lol" : "bar" 9 | } 10 | 11 | -------------------------------------------------------------------------------- /t/fuzz/mini-ko-get: -------------------------------------------------------------------------------- 1 | GET /?==yesone&&& HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /t/fuzz/mini-multipart-post: -------------------------------------------------------------------------------- 1 | POST /foobar HTTP/1.1 2 | Host: 127.0.0.1 3 | Connection: Close 4 | User-Agent: Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10 5 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 6 | Accept-Language: en-us,en;q=0.5 7 | Accept-Encoding: gzip, deflate 8 | Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 9 | Referer: http://127.0.0.1/ 10 | Content-Type: multipart/form-data; boundary=---------------------------1919886344942015258287623957 11 | Content-Length: 378 12 | 13 | -----------------------------1919886344942015258287623957 14 | Content-Disposition: form-data; name="textline" 15 | 16 | valid text and small file 17 | -----------------------------1919886344942015258287623957 18 | Content-Disposition: form-data; name="datafile"; filename="bla.txt" 19 | Content-Type: text/plain 20 | 21 | buibuibubi 22 | buibuibuib 23 | 24 | -----------------------------1919886344942015258287623957-- 25 | 26 | 27 | -------------------------------------------------------------------------------- /t/fuzz/mini-ok-get: -------------------------------------------------------------------------------- 1 | GET /?a=<> HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /t/fuzz/mini-unknown-CT-post: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | Content-Type: RAFARAFA 5 | Content-Length: 28 6 | 7 | %00XXRANDBBRANDOMTHINGS%00 8 | 9 | -------------------------------------------------------------------------------- /t/fuzz/mini-urlencded-post-2: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | Content-Type: application/x-www-form-urlencoded 5 | Content-Length: 32 6 | 7 | foo1='> 8 | 9 | -------------------------------------------------------------------------------- /t/fuzz/mini-urlencoded-post: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | Content-Type: application/x-www-form-urlencoded 5 | Content-Length: 9 6 | 7 | a1=trolol 8 | 9 | -------------------------------------------------------------------------------- /t/fuzz/small-multipart-post: -------------------------------------------------------------------------------- 1 | POST / HTTP/1.1 2 | Host: localhost 3 | Connection: close 4 | Content-Type: multipart/form-data; boundary=---------------------------103832778631715 5 | Content-Length: 353 6 | 7 | -----------------------------103832778631715 8 | Content-Disposition: form-data; name="name" 9 | 10 | MyName 11 | -----------------------------103832778631715 12 | Content-Disposition: form-data; name="married" 13 | 14 | not single 15 | -----------------------------103832778631715 16 | Content-Disposition: form-data; name="male" 17 | 18 | yes 19 | -----------------------------103832778631715-- 20 | 21 | --------------------------------------------------------------------------------