commit 41f17b127c79e131c7702c6ebb084dd876dab007 Author: Jayden Date: Sat May 9 03:21:32 2026 +0800 Saturday, May 09, 2026 AM03:21:24 HKT diff --git a/README.md b/README.md new file mode 100644 index 0000000..2c6c7b9 --- /dev/null +++ b/README.md @@ -0,0 +1,107 @@ +# ENDGAME V3.5 + +This is the third and a half edition of Endgame. The most popular anti-ddos solution on the darknet. + +EndGame is + +- a front system designed to protect the core application servers on an onion service in a safe and private way. +- locally complied and locally run (no trusted or middle party). +- a combination of multiple different technologies working together in harmony (listed below). +- FREE FOR ALL TO USE! +- *arguably* magic ㄟ( ▔, ▔ )ㄏ + +## Main Features + +- Fully scripted and easily deploy-able (for mass scaling!) on blank Debian 12 systems. +- Full featured NGINX LUA script to filter packets and provide a captcha directly using the NGINX layer. +- Rate limiting via Tor's V3 onion service circuit ID system with secondary rate limiting based on a testcookie like system. +- Easy Configuration for both local and remote (over Tor) front systems. +- Easily configurable and change-able to meet an onion service's needs. +- Hardening and compromise check processes (fail2ban, rkhunter, debsecan) +- Captcha processes and a captcha built in rust with zero runtime dependencies! +- Various updates and security improvements in the lua script (it now sends you back to the queue if you fail 3 captchas) +- Caching of nginx modules for faster deployment! +- LOTS of kernel tweaks for both hardening and more efficient memory allocation for Tor +- Fresh html and css that makes it very clear you are using the latest endgame! +- Includes an onionbalance process completely written in go built for high traffic sites (see it in the sourcecode folder) +- Includes a tor patch to require some minimum POW work for all introduction requests (stopping the introduction cell DDOS attacks bites) + +It can also: +- Cause you to grow a bigger dick than the asshole DDOSER (true *figurally*, lies *probably*) +- Save you millions of dollars do to DDOSER's downing your site for ransom or for their extorting fees. +- Make it look like you know what the fuck you are doing. + +## How it works + +EndGame is a FRONT system. That is to say it filters the requests that a service will receive, blocks bad requests, and only passes good ones to the application server. + +At a request level it works like this: + +`USER -> Tor -> Endgame Front -> Tor(optional) -> Backend (origin) Application Server` + +*Endgame should be on a separate isolated server to your backend server.* It only proxies content from your backend to the user. You will still need to configure your backend to handle requests from the Endgame Front. + +This is the same system that anti-DDOS services like Cloudflare, Indusface, and Imperva use to protect websites from attacks. The difference is this is self-hosted and fully controlled by you for your own needs and made for darknet networks. + +**On Tor, GoBalance (onionbalance) is central to really scale up protection and should be used with EndGame in production environments.** + +What GoBalance does is take the various Endgame Front addresses and combine the descriptors together to create a distributed DNS round-robin like system on Tor. This allows for load balancing and prevents a single front from being overloaded. With GoBalance you can scale to hundreds of EndGame fronts that users can access from a single master onion (which we call in the configuration MASTERONION). The master onion is the address that GoBalance uses to sign and publish to the Tor network. + +If you want to learn more about how GoBalance works go and read the [onionbalance documentation](https://onionbalance.readthedocs.io/en/latest/index.html). GoBalance is an improved fork of it written in go. To learn more about what makes Gobalance different go into the sourcecode directory and open the GoBalance folder. + +You can use Endgame without Gobalance (or onionbalance) but the protection would be limited by the single EndGame front. **YOU CAN NOT USE POW (or THE POW PATCH) WITH GOBALANCE!** + +## Setup Process + +If you want to use Gobalance, so you can load balance the requests coming in and get the real scalable protection, follow the parts below. If you don't skip to step 3 after setup 1. + +1. [Download the Latest EndGame Source from Dread](http://dreadytofatroptsdj6io7l3xptbet6onoyno2yv7jicoxknyazubrad.onion/d/endgame). Verify the archive signature and that it matches what is signed by /u/Paris. Extract the archive to your local machine. DO NOT BLINDLY USE ENDGAME FROM A RANDOM GITHUB REPO YOU FOUND. DON'T BE STUPID. +2. Go to sourcecode/gobalance and build gobalance with [go](https://go.dev). Read the README.md about how to compile and generate the gobalance configuration. With that configuration you will be able to see your MASTERONION url. The starting before .key is your master onion address. You will use that as your MASTERONION in the EndGame.config ending it with '.onion'. +3. Open up and edit the endgame.config, you will need to change your TORAUTHPASSWORD. Change it to a random alphanumeric password of your choice. This is just used for authentication on nginx's layer to send circuit kill commands. +4. You have two options for how EndGame sends the traffic to your backend. You can have it direct it to an onion address, or you can have it locally proxy to a server on the same network. + 1. Tor Proxy: You will need to set both of the BACKENDONION variables to your main onion service you want protected. This means your origin application server needs to have tor running with its own onion service address. You put that onion address on the BACKENDONION(1/2). If you have multiple backends (highly recommended) you can put different backend addresses to have load balancing and fallover. It's easy to add in even more by customizing endgame for your needs. + 2. Local Proxy: Change LOCALPROXY to true and edit the PROXYPASSURL to the specific IP or hostname of your backend location. It will default to connect on port 80 via http but you can edit line 320 of the site.conf to change that to your specific needs. +5. Enable TORSETUP by setting them to true. You can also enable TORINTRODEFENSE and TORPOWDEFENSE to provide more protection against introduction attacks on the Tor network. If you enable TOR POW you can not use endgame with any onionbalance. +6. Edit KEY and SALT to a secure cookie value. PROTECT THESE VALUES. If they get leaked, an attacker could generate EndGame cookies and kill your EndGame protection. + 1. KEY: is your encryption key used for encryption. It should be to be between 68 and 128 random alphanumeric characters. + 2. SALT: is your salt for the encryption key. It must be exactly 8 alphanumeric characters. +7. Branding is important. EndGame makes it easy to use your own branding on it. By default, it will use dread's branding, but you should change it. + 1. HEXCOLOR and HEXCOLORDARK are for the specific colors used on the pages. Set HEXCOLOR to your main site color and HEXCOLORDARK to just a slightly darker version of it. + 2. SITENAME, SITETAGLINE, SITESINCE is all information about your site. Self-explanatory. + 3. FAVICON is used as your site's favicon in base64. This limits the amount of requests a browser may do when first loading the queue page. Make sure this value is set to something. Otherwise people's connections will get cut off from the queue when their browser makes a request to the favicon.ico. + 4. SQUARELOGO is used as the icon for the queue running man and the main splash logo on the captcha page. In base64 format. + 5. NETWORKLOGO is used as a bottom network icon for on the captcha page which allows different sites a part of the same organization to be shown. In base64 format. +8. After you are done EndGame's configuration, you should archive everything except the sourcecode folder. Transfer the archive to a blank debian 12 system. As root, extract the archive and run setup.sh like './setup.sh'. At the end of the setup, it will export an onion address which you can provide to users or add to your gobalance configuration. +9. Go out into the world knowing your service is protected by the best and most tested anti-DDOS solution for the darknet. + +### Tech Overview + +EndGame uses a number of open-source projects (and libraries) to work properly. + +Projects: +* [NGINX](https://NGINX.org/) - NGINX! A web server *obviously* to provide the packet handling, threading, and proxying. +* [Tor](https://www.torproject.org/) - Tor is free and open-source software for enabling anonymous communication. It's awesome and makes all this possible. +* [STEM](https://stem.torproject.org/) - A python controller for Tor. +* [NYX](https://nyx.torproject.org/) - A command-line monitor for Tor (to easily check the EndGame front's Tor process. +* [GoBalance](http://yylovpz7taca7jfrub3wltxabzzjp34fngj5lpwl6eo47ekt5cxs6mid.onion/n0tr1v/gobalance) - A distributed DNS round-robin like system on Tor to allow load-balancing and eliminate single points of failure. +* [OpenSSL](https://www.openssl.org/) - A dependency for a lot of this projects and libraries. +* [Socat](http://www.dest-unreach.org/socat/) - Socat is a command line based utility that establishes two bidirectional byte streams and transfers data between them. (used for backend tor proxying) + +Hardening Projects: +* [Fail2ban](https://www.fail2ban.org/) - A set of server and client programs to limit brute force authentication attempts. (automatically configured) +* [Rkhunter](http://rkhunter.sourceforge.net/) - rkhunter is a shell script which carries out various checks on the local system to try and detect known rootkits and malware. +* [Chkrootkit](https://www.chkrootkit.org/) - chkrootkit is a tool to locally check for signs of a rootkit. + +NGINX Modules: +* [NAXSI](https://github.com/nbs-system/naxsi) - A high performance web application firewall for NGINX. +* [Headers More](https://github.com/openresty/headers-more-NGINX-module) - A module for better control of headers in NGINX. +* [Echo NGINX](https://github.com/openresty/echo-nginx-module) - A NGINX module which allows shell style commands in the NGINX configuration file. +* [LUA NGINX](https://github.com/openresty/lua-nginx-module) - The power of LUA into NGINX via a module. This allows all the scripting, packet filtering, and captcha functionality EndGame does. +* [NGINX Development Kit](https://github.com/vision5/ngx_devel_kit) - Development Kit for NGINX (dependency) + +Libraries: +* [LUAJIT2 NGINX](https://github.com/openresty/luajit2) - Just in time compiler for LUA. +* [LUA Resty String](https://github.com/openresty/lua-resty-string) - String functions for ngx_lua and LUAJIT2 +* [LUA Resty Cookie](https://github.com/cloudflare/lua-resty-cookie) - Provides cookie manipulation +* [LUA Resty Session](https://github.com/bungle/lua-resty-session) - Provides session manipulation +* [LUA Resty AES](https://github.com/c64bob/lua-resty-aes/raw/master/lib/resty/aes_functions.lua) - AES Functions file for LUA. Used for shared session cookies. diff --git a/aptpreferences b/aptpreferences new file mode 100644 index 0000000..6f24b7a --- /dev/null +++ b/aptpreferences @@ -0,0 +1,11 @@ +Package: * +Pin: release a=bookworm +Pin-Priority: 500 + +Package: linux-image-amd64 +Pin: release a=unstable +Pin-Priority: 1000 + +Package: * +Pin: release a=unstable +Pin-Priority: 100 diff --git a/dependencies/echo-nginx-module b/dependencies/echo-nginx-module new file mode 160000 index 0000000..4eeda3c --- /dev/null +++ b/dependencies/echo-nginx-module @@ -0,0 +1 @@ +Subproject commit 4eeda3c449eaf310db66db86d230f1727e081fbe diff --git a/dependencies/headers-more-nginx-module b/dependencies/headers-more-nginx-module new file mode 160000 index 0000000..84a65d6 --- /dev/null +++ b/dependencies/headers-more-nginx-module @@ -0,0 +1 @@ +Subproject commit 84a65d68687c9de5166fd49ddbbd68c6962234eb diff --git a/dependencies/lua-nginx-module b/dependencies/lua-nginx-module new file mode 160000 index 0000000..4e40c13 --- /dev/null +++ b/dependencies/lua-nginx-module @@ -0,0 +1 @@ +Subproject commit 4e40c1314f316e5ba4bf538213a2312daa950a8a diff --git a/dependencies/lua-resty-cookie b/dependencies/lua-resty-cookie new file mode 160000 index 0000000..f418d77 --- /dev/null +++ b/dependencies/lua-resty-cookie @@ -0,0 +1 @@ +Subproject commit f418d77082eaef48331302e84330488fdc810ef4 diff --git a/dependencies/lua-resty-session b/dependencies/lua-resty-session new file mode 160000 index 0000000..f4b7732 --- /dev/null +++ b/dependencies/lua-resty-session @@ -0,0 +1 @@ +Subproject commit f4b773244f7841bbc4065ffe15c422a1bd67efaa diff --git a/dependencies/lua-resty-string b/dependencies/lua-resty-string new file mode 160000 index 0000000..c6b4348 --- /dev/null +++ b/dependencies/lua-resty-string @@ -0,0 +1 @@ +Subproject commit c6b4348f53607044d16ec5fdc3d06fd30df487d8 diff --git a/dependencies/luajit2 b/dependencies/luajit2 new file mode 160000 index 0000000..afc7431 --- /dev/null +++ b/dependencies/luajit2 @@ -0,0 +1 @@ +Subproject commit afc74313c6f919f713e2a25003cf0066852bb24a diff --git a/dependencies/naxsi-1.7-src-with-deps.tar.gz b/dependencies/naxsi-1.7-src-with-deps.tar.gz new file mode 100644 index 0000000..744733b Binary files /dev/null and b/dependencies/naxsi-1.7-src-with-deps.tar.gz differ diff --git a/dependencies/naxsi/.clang-format b/dependencies/naxsi/.clang-format new file mode 100644 index 0000000..8b520da --- /dev/null +++ b/dependencies/naxsi/.clang-format @@ -0,0 +1,135 @@ +--- +Language: Cpp +# BasedOnStyle: Mozilla +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: true +AlignConsecutiveAssignments: true +AlignConsecutiveDeclarations: true +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: TopLevel +AlwaysBreakAfterReturnType: TopLevel +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: false + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: false + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Mozilla +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeComma +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 2 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: false +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: false +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + SortPriority: 0 + - Regex: '.*' + Priority: 1 + SortPriority: 0 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentGotoLabels: true +IndentPPDirectives: None +IndentWidth: 2 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: false +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never diff --git a/dependencies/naxsi/.gitattributes b/dependencies/naxsi/.gitattributes new file mode 100644 index 0000000..6395354 --- /dev/null +++ b/dependencies/naxsi/.gitattributes @@ -0,0 +1,7 @@ +*.txt linguist-detectable=false +*.conf linguist-detectable=false +*.script linguist-detectable=false +*.install linguist-detectable=false +*.sh linguist-detectable=false +*.py linguist-detectable=false +*.t linguist-detectable=false diff --git a/dependencies/naxsi/.github/ISSUE_TEMPLATE/bug_report.md b/dependencies/naxsi/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..5810358 --- /dev/null +++ b/dependencies/naxsi/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,27 @@ +--- +name: Bug report +about: Describe the issue +title: 'Change me' +labels: bug +assignees: wargio + +--- + +**Details** + +- NGINX version: `X.Y.Z` +- NAXSI version: `X.Y` +- Did you install NAXSI from a package manager? **YES/NO** +- Operating System: `XXX Linux` + +**Nginx Logs** + +``` + +Copy and paste here the logs + +``` + +**Additional details** + +Add any other detail about the problem here. diff --git a/dependencies/naxsi/.github/workflows/ci.yaml b/dependencies/naxsi/.github/workflows/ci.yaml new file mode 100644 index 0000000..d9ef63a --- /dev/null +++ b/dependencies/naxsi/.github/workflows/ci.yaml @@ -0,0 +1,87 @@ +name: "CI Unit Tests & Efficacy" + +on: + push: + branches: + - main + pull_request: + paths: + - 'naxsi_src/**' + - 'unit-tests/**' + - 'distros/**' + +# Automatically cancel any previous workflow on new push. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: true + +jobs: + build-sys: + strategy: + fail-fast: false + matrix: + container: + - fedora:37 + - fedora:38 + - fedora:39 + name: libinjection-system ${{ matrix.container }} + runs-on: ubuntu-latest + container: ${{ matrix.container }} + steps: + - name: Checkout repository without submodule + uses: actions/checkout@v4 + - name: Install system libinjection + run: | + sudo dnf -y install libinjection \ + libinjection-devel \ + pcre2-devel pcre2 \ + zlib-devel zlib \ + make automake gcc \ + wget openssl + - name: Build + run: /bin/bash .scripts/ci-build.sh "1.25.1" + + + build-test: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + nginx: + - 1.27.0 + - 1.26.1 + - 1.25.1 + - 1.24.0 + - 1.23.4 + - 1.22.0 + - 1.21.5 + - 1.20.2 + - 1.18.0 + - 1.16.1 + - 1.14.2 + runs-on: ${{ matrix.os }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + persist-credentials: false + - name: Build + run: /bin/bash .scripts/ci-build.sh "${{ matrix.nginx }}" + - name: Unit Tests + run: /bin/bash .scripts/ci-test.sh + + build-efficacy: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + persist-credentials: false + - name: Build + run: /bin/bash .scripts/ci-build.sh "1.25.1" + - name: Run WAF efficacy tests (core only) + run: /bin/bash .scripts/ci-wafefficacy.sh core + - name: Run WAF efficacy tests (complete) + run: /bin/bash .scripts/ci-wafefficacy.sh complete \ No newline at end of file diff --git a/dependencies/naxsi/.github/workflows/codeql-analysis.yml b/dependencies/naxsi/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..60155a1 --- /dev/null +++ b/dependencies/naxsi/.github/workflows/codeql-analysis.yml @@ -0,0 +1,69 @@ +name: "CodeQL" + +on: + push: + branches: + - main + pull_request: + # The branches below must be a subset of the branches above + branches: + - main + paths: + - 'naxsi_src/**' + schedule: + - cron: '42 17 * * 2' + +# Automatically cancel any previous workflow on new push. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: true + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + persist-credentials: false + + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: 'cpp' + + - name: Autobuild + run: .scripts/ci-build.sh "1.23.0" + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + output: "reports" + upload: false + + - name: Move file to merged.sarif (CodeQL) + run: mv reports/*.sarif merged.sarif + + - name: Exclude NGINX source + run: | + jq 'del(.runs[].results[].locations[] | select(.physicalLocation.artifactLocation.uri | contains("nginx-source/")))' merged.sarif > tmp0.sarif + jq 'del(.runs[].results[] | select(.locations | length == 0))' tmp0.sarif > filtered.sarif + + - name: Treat warnings as errors + run: | + jq '.runs[].tool.driver.rules[] |= . + {"defaultConfiguration": {"level": "error"}}' filtered.sarif > final.sarif + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: final.sarif diff --git a/dependencies/naxsi/.github/workflows/distros.yaml b/dependencies/naxsi/.github/workflows/distros.yaml new file mode 100644 index 0000000..dbf6f94 --- /dev/null +++ b/dependencies/naxsi/.github/workflows/distros.yaml @@ -0,0 +1,282 @@ +name: "CI for distros" + +on: + push: + branches: + - main + - "dist-*" + tags: + - v* + pull_request: + branches: + - "dist-*" + paths: + - 'naxsi_src/**' + - 'unit-tests/**' + - 'distros/**' + +# Automatically cancel any previous workflow on new push. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: true + +jobs: + tarball: + runs-on: ubuntu-latest + name: "Release Tarball" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + persist-credentials: false + - name: Prepare Release + shell: bash + run: | + if [[ "${{ startsWith(github.event.ref, 'refs/tags')}}" = "true" ]] + then + RELEASE_ID="${{ github.event.ref }}" + else + RELEASE_ID="git-`date "+%Y-%m-%d"`-`git rev-parse --short HEAD`" + fi + RELEASE_ID=${RELEASE_ID##refs/tags/} + echo RELEASE_NAME="naxsi-${RELEASE_ID}-src-with-deps-tgz" >> $GITHUB_ENV + export TARNAME="naxsi-${RELEASE_ID}-src-with-deps.tar.gz" + touch "$TARNAME" + rm -rf .git + tar --exclude="$TARNAME" -czvf "$TARNAME" . + - name: Upload tarball + uses: actions/upload-artifact@v3 + with: + name: ${{ env.RELEASE_NAME }} + path: ./*.tar.gz + + zip: + runs-on: ubuntu-latest + name: "Release Zip" + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + persist-credentials: false + - name: Prepare Release + shell: bash + run: | + if [[ "${{ startsWith(github.event.ref, 'refs/tags')}}" = "true" ]] + then + RELEASE_ID="${{ github.event.ref }}" + else + RELEASE_ID="git-`date "+%Y-%m-%d"`-`git rev-parse --short HEAD`" + fi + RELEASE_ID=${RELEASE_ID##refs/tags/} + echo RELEASE_NAME="naxsi-${RELEASE_ID}-src-with-deps-zip" >> $GITHUB_ENV + rm -rf .git + - name: Upload zip + uses: actions/upload-artifact@v3 + with: + name: ${{ env.RELEASE_NAME }} + path: ./* + + packages: + runs-on: ubuntu-latest + name: ${{ matrix.name }} + container: ${{ matrix.container }} + strategy: + fail-fast: false + matrix: + name: + [ + "arch-linux", + "debian-buster", + "debian-bullseye", + "debian-bookworm", + "ubuntu-focal", + "ubuntu-jammy", + "alpine-3.17.4", + "alpine-3.18.2", + ] + include: + - name: arch-linux + container: archlinux:latest + package: arch + - name: debian-buster + container: debian:buster + package: deb + pcredep: libpcre3-dev + nginxdep: nginx-common + - name: debian-bullseye + container: debian:bullseye + package: deb + pcredep: libpcre3-dev + nginxdep: nginx-common + - name: debian-bookworm + container: debian:bookworm-slim + package: deb + pcredep: libpcre2-dev + nginxdep: nginx + - name: ubuntu-focal + container: ubuntu:focal + package: deb + pcredep: libpcre3-dev + nginxdep: nginx-common + - name: ubuntu-jammy + container: ubuntu:jammy + package: deb + pcredep: libpcre3-dev + nginxdep: nginx-common + - name: alpine-3.17.4 + container: alpine:3.17.4 + package: apk + - name: alpine-3.18.2 + container: alpine:3.18.2 + package: apk + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + # APK package + - name: Install required dependencies + if: matrix.package == 'apk' + run: apk add alpine-sdk doas + - name: Checkout needed repos + if: matrix.package == 'apk' + run: | + rm -rf naxsi_src/libinjection + git clone https://github.com/libinjection/libinjection.git naxsi_src/libinjection + git -C naxsi_src/libinjection checkout b9fcaaf9e50e9492807b23ffcc6af46ee1f203b9 + chmod 777 . + - name: ${{ matrix.name }} package + if: matrix.package == 'apk' + run: sh ./distros/alpine/build-ci.sh + - name: Test apk package + if: matrix.package == 'apk' + run: | + apk add --no-cache nginx + apk add --allow-untrusted build/*.apk + - name: Upload apk package + if: matrix.package == 'apk' + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.name }} + path: build/*.apk + + # DEB package + - name: Update OS & Install deps + if: matrix.package == 'deb' + run: | + if [ -f "/etc/apt/sources.list" ]; then + cat /etc/apt/sources.list > /tmp/sources.list.orig + cat /tmp/sources.list.orig | grep -v "#" | sed 's/^deb /deb-src /g' >> /etc/apt/sources.list + fi + apt-get -qqy update + DEBIAN_FRONTEND=noninteractive apt-get -qqy --no-install-recommends install \ + build-essential \ + ca-certificates \ + dpkg-dev \ + gzip \ + git \ + libgd-dev \ + libgeoip-dev \ + ${{ matrix.pcredep }} \ + libperl-dev \ + libssl-dev \ + libxslt1-dev \ + nginx \ + tar \ + wget \ + zlib1g-dev + if [ -f "/etc/apt/sources.list.d/debian.sources" ]; then + # bookworm only. + echo "deb https://ftp.debian.org/debian/ bookworm contrib main non-free non-free-firmware" >> /etc/apt/sources.list.d/nginx.list + echo "deb-src https://ftp.debian.org/debian/ bookworm contrib main non-free non-free-firmware" >> /etc/apt/sources.list.d/nginx.list + apt-get -qqy update + DEBIAN_FRONTEND=noninteractive apt-get -qqy --no-install-recommends install \ + libperl-dev + fi + - name: Checkout needed repos + if: matrix.package == 'deb' + run: | + rm -rf naxsi_src/libinjection + git clone https://github.com/libinjection/libinjection.git naxsi_src/libinjection + git -C naxsi_src/libinjection checkout b9fcaaf9e50e9492807b23ffcc6af46ee1f203b9 + git clone --depth=1 https://github.com/wargio/deb-creator.git + chmod 777 . + apt-get source nginx + - name: ${{ matrix.name }} package + if: matrix.package == 'deb' + run: | + mkdir -p deb_pkg/ + DEB_PKG=$(realpath deb_pkg) + NGINX_PACKAGE="${{ matrix.nginxdep }}" + NAXSI_VERSION=$(grep "NAXSI_VERSION" naxsi_src/naxsi_const.h | cut -d ' ' -f3 | sed 's/"//g') + LIBPCRE_PACKAGE="${{ matrix.pcredep }}" + LIBPCRE_VERSION=$(dpkg -s ${{ matrix.pcredep }} | grep '^Version:' | cut -d ' ' -f2 | cut -d '-' -f1) + NGINX_VERSION=$(dpkg -s nginx | grep '^Version:' | cut -d ' ' -f2 | cut -d '-' -f1) + NGINX_BUILD_OPTS=$(nginx -V 2>&1 | grep "configure arguments:" | cut -d ":" -f2- | sed -e "s#/build/nginx-[A-Za-z0-9]*/#./#g" | sed 's/--add-dynamic-module=[A-Za-z0-9\/\._-]*//g') + echo "NGINX_VERSION: $NGINX_VERSION" + echo "NGINX_BUILD_OPTS: $NGINX_BUILD_OPTS" + # build module + cd nginx-$NGINX_VERSION + CMDLINE=$(echo ./configure $NGINX_BUILD_OPTS --add-dynamic-module=../naxsi_src/) + eval $CMDLINE + make modules + cd .. + # install files + mkdir -p "$DEB_PKG/data/usr/lib/nginx/modules/" + mkdir -p "$DEB_PKG/data/usr/share/nginx/modules-available/" + mkdir -p "$DEB_PKG/data/usr/share/naxsi/whitelists" + mkdir -p "$DEB_PKG/data/usr/share/naxsi/blocking" + install -Dm755 distros/deb/postinstall.script "$DEB_PKG/postinstall.script" + install -Dm755 distros/deb/postremove.script "$DEB_PKG/postremove.script" + install -Dm755 distros/deb/preremove.script "$DEB_PKG/preremove.script" + install -Dm644 distros/deb/control.install "$DEB_PKG/control.install" + install -Dm755 "nginx-$NGINX_VERSION/objs/ngx_http_naxsi_module.so" "$DEB_PKG/data/usr/lib/nginx/modules/ngx_http_naxsi_module.so" + install -Dm644 distros/deb/mod-http-naxsi.conf "$DEB_PKG/data/usr/share/nginx/modules-available/mod-http-naxsi.conf" + install -Dm644 distros/nginx/naxsi_block_mode.conf "$DEB_PKG/data/usr/share/naxsi/naxsi_block_mode.conf" + install -Dm644 distros/nginx/naxsi_denied_url.conf "$DEB_PKG/data/usr/share/naxsi/naxsi_denied_url.conf" + install -Dm644 distros/nginx/naxsi_learning_mode.conf "$DEB_PKG/data/usr/share/naxsi/naxsi_learning_mode.conf" + install -Dm644 naxsi_rules/naxsi_core.rules "$DEB_PKG/data/usr/share/naxsi/naxsi_core.rules" + install -Dm644 naxsi_rules/whitelists/*.rules "$DEB_PKG/data/usr/share/naxsi/whitelists" + install -Dm644 naxsi_rules/blocking/*.rules "$DEB_PKG/data/usr/share/naxsi/blocking" + # add deb details. + sed -i "s/@NGINX_PACKAGE@/$NGINX_PACKAGE/" "$DEB_PKG/control.install" + sed -i "s/@NGINX_VERSION@/$NGINX_VERSION/" "$DEB_PKG/control.install" + sed -i "s/@LIBPCRE_PACKAGE@/$LIBPCRE_PACKAGE/" "$DEB_PKG/control.install" + sed -i "s/@LIBPCRE_VERSION@/$LIBPCRE_VERSION/" "$DEB_PKG/control.install" + sed -i "s/@NAXSI_VERSION@/$NAXSI_VERSION/" "$DEB_PKG/control.install" + # build deb file + ./deb-creator/deb-creator "$DEB_PKG" + - name: Test deb package + if: matrix.package == 'deb' + run: dpkg -i deb_pkg/*.deb + - name: Upload deb package + if: matrix.package == 'deb' + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.name }} + path: deb_pkg/*.deb + + # Arch Linux package + - name: ${{ matrix.name }} package + if: matrix.package == 'arch' + run: | + pacman -Syy --needed --noconfirm sudo base-devel git perl-rename + chmod 777 distros/arch + useradd build-user -m + passwd -d build-user + printf 'build-user ALL=(ALL) ALL\n' | tee -a /etc/sudoers + cd distros/arch + sudo -u build-user makepkg -s --noconfirm + # Fix package name due github name restrictions + perl-rename -v 's/:/-/g' *.pkg.tar.zst + - name: Test arch package + if: matrix.package == 'arch' + run: pacman -U --noconfirm distros/arch/*.pkg.tar.zst + - name: Upload arch package + if: matrix.package == 'arch' + uses: actions/upload-artifact@v3 + with: + name: ${{ matrix.name }} + path: distros/arch/*.pkg.tar.zst \ No newline at end of file diff --git a/dependencies/naxsi/.github/workflows/linter.yml b/dependencies/naxsi/.github/workflows/linter.yml new file mode 100644 index 0000000..7a87359 --- /dev/null +++ b/dependencies/naxsi/.github/workflows/linter.yml @@ -0,0 +1,69 @@ +name: "Linters" + +on: + push: + branches: + - main + pull_request: + +# Automatically cancel any previous workflow on new push. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: true + +jobs: + no-debug: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Check debug logs are disabled + run: /bin/bash .scripts/ci-debug-check.sh + + distro-ci-check: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + persist-credentials: false + - name: Check if the distro info are updated + run: /bin/bash .scripts/ci-distro-check.sh + + licenses: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Reuse Compliance Check + uses: fsfe/reuse-action@v5 + with: + args: --suppress-deprecation lint + + + formatting: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install wget, software-properties-common, lsb-release (dependencies of LLVM install script) + run: sudo apt --assume-yes install wget software-properties-common lsb-release + - name: Install automatic LLVM 16 + run: wget https://apt.llvm.org/llvm.sh -O /tmp/llvm-install.sh; chmod +x /tmp/llvm-install.sh; sudo /tmp/llvm-install.sh 16 + - name: Install clang-format-16 + run: sudo apt --assume-yes install clang-format-16 + - name: Format check + run: find naxsi_src/ -type f -name "*.c" -o -name "*.h" | grep -v "libinjection" | xargs -I % clang-format --verbose --Werror --dry-run % + + rules: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install python3 + run: sudo apt --assume-yes install python3 + - name: Format check rules + run: | + bash .scripts/ci-rules-linter.sh naxsi_rules/blocking + bash .scripts/ci-rules-linter.sh naxsi_rules/whitelists diff --git a/dependencies/naxsi/.github/workflows/windows.yml b/dependencies/naxsi/.github/workflows/windows.yml new file mode 100644 index 0000000..cdfbd5a --- /dev/null +++ b/dependencies/naxsi/.github/workflows/windows.yml @@ -0,0 +1,41 @@ +name: "Windows CI Unit Tests" + +on: + push: + branches: + - main + pull_request: + paths: + - 'naxsi_src/**' + - 'unit-tests/**' + - 'distros/**' + +# Automatically cancel any previous workflow on new push. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }} + cancel-in-progress: true + +jobs: + build-test: + strategy: + fail-fast: false + matrix: + os: [windows-latest] + nginx: + - 1.24.0 + - 1.23.2 + - 1.22.1 + runs-on: ${{ matrix.os }} + defaults: + run: + shell: cmd + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: recursive + persist-credentials: false + - name: Windows build + run: .scripts\ci-windows-build.bat ${{ matrix.nginx }} + - name: Unit Tests + run: .scripts\ci-windows-test.bat \ No newline at end of file diff --git a/dependencies/naxsi/.gitignore b/dependencies/naxsi/.gitignore new file mode 100644 index 0000000..f239e39 --- /dev/null +++ b/dependencies/naxsi/.gitignore @@ -0,0 +1,10 @@ +*.tar.gz +*.asc +nginx-source +nginx-tmp +*.log +.scripts/.tmp/ +/naxsi_src/libinjection_ngxbuild/ +/unit-tests/python/__pycache__ +/unit-tests/python/test_* +*.orig \ No newline at end of file diff --git a/dependencies/naxsi/.gitmodules b/dependencies/naxsi/.gitmodules new file mode 100644 index 0000000..d5b5725 --- /dev/null +++ b/dependencies/naxsi/.gitmodules @@ -0,0 +1,3 @@ +[submodule "naxsi_src/libinjection"] + path = naxsi_src/libinjection + url = https://github.com/libinjection/libinjection diff --git a/dependencies/naxsi/.scripts/ci-build.sh b/dependencies/naxsi/.scripts/ci-build.sh new file mode 100755 index 0000000..a377a96 --- /dev/null +++ b/dependencies/naxsi/.scripts/ci-build.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# SPDX-FileCopyrightText: 2022 wargio +# SPDX-License-Identifier: LGPL-3.0-only +set -e + +NGINX_VERSION="$1" +N_CPUS=$(nproc) + +if [ -z "$NGINX_VERSION" ]; then + echo "usage: $0 " + echo "example: $0 1.12.2" + exit 1 +fi + +echo "############################" +echo " NGINX VERSION: $NGINX_VERSION" +echo "############################" + +NEW_BUILD=true +if [ -d "nginx-tmp" ] && [ "$NGINX_VERSION" == $(cat nginx-tmp/nginx.version) ]; then + NEW_BUILD=false +fi + +if $NEW_BUILD ; then + rm -rf nginx-source nginx-tmp nginx.tar.gz 2>&1 > /dev/null + wget --no-clobber -O nginx.tar.gz "https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz" + mkdir -p nginx-source nginx-tmp/naxsi_ut/root + echo "$NGINX_VERSION" > nginx-tmp/nginx.version + tar -C nginx-source -xzf nginx.tar.gz --strip-components=1 + rm nginx.tar.gz +fi + +export NAXSI_SRC_PATH=$(realpath naxsi_src/) +export NAXSI_TMP_PATH=$(realpath nginx-tmp/) +export NGINX_TMP_PATH=$(realpath nginx-source/) + +if $NEW_BUILD ; then + cd "$NGINX_TMP_PATH" + ./configure --with-cc-opt='-g -O2 -Wextra -Wall -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' \ + --with-ld-opt='-Wl,-z,relro -Wl,-z,now -fPIC' \ + --with-select_module \ + --conf-path="$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" \ + --http-client-body-temp-path="$NAXSI_TMP_PATH/naxsi_ut/body/" \ + --http-fastcgi-temp-path="$NAXSI_TMP_PATH/naxsi_ut/fastcgi/" \ + --http-proxy-temp-path="$NAXSI_TMP_PATH/naxsi_ut/proxy/" \ + --lock-path="$NAXSI_TMP_PATH/nginx.lock" \ + --pid-path="$NAXSI_TMP_PATH/naxsi_ut/nginx.pid" \ + --modules-path="$NAXSI_TMP_PATH/naxsi_ut/modules/" \ + --without-mail_pop3_module \ + --without-mail_smtp_module \ + --without-mail_imap_module \ + --with-http_realip_module \ + --with-http_v2_module \ + --without-http_uwsgi_module \ + --without-http_scgi_module \ + --prefix="$NAXSI_TMP_PATH/" \ + --add-dynamic-module="$NAXSI_SRC_PATH" \ + --error-log-path="$NAXSI_TMP_PATH/naxsi_ut/error.log" \ + --conf-path="$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" + cd .. +fi + +make -C "$NGINX_TMP_PATH" -j$N_CPUS install diff --git a/dependencies/naxsi/.scripts/ci-debug-check.sh b/dependencies/naxsi/.scripts/ci-debug-check.sh new file mode 100755 index 0000000..61b1a19 --- /dev/null +++ b/dependencies/naxsi/.scripts/ci-debug-check.sh @@ -0,0 +1,10 @@ +#!/bin/sh +# SPDX-FileCopyrightText: 2022 wargio +# SPDX-License-Identifier: LGPL-3.0-only +set -e + +N_DEBUGS=$(cat naxsi_src/naxsi.h | grep "#define _debug" | grep 1 | wc -l) +if [ $N_DEBUGS -gt 0 ]; then + cat naxsi_src/naxsi.h | grep "#define _debug" | grep 1 + exit 1 +fi diff --git a/dependencies/naxsi/.scripts/ci-distro-check.sh b/dependencies/naxsi/.scripts/ci-distro-check.sh new file mode 100755 index 0000000..0646a3c --- /dev/null +++ b/dependencies/naxsi/.scripts/ci-distro-check.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# SPDX-FileCopyrightText: 2023 wargio +# SPDX-License-Identifier: LGPL-3.0-only +set -e + +check_file_for() { + local FILENAME="$1" + local SEARCH_FOR="$2" + local EXPECTED="$3" + local FOUND=$(cat "$FILENAME" | grep "$SEARCH_FOR") + if [ -z "$FOUND" ]; then + echo "'$FILENAME' does not contain '$SEARCH_FOR'." + exit 1 + fi + local HAS_EXPECTED=$(echo "$FOUND" | grep "$EXPECTED") + if [ -z "$HAS_EXPECTED" ]; then + echo "'$FILENAME' differs with what is expected to have." + echo "Expected: $EXPECTED" + echo "Got: $FOUND" + exit 1 + fi +} + +# check distro release version. +NAXSI_VERSION=$(grep -R "NAXSI_VERSION" naxsi_src/ | cut -d '"' -f2) + +if [ -z "$NAXSI_VERSION" ]; then + echo "Cannot find NAXSI_VERSION in naxsi_src/" + exit 1 +fi + +check_file_for "distros/arch/PKGBUILD" "pkgver=" "$NAXSI_VERSION" +check_file_for "distros/alpine/1.18.0-r13/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION" +check_file_for "distros/alpine/1.20.1-r3/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION" +check_file_for "distros/alpine/1.20.2-r1/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION" +check_file_for "distros/alpine/1.22.1-r0/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION" +check_file_for "distros/alpine/1.18.0-r15/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION" +check_file_for "distros/alpine/1.20.2-r0/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION" +check_file_for "distros/alpine/1.22.0-r1/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION" +check_file_for "distros/alpine/1.24.0-r3/APKBUILD" "_add_module \"http-naxsi" "$NAXSI_VERSION" + +# check libinjection hash +SUBMODULE_HASH=$(git -C naxsi_src/libinjection rev-parse HEAD) +for DISTRO_YAML_HASH in $(grep "git -C naxsi_src/libinjection checkout" .github/workflows/distros.yaml | xargs -L1 echo | cut -d ' ' -f5); do + if [ "$DISTRO_YAML_HASH" != "$SUBMODULE_HASH" ]; then + echo "The libinjection hash in .github/workflows/distros.yaml does not match the submodule one." + echo "Expected: $SUBMODULE_HASH" + echo "Got: $DISTRO_YAML_HASH" + echo ".github/workflows/distros.yaml:" + grep -n "$DISTRO_YAML_HASH" .github/workflows/distros.yaml + exit 1 + fi +done diff --git a/dependencies/naxsi/.scripts/ci-rules-linter.sh b/dependencies/naxsi/.scripts/ci-rules-linter.sh new file mode 100755 index 0000000..1bfec5c --- /dev/null +++ b/dependencies/naxsi/.scripts/ci-rules-linter.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# SPDX-FileCopyrightText: 2022 wargio +# SPDX-License-Identifier: LGPL-3.0-only +RULE_FOLDER="$1" + +SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) +TMP_DIR="$SCRIPT_DIR/.tmp" +RET_VAL=0 + +if [ -z "$RULE_FOLDER" ]; then + echo "usage: $0 " + echo "example: $0 naxsi_rules/blocking" + exit 1 +fi + +if [[ -d "$TMP_DIR" ]]; then + rm -rf "$TMP_DIR" +fi + +mkdir "$TMP_DIR" || exit 1 +for FILE in $(ls "$RULE_FOLDER/"*.rules); do + FILENAME=$(basename $FILE) + echo "Linter: $FILE" + python "$SCRIPT_DIR/naxsi-lint.py" -r "$FILE" -o "$TMP_DIR/$FILENAME" || exit 1 + DIFF=$(diff -u "$FILE" "$TMP_DIR/$FILENAME") + if [[ ! -z "$DIFF" ]]; then + diff -u --color=auto "$FILE" "$TMP_DIR/$FILENAME" + RET_VAL=1 + fi +done + +rm -rf "$TMP_DIR" +exit $RET_VAL \ No newline at end of file diff --git a/dependencies/naxsi/.scripts/ci-test-perl.sh b/dependencies/naxsi/.scripts/ci-test-perl.sh new file mode 100755 index 0000000..5903488 --- /dev/null +++ b/dependencies/naxsi/.scripts/ci-test-perl.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# SPDX-FileCopyrightText: 2022 wargio +# SPDX-License-Identifier: LGPL-3.0-only + +RUN_TEST="$1" + +export NAXSI_CFG_PATH=$(realpath naxsi_rules/) +export NAXSI_TMP_PATH=$(realpath nginx-tmp/) +export NAXSI_TST_PATH=$(realpath unit-tests/) + +if [ -z "$NAXSI_CFG_PATH" ] || [ -z "$NAXSI_TMP_PATH" ] || [ -z "$NAXSI_TST_PATH" ] ; then + echo "did you run first ci-build.sh ?" + exit 1 +fi + +echo "############################" +echo " running tests" +echo "############################" + +cp -v "$NAXSI_TST_PATH/nginx-ci.conf" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" +openssl req -batch -x509 -nodes -days 365 -newkey rsa:2048 -keyout "$NAXSI_TMP_PATH/nginx.key" -out "$NAXSI_TMP_PATH/nginx.crt" + +export PATH="$NGINX_TMP_PATH/objs/:$PATH" +export TEST_NGINX_SERVROOT="$NAXSI_TMP_PATH/naxsi_ut/root" +export TEST_NGINX_BINARY="$NAXSI_TMP_PATH/sbin/nginx" +export TEST_NGINX_NAXSI_MODULE_SO="$NAXSI_TMP_PATH/naxsi_ut/modules/ngx_http_naxsi_module.so" +export TEST_NGINX_NAXSI_RULES="$NAXSI_CFG_PATH/naxsi_core.rules" +export TEST_NGINX_NAXSI_BLOCKING_RULES="$NAXSI_CFG_PATH/blocking" +export TEST_NGINX_NAXSI_WHITELISTS_RULES="$NAXSI_CFG_PATH/whitelists" + +cd "$NAXSI_TMP_PATH" + +if [ -z "$RUN_TEST" ]; then + prove -r "$NAXSI_TST_PATH/tests/"*.t +else + prove --verbose -r "$NAXSI_TST_PATH/tests/$RUN_TEST" +fi diff --git a/dependencies/naxsi/.scripts/ci-test.sh b/dependencies/naxsi/.scripts/ci-test.sh new file mode 100755 index 0000000..f9ef26e --- /dev/null +++ b/dependencies/naxsi/.scripts/ci-test.sh @@ -0,0 +1,33 @@ +#!/bin/sh +# SPDX-FileCopyrightText: 2022 wargio +# SPDX-License-Identifier: LGPL-3.0-only + +RUN_TEST="$1" + +if command -v python3 &> /dev/null ; then + PYTHON=python3 +elif command -v python &> /dev/null ; then + PYTHON=python +else + echo "Cannot find python.." + exit 1 +fi + +export NAXSI_CFG_PATH=$(realpath naxsi_rules/) +export NAXSI_TMP_PATH=$(realpath nginx-tmp/) +export NAXSI_TST_PATH=$(realpath unit-tests/) + +if [ -z "$NAXSI_CFG_PATH" ] || [ -z "$NAXSI_TMP_PATH" ] || [ -z "$NAXSI_TST_PATH" ] ; then + echo "did you run first ci-build.sh ?" + exit 1 +fi + +echo "############################" +echo " running tests" +echo "############################" + +cp -v "$NAXSI_TST_PATH/nginx-ci.conf" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" +openssl req -batch -x509 -nodes -days 365 -newkey rsa:2048 -keyout "$NAXSI_TMP_PATH/nginx.key" -out "$NAXSI_TMP_PATH/nginx.crt" + +$PYTHON .scripts/naxsi-gen-tests.py +$PYTHON -m unittest discover ./unit-tests/python/ $RUN_TEST -v diff --git a/dependencies/naxsi/.scripts/ci-wafefficacy.sh b/dependencies/naxsi/.scripts/ci-wafefficacy.sh new file mode 100755 index 0000000..d64ca92 --- /dev/null +++ b/dependencies/naxsi/.scripts/ci-wafefficacy.sh @@ -0,0 +1,116 @@ +#!/bin/sh +# SPDX-FileCopyrightText: 2023 wargio +# SPDX-License-Identifier: LGPL-3.0-only + +set -e + +WAFEFFICACY_VERSION="v1.0" +NUCLEI_VERSION="2.9.6" + +case "$1" in + "core" | "complete") + ;; + *) + if [ -z "$1" ]; then + echo "usage: $0 [mode]" + else + echo "error: invalid mode option '$1'." + fi + echo "supported modes:" + echo " - core test efficacy only against naxsi_core.rules" + echo " - complete test efficacy against all rules" + exit 1 + ;; +esac + +export NAXSI_CFG_PATH=$(realpath naxsi_rules) +export NAXSI_TMP_PATH=$(realpath nginx-tmp) +export NAXSI_DST_PATH=$(realpath distros/nginx) +export NAXSI_TST_PATH=$(realpath unit-tests/) +export NAXSI_VERSION=$(grep -R "NAXSI_VERSION" naxsi_src/ | cut -d '"' -f2) +export NAXSI_MODE="$1" + +check_for() { + if [ "$1" == "f" ] && [ ! -f "$2" ]; then + echo "file '$1' does not exist!" + exit 1 + elif [ "$1" == "d" ] && [ ! -d "$2" ]; then + echo "directory '$1' does not exist!" + exit 1 + fi +} + +if [ -z "$NAXSI_CFG_PATH" ] || [ -z "$NAXSI_TMP_PATH" ] || [ -z "$NAXSI_DST_PATH" ] ; then + echo "did you run first ci-build.sh ?" + exit 1 +fi + +if [ ! -d "$NAXSI_TMP_PATH/wafefficacy" ]; then + mkdir -p "$NAXSI_TMP_PATH/wafefficacy-tmp" + OLDPATH="$PWD" + cd "$NAXSI_TMP_PATH/wafefficacy-tmp" + # install wafefficacy + wget -O wafefficacy.zip "https://github.com/wargio/wafefficacy/releases/download/$WAFEFFICACY_VERSION/wafefficacy-linux-amd64.zip" + unzip wafefficacy.zip + mv -v wafefficacy-release "$NAXSI_TMP_PATH/wafefficacy" + cd "$OLDPATH" + rm -rf "$NAXSI_TMP_PATH/wafefficacy-tmp" +fi + +if [ ! -f "$NAXSI_TMP_PATH/sbin/nuclei" ]; then + mkdir -p "$NAXSI_TMP_PATH/nuclei-tmp" + OLDPATH="$PWD" + cd "$NAXSI_TMP_PATH/nuclei-tmp" + # install nuclei + wget -O nuclei.zip "https://github.com/projectdiscovery/nuclei/releases/download/v$NUCLEI_VERSION/nuclei_""$NUCLEI_VERSION""_linux_amd64.zip" + unzip nuclei.zip || sleep 0 + mv -v nuclei "$NAXSI_TMP_PATH/sbin/" + cd "$OLDPATH" + rm -rf "$NAXSI_TMP_PATH/nuclei-tmp" +fi + +echo "############################" +echo " running wafefficacy" +echo "############################" + +if [ ! -d "$NAXSI_TMP_PATH/naxsi_ut/logs" ]; then + mkdir -p "$NAXSI_TMP_PATH/naxsi_ut/logs" +fi + +WAFEFFICACY_NGINX_CONF=$(realpath "$NAXSI_TST_PATH/nginx-ci-wafefficacy.conf") +RULES_NGINX_NAXSI_BLOCKING=$(realpath "$NAXSI_CFG_PATH/blocking") +RULES_NGINX_NAXSI_CORE=$(realpath "$NAXSI_CFG_PATH/naxsi_core.rules") +RULES_NGINX_NAXSI_WHITELISTS=$(realpath "$NAXSI_CFG_PATH/whitelists") +TEST_NGINX_NAXSI_MODULE_SO=$(realpath "$NAXSI_TMP_PATH/naxsi_ut/modules/ngx_http_naxsi_module.so") + +check_for "f" "$WAFEFFICACY_NGINX_CONF" +check_for "f" "$TEST_NGINX_NAXSI_MODULE_SO" +check_for "f" "$RULES_NGINX_NAXSI_CORE" +check_for "d" "$RULES_NGINX_NAXSI_WHITELISTS" +check_for "d" "$RULES_NGINX_NAXSI_BLOCKING" + +cp -v "$WAFEFFICACY_NGINX_CONF" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" +sed -i "s#@RULES_NGINX_NAXSI_CORE@#include $RULES_NGINX_NAXSI_CORE;#g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" +sed -i "s#@TEST_NGINX_NAXSI_MODULE_SO@#$TEST_NGINX_NAXSI_MODULE_SO#g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" + +case "$1" in + "core") + sed -i "s#@RULES_NGINX_NAXSI_BLOCKING@##g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" + sed -i "s#@RULES_NGINX_NAXSI_WHITELISTS@##g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" + ;; + "complete") + sed -i "s#@RULES_NGINX_NAXSI_BLOCKING@#include $RULES_NGINX_NAXSI_BLOCKING/*;#g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" + sed -i "s#@RULES_NGINX_NAXSI_WHITELISTS@#include $RULES_NGINX_NAXSI_WHITELISTS/*;#g" "$NAXSI_TMP_PATH/naxsi_ut/nginx.conf" + ;; + *) + echo "error: invalid mode option '$1'." + exit 1 + ;; +esac + +cd "$NAXSI_TMP_PATH/wafefficacy" + +"$NAXSI_TMP_PATH/sbin/nginx" -p "$NAXSI_TMP_PATH/naxsi_ut/" & +PATH="$PATH:$NAXSI_TMP_PATH/sbin" ./run.sh -w "naxsi-$NAXSI_VERSION" -t localhost:4242 + +jobs -p | xargs kill \ No newline at end of file diff --git a/dependencies/naxsi/.scripts/ci-windows-build.bat b/dependencies/naxsi/.scripts/ci-windows-build.bat new file mode 100644 index 0000000..fb9a86f --- /dev/null +++ b/dependencies/naxsi/.scripts/ci-windows-build.bat @@ -0,0 +1,30 @@ +@echo off +rem SPDX-FileCopyrightText: 2022 Alex +rem SPDX-License-Identifier: LGPL-3.0-only + +@echo on + +set BAD_SLASH_SCRIPT_DIR=%~dp0 +set SCRIPT_DIR=%BAD_SLASH_SCRIPT_DIR:\=/% +set NAXSI_DIR=%SCRIPT_DIR%.. +set NW_DIR=%NAXSI_DIR%/../nginx-windows + +set NGINX_VERSION=%1 + +pushd .. || exit /b 1 +git clone --branch 1.22.1-1 https://github.com/noproxy-http/nginx-windows.git || exit /b 1 +popd || exit /b 1 + +pushd "%NW_DIR%" || exit /b 1 +git submodule update --init || exit /b 1 +popd || exit /b 1 + +pushd "%NW_DIR%/sources/nginx" || exit /b 1 +git checkout release-%NGINX_VERSION% || exit /b 1 +popd || exit /b 1 + +robocopy %NAXSI_DIR%/naxsi_src %NW_DIR%/modules/naxsi_src /e /nfl /ndl /njh /njs /nc /ns /np + +pushd "%NW_DIR%" || exit /b 1 +scripts\build.bat "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/vcvars64.bat" nossl +popd || exit /b 1 \ No newline at end of file diff --git a/dependencies/naxsi/.scripts/ci-windows-test.bat b/dependencies/naxsi/.scripts/ci-windows-test.bat new file mode 100644 index 0000000..4f41692 --- /dev/null +++ b/dependencies/naxsi/.scripts/ci-windows-test.bat @@ -0,0 +1,15 @@ +@echo off +rem SPDX-FileCopyrightText: 2022 Alex +rem SPDX-License-Identifier: LGPL-3.0-only + +@echo on + +set BAD_SLASH_SCRIPT_DIR=%~dp0 +set SCRIPT_DIR=%BAD_SLASH_SCRIPT_DIR:\=/% +set NAXSI_DIR=%SCRIPT_DIR%.. + +pushd "%NAXSI_DIR%" || exit /b 1 +python .scripts/naxsi-windows-test-dist.py %NAXSI_DIR%/../nginx-windows/build/dist || exit /b 1 +python .scripts/naxsi-gen-tests.py || exit /b 1 +python -m unittest discover unit-tests/python/ -v || exit /b 1 +popd || exit /b 1 \ No newline at end of file diff --git a/dependencies/naxsi/.scripts/naxsi-gen-tests.py b/dependencies/naxsi/.scripts/naxsi-gen-tests.py new file mode 100644 index 0000000..fa75c02 --- /dev/null +++ b/dependencies/naxsi/.scripts/naxsi-gen-tests.py @@ -0,0 +1,434 @@ +# -* coding: utf-8 +# SPDX-FileCopyrightText: 2022 Alex +# SPDX-License-Identifier: LGPL-3.0-only + +import os, sys +from collections import namedtuple +from os import path, replace +import re + +NginxTest = namedtuple("NginxTest", "filename name user_files main_config http_config config more_headers request raw_request curl curl_protocol curl_options error_code, error_log no_error_log response_body") + +unique_fun_names = set() + +def is_test_file(dirpath, filename): + if not filename.endswith(".t"): + return False + filepath = path.join(dirpath, filename) + return path.isfile(filepath) + +def read_list_of_test_files(test_file_or_dir): + if path.isfile(test_file_or_dir): + return [test_file_or_dir] + elif path.isdir(test_file_or_dir): + lst = os.listdir(test_file_or_dir) + filtered = list(filter(lambda f: is_test_file(test_file_or_dir, f), lst)) + filtered.sort() + return list(map(lambda f: path.join(test_file_or_dir, f), filtered)) + else: + print("ERROR: tests not found in directory: [{}]".format(test_file_or_dir)) + sys.exit(1) + +def collect_section(lines, idx, dest): + i = idx + 1 + while not lines[i].startswith("--- "): + dest.append(lines[i]) + i += 1 + return i + +def trim_test_lines(lines): + last_nonempty_idx = len(lines) + for i in reversed(range(len(lines))): + if len(lines[i]) == 0: + last_nonempty_idx = i + else: + break + return lines[:last_nonempty_idx] + +def parse_test(lines, test_file, line_num): + lines = trim_test_lines(lines) + if len(lines) == 0: + return None + filename = path.basename(test_file) + name = lines[0][4:].strip() + user_files = [] + main_config = [] + http_config = [] + config = [] + more_headers = [] + request = [] + raw_request = [] + curl = False + curl_protocol = "http" + curl_options = "" + error_code = 0 + error_log = [] + no_error_log = [] + response_body = [] + idx = 1 + if lines[idx].lstrip().startswith("--- user_files"): + idx = collect_section(lines, idx, user_files) + if lines[idx].lstrip().startswith("--- main_config"): + idx = collect_section(lines, idx, main_config) + if lines[idx].lstrip().startswith("--- main_config"): + idx = collect_section(lines, idx, main_config) + if lines[idx].lstrip().startswith("--- http_config"): + idx = collect_section(lines, idx, http_config) + if lines[idx].lstrip().startswith("--- user_files"): + idx = collect_section(lines, idx, user_files) + if lines[idx].lstrip().startswith("--- config"): + idx = collect_section(lines, idx, config) + if lines[idx].lstrip().startswith("--- more_headers"): + idx = collect_section(lines, idx, more_headers) + if lines[idx].lstrip().startswith("--- request"): + idx = collect_section(lines, idx, request) + if lines[idx].lstrip().startswith("--- raw_request"): + idx = collect_section(lines, idx, raw_request) + if lines[idx].lstrip().startswith("--- curl"): + curl = True + idx = idx + 1 + if lines[idx].lstrip().startswith("--- curl_protocol:"): + curl_protocol = lines[idx].strip()[len("--- curl_protocol:"):] + idx = idx + 1 + if lines[idx].lstrip().startswith("--- curl_options:"): + curl_options = lines[idx].strip()[len("--- curl_options:"):] + idx = idx + 1 + if not lines[idx].lstrip().startswith("--- error_code: "): + print("ERROR: Cannot parse test defintion, file: [{}], line: [{}]".format(test_file, line_num + idx - 2)) + sys.exit(1) + prefix_len = len("--- error_code:") + error_code = int(lines[idx].lstrip()[prefix_len:]) + if idx < len(lines) - 2 and lines[idx + 1].lstrip().startswith("--- error_log"): + idx += 2 + while idx < len(lines) and (not lines[idx].startswith("--- ") or lines[idx].startswith("=== ")): + error_log.append(lines[idx]) + idx += 1 + idx -= 1 + if idx < len(lines) - 2 and lines[idx + 1].lstrip().startswith("--- no_error_log"): + idx += 2 + while idx < len(lines) and (not lines[idx].startswith("--- ") or lines[idx].startswith("=== ")): + no_error_log.append(lines[idx]) + idx += 1 + idx -= 1 + if idx < len(lines) - 1 and lines[idx + 1].lstrip().startswith("--- response_body"): + idx+=1 + response_body.append(lines[idx][18:].strip()) + return NginxTest(filename, name, user_files, main_config, http_config, config, more_headers, request, raw_request, curl, curl_protocol, curl_options, error_code, error_log, no_error_log, response_body) + +def read_list_of_tests(test_file): + tests = [] + with open(test_file, encoding="utf-8") as file: + data_reached = False + test_lines = [] + line_num = 0 + for line in file: + line_num += 1 + stripped = line.rstrip() + if stripped.startswith("#"): + continue + if not data_reached: + if "__DATA__" == stripped: + data_reached = True + continue + if stripped.startswith("==="): + if len(test_lines) > 0: + test = parse_test(test_lines, test_file, line_num - len(test_lines)) + if test is not None: + tests.append(test) + test_lines = [] + test_lines.append(stripped) + if len(test_lines) > 0: + test = parse_test(test_lines, test_file, line_num - len(test_lines)) + if test is not None: + tests.append(test) + return tests + +def format_array_eval_line(line): + line = line[2:-2].strip() + elems = line.split(",") + for i in range(len(elems)): + elems[i] = elems[i].strip() + xidx = elems[i].find("\"x") + if xidx > 0: + base = elems[i][1:xidx] + count = int(elems[i][xidx+2:]) + elems[i] = "" + for j in range(count): + elems[i] += base + else: + elems[i] = elems[i][1:-1] + return "".join(elems) + +def format_test_lines(test): + for i in range(len(test.http_config)): + test.http_config[i] = test.http_config[i].replace("\\", "\\\\") + test.http_config[i] = " {}".format(test.http_config[i]) + for i in range(len(test.config)): + test.config[i] = " {}".format(test.config[i]) + request_lines_to_pop = [] + for i in range(len(test.request)): + line = test.request[i] + if line.lstrip().startswith("use "): + request_lines_to_pop.append(i) + if line.startswith("[[") and line.endswith("]]"): + test.request[i] = format_array_eval_line(line) + for idx in request_lines_to_pop: + test.request.pop(idx) + if len(test.request) > 0 and test.request[0].startswith("\""): + test.request[0] = test.request[0][1:] + test.request[-1] = test.request[-1][:-1] + for i in range(len(test.request)): + line = test.request[i] + test.request[i] = line.replace("\\\"", "\"").replace("\x00", "\\x00") + if len(test.raw_request) > 0 and test.raw_request[0].startswith("\""): + test.raw_request[0] = test.raw_request[0][1:] + test.raw_request[-1] = test.raw_request[-1][:-1] + for i in range(len(test.raw_request)): + line = test.raw_request[i] + test.raw_request[i] = line.replace("\\\"", "\"") + if len(test.error_log) > 0: + el = test.error_log + for i in range(len(el)): + if el[i].startswith("["): + el[i] = el[i][1:].lstrip() + if el[i].startswith("qr@"): + el[i] = el[i][3:].lstrip() + if el[i].endswith("]"): + el[i] = el[i][:-1].rstrip() + if el[i].endswith(","): + el[i] = el[i][:-1].rstrip() + if el[i].endswith("@"): + el[i] = el[i][:-1].rstrip() + el[i] = el[i].replace("server=localhost", "server=127.0.0.1") + if len(el[-1]) == 0: + el.pop() + if len(test.response_body) > 0: + for i in range(len(test.response_body)): + test.response_body[i] = test.response_body[i].replace("localhost", "127.0.0.1") + +def hotpatch_test(test): + if "TEST 24: Testing MULTIPART POSTs" == test.name: + test.more_headers[1] = test.more_headers[1].replace( + "Content-Length: 355", + "Content-Length: 353", + ) + +def parse_req_method(req): + space_idx = req[0].find(" ") + return req[0][:space_idx] + +def parse_req_data(req, method): + if method not in ["POST", "PATCH"]: + return None + rn_idx = req[0].find("\\r\\n") + inline = "" + if rn_idx > 0: + inline = req[0][rn_idx:] + res = inline + if len(req) > 1: + res += "\n".join(req[1:]) + if res.startswith("\\r\\n"): + res = res[4:] + if res.endswith("\\r\\n\\r\\n"): + res = res[:-8] + return res + +def parse_req_url(req): + space_idx = req[0].find(" ") + rn_idx = req[0].find("\\r\\n") + if rn_idx > 0: + return req[0][space_idx + 1:rn_idx] + else: + return req[0][space_idx + 1:] + +def parse_headers(more_headers): + headers = {} + for line in more_headers: + idx = line.find(": ") + name = line[:idx] + value = line[idx + 2:] + headers[name] = value + return headers + +def parse_user_files(user_files): + res = {} + name = None + for line in user_files: + stripped = line.strip() + if stripped.startswith(">>> "): + name = stripped[4:] + res[name] = "" + else: + res[name] += line + return res + +def gen_file_header(test_file_name_noext): + cls_name = test_file_name_noext[2:].replace("-", "_") + return """# -* coding: utf-8 +# SPDX-FileCopyrightText: NAXSI project +# SPDX-License-Identifier: LGPL-3.0-only + +import unittest +from _test_utils import nginx_runner + +class {}(unittest.TestCase):""".format(cls_name) + +def gen_function_header(test): + fun_name = test.name.strip() + fun_name = re.sub(r'[^a-zA-Z\d_]', '_', fun_name) + if not fun_name.startswith("test_"): + fun_name = "test_{}".format(fun_name) + while fun_name in unique_fun_names: + fun_name += "_" + unique_fun_names.add(fun_name) + docstring = test.name.replace("\\x", "\\\\x") + return ''' + def {}(self): + """ + {} + """'''.format(fun_name, docstring) + +def gen_runner_init(test): + res = ''' with nginx_runner(''' + if len(test.http_config) > 0: + http_config = "\n".join(test.http_config) + res += ''' + http_config=""" +{} + """,'''.format(http_config) + if len(test.config) > 0: + config = "\n".join(test.config) + res += ''' + config=""" +{} + """,'''.format(config) + if len(test.user_files) > 0: + res += ''' + user_files={''' + files = parse_user_files(test.user_files) + for name, value in files.items(): + res += ''' + "{}": "{}",'''.format(name, value) + res += ''' + },''' + res += ''' + ) as nr:''' + return res; + +def gen_request(test): + if len(test.response_body) > 0: + res = ''' ec, resp_body = nr.request(''' + else: + res = ''' ec = nr.request(''' + url = parse_req_url(test.request).replace("\"", "\\\"") + res += ''' + url="{}",'''.format(url) + method = parse_req_method(test.request) + if "GET" != method: + res += ''' + method="{}",'''.format(method) + if len(test.more_headers) > 0: + res += ''' + headers={''' + headers = parse_headers(test.more_headers) + for name, value in headers.items(): + res += ''' + "{}": "{}",'''.format(name, value) + res += ''' + },''' + data = parse_req_data(test.request, method) + if data is not None: + res += ''' + data="""{}""",'''.format(data) + if test.curl: + res += ''' + curl=True,''' + if len(test.curl_protocol) > 0: + res += ''' + curl_protocol="{}",'''.format(test.curl_protocol) + if len(test.curl_options) > 0: + res += ''' + curl_options="{}",'''.format(test.curl_options) + if len(test.response_body) > 0: + res += ''' + resp_body_required=True''' + res += ''' + )'''. format(test.error_code) + return res + +def gen_raw_request(test): + raw_req = "\n".join(test.raw_request) + return ''' ec = nr.raw_request(""" +{}""")'''.format(raw_req) + +def gen_checks(test): + res = " self.assertEqual(ec, {})".format(test.error_code) + if len(test.error_log) > 0: + res += ''' + elm = nr.error_log_matches([''' + for line in test.error_log: + line = line.replace("\"", "\\\"") + res += ''' + r"{}",'''.format(line) + res += ''' + ]) + self.assertTrue(elm)''' + if len(test.no_error_log) > 0: + res += ''' + nelm = nr.error_log_matches([''' + for line in test.no_error_log: + line = line.replace("\"", "\\\"") + res += ''' + r"{}",'''.format(line) + res += ''' + ]) + self.assertFalse(nelm)''' + if len(test.response_body) > 0: + response_body = "\n".join(test.response_body) + res += ''' + self.assertEqual(resp_body, """{}""".encode("utf-8"))'''.format(response_body) + return res + +def gen_test_function(test): + header = gen_function_header(test) + runner = gen_runner_init(test) + if len(test.request) > 0: + send_req = gen_request(test) + else: + send_req = gen_raw_request(test) + checks = gen_checks(test) + return ''' +{} +{} +{} +{}'''.format(header, runner, send_req, checks) + +def write_python_test_file(test_file_name, test_list): + scripts_dir = path.dirname(__file__) + naxsi_dir = path.dirname(scripts_dir) + dest_dir = path.join(naxsi_dir, "unit-tests", "python") + test_file_name_noext = path.splitext(test_file_name)[0] + test_file_name_nodash = test_file_name_noext.replace("-", "_") + dest_file_name = "test_{}.py".format(test_file_name_nodash) + dest_file_path = path.join(dest_dir, dest_file_name) + if path.exists(dest_file_path): + os.remove(dest_file_path) + with open(dest_file_path, "w", encoding="utf-8") as file: + file.write(gen_file_header(test_file_name_noext)) + for test in test_list: + hotpatch_test(test) + format_test_lines(test) + file.write(gen_test_function(test)) + file.write("\n") + + +if __name__ == "__main__": + scripts_dir = path.dirname(__file__) + naxsi_dir = path.dirname(scripts_dir) + tests_dir = path.join(naxsi_dir, "unit-tests", "tests") + test_files_list = read_list_of_test_files(tests_dir) + for test_file_path in test_files_list[:]: + unique_fun_names.clear() + test_list = read_list_of_tests(test_file_path) + test_file_name = path.basename(test_file_path) + write_python_test_file(test_file_name, test_list[:]) \ No newline at end of file diff --git a/dependencies/naxsi/.scripts/naxsi-lint.py b/dependencies/naxsi/.scripts/naxsi-lint.py new file mode 100644 index 0000000..ce35875 --- /dev/null +++ b/dependencies/naxsi/.scripts/naxsi-lint.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python3 +# SPDX-FileCopyrightText: 2022 deroad +# SPDX-License-Identifier: LGPL-3.0-only + +import argparse +import sys +import re +import shlex + +DESCRIPTION='Naxsi Rule Linter' +EPILOG=''' +This tool lints naxsi rules +Example: + $ python naxsi-lint.py --rule /path/to/file.rules --output output.rules --begin-id 4200000 +''' + +def clean_token(token): + if not token.startswith('"'): + return token + return token[1:-1] + +def find_keyword(keyword, tokens): + for token in tokens: + token = clean_token(token) + if token.startswith(keyword): + return token + return None + + +class Rule(object): + def __init__(self, tokens, line_num, comments): + super(Rule, self).__init__() + self.line_num = line_num + self.comments = comments + self.main_rule = find_keyword("MainRule", tokens) + self.basic_rule = find_keyword("BasicRule", tokens) + self.id = find_keyword("id:", tokens) + self.msg = find_keyword("msg:", tokens) + self.str = find_keyword("str:", tokens) + self.rx = find_keyword("rx:", tokens) + self.mz = find_keyword("mz:", tokens) + self.s = find_keyword("s:", tokens) + self.wl = find_keyword("wl:", tokens) + self.d = find_keyword("d:libinj_", tokens) + self.negative = find_keyword("negative", tokens) + + # validate first + self.validate() + + if self.wl != None: + ids = list(set(self.wl[3:].split(','))) + ids.sort() + self.wl = 'wl:' + ','.join(ids) + else: + self.id = int(self.id[3:]) + if self.msg != None: + self.msg = re.sub(r'\s+', ' ', self.msg.strip()) + self.msg = re.sub(r'"', '\'', self.msg.strip()) + + def validate(self): + if self.main_rule == None and self.basic_rule == None: + print("ERROR: {}: missing 'MainRule' or 'BasicRule' prefix".format(self.line_num)) + sys.exit(1) + if self.main_rule != None and self.basic_rule != None: + print("ERROR: {}: 'MainRule' and 'BasicRule' are set".format(self.line_num)) + sys.exit(1) + + if self.id == None and self.wl == None: + print("ERROR: {}: missing 'id:' or 'wl:'".format(self.line_num)) + sys.exit(1) + elif self.id != None and self.wl != None: + print("ERROR: {}: 'id:' and 'wl:' are both set".format(self.line_num)) + sys.exit(1) + + if self.is_whitelist(): + if self.mz == None: + print("ERROR: {}: missing whitelist 'mz:'".format(self.line_num)) + sys.exit(1) + elif self.str != None: + print("ERROR: {}: 'str:' is set for a whitelist".format(self.line_num)) + sys.exit(1) + elif self.rx != None: + print("ERROR: {}: 'rx:' is set for a whitelist".format(self.line_num)) + sys.exit(1) + elif self.d != None: + print("ERROR: {}: 'd:' is set for a whitelist".format(self.line_num)) + sys.exit(1) + else: + self.match() + if self.mz == None: + print("ERROR: {}: missing rule 'mz:'".format(self.line_num)) + sys.exit(1) + if self.s == None: + print("ERROR: {}: missing rule 's:'".format(self.line_num)) + sys.exit(1) + + def prefix(self): + return self.main_rule if self.main_rule != None else self.basic_rule + + def match(self): + if self.rx != None: + return self.rx + elif self.str != None: + return self.str + elif self.d != None: + return self.d + print("ERROR: {}: missing rule 'rx:' or 'str:' or 'd:'".format(self.line_num)) + sys.exit(1) + + def is_whitelist(self): + return self.wl != None + + def message(self): + if self.msg == None: + return "match " + self.match().replace('"', '') + return self.msg[4:] + + def print(self): + if len(self.comments) > 0: + print('\n'.join(self.comments)) + prefix = self.prefix() + args = [] + if self.is_whitelist(): + args = [ + self.wl, + self.negative, + '"{}"'.format(self.mz), + '"{}"'.format(self.msg), + ] + else: + args = [ + 'id:{}'.format(self.id), + '"{}"'.format(self.s), + self.negative, + '"{}"'.format(self.match()), + '"{}"'.format(self.mz), + '"{}"'.format(self.msg), + ] + args = list(filter(lambda x: x != None and x != '"None"', args)) + print("{} {};".format(self.prefix(), ' '.join(args))) + +def parse_file(filename, rules, whitelists, ruleid): + lines = [] + with open(filename, 'r') as fp: + lines = fp.readlines() + + line_num = 0 + comments = [] + for line in lines: + line_num += 1 + line = line.strip() + if line.startswith("#") or len(line) < 1: + comments.append(line) + continue + elif '#' in line and not '#"' in line and not line.endswith(';'): + comments.append('#' + line.split('#', 1)[-1]) + line = line.split('#')[0] + + if not line.endswith(';'): + print("ERROR: {}: missing ; at the end the line '{}'".format(line_num, line)) + sys.exit(1) + + line = re.sub(r';$', " ;", line) + tokens = shlex.split(line, posix=False) + # print("{}: {}".format(line_num, tokens)) + + rule = Rule(tokens, line_num, comments) + comments = [] + + if rule.is_whitelist(): + whitelists.append(rule) + continue + + if ruleid > 100: + rule.id = ruleid + ruleid += 1 + elif rule.id in rules: + print("ERROR: {}: Rule {} already exists at line {}".format(line_num, rule.id, rules[rule.id].line_num)) + sys.exit(1) + + rules[rule.id] = rule + +def print_rules(rules_ids, rules, whitelists): + header = len(rules_ids) < 1 + if len(whitelists) > 0: + for whitelist in whitelists: + if not header: + header = True + print('#############') + print("# Whitelist #") + print('#############') + whitelist.print() + + for idx in rules_ids: + if header: + header = False + print('#########') + print("# Rules #") + print('#########') + rules[idx].print() + +def print_translate_dictionary(rules_ids, rules, whitelists): + for idx in rules_ids: + print('"{}","{}"'.format(rules[idx].id, rules[idx].message())) + +output_formats = { + 'rules': print_rules, + 'logstash_translate_dictionary': print_translate_dictionary, +} + +def main(): + parser = argparse.ArgumentParser(usage='%(prog)s [options]', description=DESCRIPTION, epilog=EPILOG, formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument('-r', '--rule', default='', help='source rule to parse') + parser.add_argument('-o', '--output', default='', help='path to the output file') + parser.add_argument('-f', '--format', default='rules', help='format of the output file ({})'.format(','.join(list(output_formats.keys())))) + parser.add_argument('-b', '--begin-id', default=0, type=int, help='rebase all rules ids from this id number (id must be > 100)') + args = parser.parse_args() + + if len(sys.argv) == 1 or \ + len(args.rule) < 1 or \ + len(args.output) < 1 or \ + len(args.format) < 1 or \ + args.format not in output_formats or \ + (args.begin_id != 0 and args.begin_id <= 100): + parser.print_help(sys.stderr) + sys.exit(1) + + rules = {} + whitelists = [] + + parse_file(args.rule, rules, whitelists, args.begin_id) + + rules_ids = list(rules.keys()) + rules_ids.sort() + + file_format = output_formats[args.format] + + fd = sys.stdout + if args.output != '-': + sys.stdout = open(args.output, 'w') + + file_format(rules_ids, rules, whitelists) + + if args.output != '-': + sys.stdout.close() + sys.stdout = fd + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/dependencies/naxsi/.scripts/naxsi-windows-test-dist.py b/dependencies/naxsi/.scripts/naxsi-windows-test-dist.py new file mode 100644 index 0000000..d0d72e9 --- /dev/null +++ b/dependencies/naxsi/.scripts/naxsi-windows-test-dist.py @@ -0,0 +1,30 @@ +# -* coding: utf-8 +# SPDX-FileCopyrightText: 2022 Alex +# SPDX-License-Identifier: LGPL-3.0-only + +import os, shutil, sys +from os import path + +if __name__ == "__main__": + if 2 != len(sys.argv): + print("ERROR: The path to Nginx dist must be specified as a first and only argument") + sys.exit(1) + src = sys.argv[1] + if not path.isdir(src): + print("ERROR: Nginx dist not found on the specified path: [{}]".format(src)) + sys.exit(1) + scripts_dir = path.dirname(__file__) + naxsi_dir = path.dirname(scripts_dir) + nginx_dir = path.join(naxsi_dir, "nginx-tmp") + if path.exists(nginx_dir): + shutil.rmtree(nginx_dir) + os.mkdir(nginx_dir) + shutil.copytree(path.join(src, "conf"), path.join(nginx_dir, "conf")) + os.remove(path.join(nginx_dir, "conf", "nginx.conf")) + shutil.copytree(path.join(src, "logs"), path.join(nginx_dir, "logs")) + shutil.copytree(path.join(src, "temp"), path.join(nginx_dir, "temp")) + os.mkdir(path.join(nginx_dir, "html")) + with open(path.join(nginx_dir, "html", "index.html"), "w", encoding="utf-8") as file: + file.write("Hello Nginx!") + shutil.copy(path.join(src, "nginx.exe"), nginx_dir) + print("Test Nginx dist prepared successfully"); \ No newline at end of file diff --git a/dependencies/naxsi/LICENSE b/dependencies/naxsi/LICENSE new file mode 100644 index 0000000..9cecc1d --- /dev/null +++ b/dependencies/naxsi/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/dependencies/naxsi/LICENSES/GPL-3.0-or-later.txt b/dependencies/naxsi/LICENSES/GPL-3.0-or-later.txt new file mode 100644 index 0000000..d41c0bd --- /dev/null +++ b/dependencies/naxsi/LICENSES/GPL-3.0-or-later.txt @@ -0,0 +1,232 @@ +GNU GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright © 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +Preamble + +The GNU General Public License is a free, copyleft license for software and other kinds of works. + +The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. + +Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. + +Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and modification follow. + +TERMS AND CONDITIONS + +0. Definitions. + +“This License” refers to version 3 of the GNU General Public License. + +“Copyright” also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. + +“The Program” refers to any copyrightable work licensed under this License. Each licensee is addressed as “you”. “Licensees” and “recipients” may be individuals or organizations. + +To “modify” a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a “modified version” of the earlier work or a work “based on” the earlier work. + +A “covered work” means either the unmodified Program or a work based on the Program. + +To “propagate” a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. + +To “convey” a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays “Appropriate Legal Notices” to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. + +1. Source Code. +The “source code” for a work means the preferred form of the work for making modifications to it. “Object code” means any non-source form of a work. + +A “Standard Interface” means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. + +The “System Libraries” of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A “Major Component”, in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. + +The “Corresponding Source” for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same work. + +2. Basic Permissions. +All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. +No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. + +When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. + +4. Conveying Verbatim Copies. +You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. +You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to “keep intact all notices”. + + c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. + +A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an “aggregate” if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. + +6. Conveying Non-Source Forms. +You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: + + a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. + + d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. + +A “User Product” is either (1) a “consumer product”, which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, “normally used” refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. + +“Installation Information” for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. + +If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). + +The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. + +7. Additional Terms. +“Additional permissions” are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or authors of the material; or + + e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. + +All other non-permissive additional terms are considered “further restrictions” within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. + +8. Termination. +You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). + +However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. + +Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. + +9. Acceptance Not Required for Having Copies. +You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. +Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. + +An “entity transaction” is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. + +11. Patents. +A “contributor” is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's “contributor version”. + +A contributor's “essential patent claims” are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, “control” includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. + +In the following three paragraphs, a “patent license” is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To “grant” such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. + +If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. “Knowingly relying” means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. + +A patent license is “discriminatory” if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. +If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. +Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. + +14. Revised Versions of this License. +The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License “or any later version” applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. + +Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. + +15. Disclaimer of Warranty. +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. +If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the “copyright” line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an “about box”. + +You should also get your employer (if you work as a programmer) or school, if any, to sign a “copyright disclaimer” for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . + +The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . diff --git a/dependencies/naxsi/LICENSES/LGPL-3.0-only.txt b/dependencies/naxsi/LICENSES/LGPL-3.0-only.txt new file mode 100644 index 0000000..c9287dd --- /dev/null +++ b/dependencies/naxsi/LICENSES/LGPL-3.0-only.txt @@ -0,0 +1,71 @@ +GNU LESSER GENERAL PUBLIC LICENSE +Version 3, 29 June 2007 + +Copyright (C) 2007 Free Software Foundation, Inc. + +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. + +This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. + +0. Additional Definitions. + +As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU General Public License. + +"The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined below. + +An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by the Library. + +A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of the Library with which the Combined Work was made is also called the "Linked Version". + +The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not on the Linked Version. + +The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application, including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the System Libraries of the Combined Work. + +1. Exception to Section 3 of the GNU GPL. +You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL. + +2. Conveying Modified Versions. +If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may convey a copy of the modified version: + + a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy. + +3. Object Code Incorporating Material from Library Header Files. +The object code form of an Application may incorporate material from a header file that is part of the Library. You may convey such object code under terms of your choice, provided that, if the incorporated material is not limited to numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates (ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its use are covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license document. + +4. Combined Works. +You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications, if you also do each of the following: + + a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its use are covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license document. + + c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this License, and the Corresponding Application Code in a form suitable for, and under terms that permit, the user to recombine or relink the Application with a modified version of the Linked Version to produce a modified Combined Work, in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (a) uses at run time a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked Version. + + e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner specified by section 6 of the GNU GPL for conveying Corresponding Source.) + +5. Combined Libraries. +You may place library facilities that are a work based on the Library side by side in a single library together with other library facilities that are not Applications and are not covered by this License, and convey such a combined library under terms of your choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities, conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. + +6. Revised Versions of the GNU Lesser General Public License. +The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library as you received it specifies that a certain numbered version of the GNU Lesser General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that published version or of any later version published by the Free Software Foundation. If the Library as you received it does not specify a version number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License ever published by the Free Software Foundation. + +If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is permanent authorization for you to choose that version for the Library. diff --git a/dependencies/naxsi/README.md b/dependencies/naxsi/README.md new file mode 100644 index 0000000..cc61866 --- /dev/null +++ b/dependencies/naxsi/README.md @@ -0,0 +1,86 @@ +![naxsi](logo.png) + +## Documentation + +Updated documentation is available [here](https://wargio.github.io/naxsi/). + +## What is Naxsi? + +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). + +Technically, it is a third party nginx module, available as a package for +many UNIX-like platforms. This module, by default, reads a small subset of +simple (and readable) rules containing 99% of known patterns involved in +website vulnerabilities. For example, `<`, `|` or `drop` are not supposed +to be part of a URI. + +Being very simple, those patterns may match legitimate queries, it is +the Naxsi's administrator duty to add specific rules that will whitelist +legitimate behaviours. The administrator can either add whitelists manually +by analyzing nginx's error log, or (recommended) start the project with an +intensive auto-learning phase that will automatically generate whitelisting +rules regarding a website's behaviour. + +In short, Naxsi behaves like a DROP-by-default firewall, the only task +is to add required ACCEPT rules for the target website to work properly. + +## Why is it different? + +Contrary to most Web Application Firewalls, Naxsi doesn't rely on a +signature base like an antivirus, and thus cannot be circumvented by an +"unknown" attack pattern. +Naxsi is [Free software](https://www.gnu.org/licenses/gpl.html) (as in freedom) +and free (as in free beer) to use. + +## What does it run on? +Naxsi should be compatible with any nginx version. + +It depends on `libpcre` for its regexp support, and is reported to work great on NetBSD, FreeBSD, OpenBSD, Debian, Ubuntu and CentOS. + +## Why using this repository + +The original project is **officially** abandoned (and has been archived the 8th Nov 2023), but you can fully ask for support here as i'm willing to keep the project working as last remaining developer. + +## Build naxsi + +**Be sure when you clone the repository to fetch all the submodules.** + +``` +$ git clone --recurse-submodules https://github.com/wargio/naxsi.git +$ wget --no-clobber -O nginx.tar.gz "https://nginx.org/download/nginx-1.22.0.tar.gz" +$ mkdir nginx-source +$ tar -C nginx-source -xzf nginx.tar.gz --strip-components=1 +$ cd nginx-source +$ ./configure --prefix=/etc/nginx --add-dynamic-module=../naxsi/naxsi_src +$ make +``` + +# Support & Bugs + +Questions & bug reports regarding NAXSI can be addressed via issues. + +[Click here to open an issue](https://github.com/wargio/naxsi/issues/new) + +# Vulnerability disclosure + +When disclosing vulnerabilities, please send first an email to `deroad at kumo.xn--q9jyb4c` (gpg keyid: `29656E856786B9A1FBF983CFA219F52A8217B1FE`) + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- +mDMEXR3FZhYJKwYBBAHaRw8BAQdAfuSDE68TEppjJfUAApXSTsHrKtGefVJXvz7f +YIO0gci0MUdpb3Zhbm5pIERhbnRlIEdyYXppb2xpIDxkZXJvYWRAa3Vtby54bi0t +cTlqeWI0Yz6IkAQTFggAOAIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBCll +boVnhrmh+/mDz6IZ9SqCF7H+BQJg9+CGAAoJEKIZ9SqCF7H+X04BAPXz7R856z72 +f8nsZZjj4q3YaJbXA3pSVLIJ9uDQniCsAP9PaPBcbr231M3cjjBMo7ovlrElfFor +zCWA3NhRb4Y2DLg4BF0dxWYSCisGAQQBl1UBBQEBB0AVby+EIQcIoqSDZelvkqt8 +dV1kvF4f/J0jj0k3OEKNcAMBCAeIeAQYFggAIAIbDBYhBCllboVnhrmh+/mDz6IZ +9SqCF7H+BQJg9+C4AAoJEKIZ9SqCF7H+ZfQBAOFb7iZm7t8j5ymiXyJFcuM/nF9+ +bx4+KJJUTR9r6zBFAQD3Ea5Ya4lny/v9WKNSpBfZFEs3pkDnfgxw3o8vc4iSAQ== +=d/IR +-----END PGP PUBLIC KEY BLOCK----- +``` + +## Future plans + +- Bring back nxapi using python3 +- Creation of a simple tool to create rules and test them diff --git a/dependencies/naxsi/REUSE.toml b/dependencies/naxsi/REUSE.toml new file mode 100644 index 0000000..98b4948 --- /dev/null +++ b/dependencies/naxsi/REUSE.toml @@ -0,0 +1,64 @@ +version = 1 +SPDX-PackageName = "Naxsi WAF" +SPDX-PackageSupplier = "deroad " +SPDX-PackageDownloadLocation = "https://github.com/wargio/naxsi" + +[[annotations]] +path = ".github/**" +precedence = "aggregate" +SPDX-FileCopyrightText = "2022 deroad " +SPDX-License-Identifier = "LGPL-3.0-only" + +[[annotations]] +path = ".clang-format" +precedence = "aggregate" +SPDX-FileCopyrightText = "2022 deroad " +SPDX-License-Identifier = "LGPL-3.0-only" + +[[annotations]] +path = [".gitignore", ".gitmodules"] +precedence = "aggregate" +SPDX-FileCopyrightText = "2022 deroad " +SPDX-License-Identifier = "LGPL-3.0-only" + +[[annotations]] +path = "distros/**" +precedence = "aggregate" +SPDX-FileCopyrightText = "2022 deroad " +SPDX-License-Identifier = "LGPL-3.0-only" + +[[annotations]] +path = "naxsi_rules/**" +precedence = "aggregate" +SPDX-FileCopyrightText = "2022 deroad " +SPDX-License-Identifier = "LGPL-3.0-only" + +[[annotations]] +path = ["README.md", ".gitattributes", "logo.png"] +precedence = "aggregate" +SPDX-FileCopyrightText = "2019 nbs-system " +SPDX-License-Identifier = "GPL-3.0-or-later" + +[[annotations]] +path = "naxsi_rules/naxsi_core.rules" +precedence = "aggregate" +SPDX-FileCopyrightText = "2019 nbs-system " +SPDX-License-Identifier = "GPL-3.0-or-later" + +[[annotations]] +path = "unit-tests/**" +precedence = "aggregate" +SPDX-FileCopyrightText = ["2019 nbs-system \\", "2022 deroad "] +SPDX-License-Identifier = "GPL-3.0-or-later" + +[[annotations]] +path = "docs/**.md" +precedence = "aggregate" +SPDX-FileCopyrightText = "2022 deroad " +SPDX-License-Identifier = "LGPL-3.0-only" + +[[annotations]] +path = "docs/old**" +precedence = "aggregate" +SPDX-FileCopyrightText = "2019 nbs-system " +SPDX-License-Identifier = "GPL-3.0-or-later" diff --git a/dependencies/naxsi/distros/alpine/1.18.0-r13/APKBUILD b/dependencies/naxsi/distros/alpine/1.18.0-r13/APKBUILD new file mode 100644 index 0000000..abcf13c --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.18.0-r13/APKBUILD @@ -0,0 +1,220 @@ +# Maintainer: Giovanni Dante Grazioli +pkgname=nginx +pkgver=1.18.0 +pkgrel=13 +pkgdesc="HTTP and reverse proxy server (stable version)" +url="https://www.nginx.org/" +arch="all" +license="BSD-2-Clause" +depends="" +makedepends=" + brotli-dev + gd-dev + geoip-dev + libmaxminddb-dev + libxml2-dev + libxslt-dev + linux-headers + luajit-dev + openssl-dev + pcre-dev + perl-dev + pkgconf + zlib-dev + " +checkdepends=" + gd + perl + perl-fcgi + perl-io-socket-ssl + perl-net-ssleay + perl-protocol-websocket + tzdata + uwsgi-python3 + " +pkgusers="nginx" +_grp_ngx="nginx" +_grp_www="www-data" +pkggroups="$_grp_ngx $_grp_www" +install="" +subpackages="" +source="https://nginx.org/download/$pkgname-$pkgver.tar.gz" +builddir="$srcdir/$pkgname-$pkgver" + +_modules_dir="usr/lib/$pkgname/modules" + +# For simplicity we assume that module is hosted on GitHub. +_add_module() { + local name="$1" ver="$2" url="$3" subdir="$4" + local dirname=${url##*/}-${ver#v} + local varprefix="_${name//-/_}" + + eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'" + + # Don't add new flag and source if it's already there, i.e. two or more + # modules share the same source (e.g. geoip2 that provides http-geoip2 + # and stream-geoip2). + if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then + _module_path=$(realpath ../../../$subdir) + _extra_flags="$_extra_flags --add-dynamic-module=$_module_path" + fi + subpackages="$subpackages $pkgname-mod-$name:_module" +} + +_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src" +_naxsi_provides="$pkgname-naxsi" # for backward compatibility + +prepare() { + local file; for file in $source; do + file=${file%%::*} + + case $file in + *~*.patch) + msg $file + cd "$srcdir"/${file%%~*}-* + patch -p 1 -i "$srcdir/$file" + ;; + *.patch) + msg $file + cd "$builddir" + patch -p 1 -i "$srcdir/$file" + ;; + esac + done +} + +_build() { + ./configure \ + --prefix=/var/lib/$pkgname \ + --sbin-path=/usr/sbin/$pkgname \ + --modules-path=/$_modules_dir \ + --conf-path=/etc/$pkgname/$pkgname.conf \ + --pid-path=/run/$pkgname/$pkgname.pid \ + --lock-path=/run/$pkgname/$pkgname.lock \ + --http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \ + --http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \ + --http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \ + --http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \ + --http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \ + --with-perl_modules_path=/usr/lib/perl5/vendor_perl \ + \ + --user=$pkgusers \ + --group=$_grp_ngx \ + --with-threads \ + --with-file-aio \ + \ + --with-http_ssl_module \ + --with-http_v2_module \ + --with-http_realip_module \ + --with-http_addition_module \ + --with-http_xslt_module=dynamic \ + --with-http_image_filter_module=dynamic \ + --with-http_geoip_module=dynamic \ + --with-http_sub_module \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_mp4_module \ + --with-http_gunzip_module \ + --with-http_gzip_static_module \ + --with-http_auth_request_module \ + --with-http_random_index_module \ + --with-http_secure_link_module \ + --with-http_degradation_module \ + --with-http_slice_module \ + --with-http_stub_status_module \ + --with-http_perl_module=dynamic \ + --with-mail=dynamic \ + --with-mail_ssl_module \ + --with-stream=dynamic \ + --with-stream_ssl_module \ + --with-stream_realip_module \ + --with-stream_geoip_module=dynamic \ + --with-stream_ssl_preread_module \ + \ + $_extra_flags \ + "$@" + + make -j +} + +build() { + cd "$builddir" + + _build --with-debug + mv objs objs-debug + + make clean + _build +} + +check() { + msg "Ignore nginx tests..." +} + +package() { + cd "$builddir" + + make DESTDIR="$pkgdir" install +} + +debug() { + return +} + +vim() { + return +} + +_module() { + local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}" + local ver=$(getvar _${name}_ver) + + pkgdesc="Nginx module ${name//_/-}" + [ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)" + + url=$(getvar "_${name}_url" "$url") + sonames=$(getvar "_${name}_so" "ngx_${name}_module.so") + depends="$pkgname $(getvar "_${name}_depends")" + provides=$(getvar "_${name}_provides") + + # Numeric prefix for the module config to ensure that modules with + # dependencies on other modules will be loaded after their dependencies. + # For simplicity, we don't actually resolve dependency tree. Instead, + # we just prefix the module name with a number that reflects number of + # the module's dependencies times ten (e.g. 10, 20, 30, ...). + local conf_prefix="$(echo "$depends" | wc -w)0_" + + mkdir -p "$subpkgdir"/$_modules_dir + mkdir -p "$subpkgdir"/etc/nginx/modules + + cd "$subpkgdir" + + local soname; for soname in $sonames; do + mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname + echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf + done + + mkdir -p ./etc/nginx/naxsi/blocking/ + mkdir -p ./etc/nginx/naxsi/whitelists/ + + cd "$srcdir/.." + case "$name" in + http_naxsi) + install -m644 -D ../../../naxsi_rules/naxsi_core.rules \ + "$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules + install -m644 -D ../../../naxsi_rules/blocking/*.rules \ + "$subpkgdir/etc/nginx/naxsi/blocking/" + install -m644 -D ../../../naxsi_rules/whitelists/*.rules \ + "$subpkgdir/etc/nginx/naxsi/whitelists/" + ;; + esac +} + +# Print value of the specified variable, or the default if empty or not defined. +getvar() { + eval "printf '%s\n' \"\${$1:-$2}\"" +} + +sha512sums=" +8c21eeb62ab6e32e436932500f700bd2fb99fd2d29e43c08a5bfed4714c189c29c7141db551fcd5d2437303b7439f71758f7407dfd3e801e704e45e7daa78ddb nginx-1.18.0.tar.gz +" diff --git a/dependencies/naxsi/distros/alpine/1.18.0-r15/APKBUILD b/dependencies/naxsi/distros/alpine/1.18.0-r15/APKBUILD new file mode 100644 index 0000000..77f5c4e --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.18.0-r15/APKBUILD @@ -0,0 +1,222 @@ +# Maintainer: Giovanni Dante Grazioli +pkgname=nginx +pkgver=1.18.0 +pkgrel=15 +pkgdesc="HTTP and reverse proxy server (stable version)" +url="https://www.nginx.org/" +arch="all" +license="BSD-2-Clause" +depends="" +makedepends=" + brotli-dev + gd-dev + geoip-dev + libmaxminddb-dev + libxml2-dev + libxslt-dev + linux-headers + luajit-dev + openssl-dev + pcre-dev + perl-dev + pkgconf + zlib-dev + " +checkdepends=" + gd + perl + perl-fcgi + perl-io-socket-ssl + perl-net-ssleay + perl-protocol-websocket + tzdata + uwsgi-python3 + " +pkgusers="nginx" +_grp_ngx="nginx" +_grp_www="www-data" +pkggroups="$_grp_ngx $_grp_www" +install="" +subpackages="" +source="https://nginx.org/download/$pkgname-$pkgver.tar.gz + CVE-2021-23017.patch" +builddir="$srcdir/$pkgname-$pkgver" + +_modules_dir="usr/lib/$pkgname/modules" + +# For simplicity we assume that module is hosted on GitHub. +_add_module() { + local name="$1" ver="$2" url="$3" subdir="$4" + local dirname=${url##*/}-${ver#v} + local varprefix="_${name//-/_}" + + eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'" + + # Don't add new flag and source if it's already there, i.e. two or more + # modules share the same source (e.g. geoip2 that provides http-geoip2 + # and stream-geoip2). + if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then + _module_path=$(realpath ../../../$subdir) + _extra_flags="$_extra_flags --add-dynamic-module=$_module_path" + fi + subpackages="$subpackages $pkgname-mod-$name:_module" +} + +_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src" +_naxsi_provides="$pkgname-naxsi" # for backward compatibility + +prepare() { + local file; for file in $source; do + file=${file%%::*} + + case $file in + *~*.patch) + msg $file + cd "$srcdir"/${file%%~*}-* + patch -p 1 -i "$srcdir/$file" + ;; + *.patch) + msg $file + cd "$builddir" + patch -p 1 -i "$srcdir/$file" + ;; + esac + done +} + +_build() { + ./configure \ + --prefix=/var/lib/$pkgname \ + --sbin-path=/usr/sbin/$pkgname \ + --modules-path=/$_modules_dir \ + --conf-path=/etc/$pkgname/$pkgname.conf \ + --pid-path=/run/$pkgname/$pkgname.pid \ + --lock-path=/run/$pkgname/$pkgname.lock \ + --http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \ + --http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \ + --http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \ + --http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \ + --http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \ + --with-perl_modules_path=/usr/lib/perl5/vendor_perl \ + \ + --user=$pkgusers \ + --group=$_grp_ngx \ + --with-threads \ + --with-file-aio \ + \ + --with-http_ssl_module \ + --with-http_v2_module \ + --with-http_realip_module \ + --with-http_addition_module \ + --with-http_xslt_module=dynamic \ + --with-http_image_filter_module=dynamic \ + --with-http_geoip_module=dynamic \ + --with-http_sub_module \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_mp4_module \ + --with-http_gunzip_module \ + --with-http_gzip_static_module \ + --with-http_auth_request_module \ + --with-http_random_index_module \ + --with-http_secure_link_module \ + --with-http_degradation_module \ + --with-http_slice_module \ + --with-http_stub_status_module \ + --with-http_perl_module=dynamic \ + --with-mail=dynamic \ + --with-mail_ssl_module \ + --with-stream=dynamic \ + --with-stream_ssl_module \ + --with-stream_realip_module \ + --with-stream_geoip_module=dynamic \ + --with-stream_ssl_preread_module \ + \ + $_extra_flags \ + "$@" + + make -j +} + +build() { + cd "$builddir" + + _build --with-debug + mv objs objs-debug + + make clean + _build +} + +check() { + msg "Ignore nginx tests..." +} + +package() { + cd "$builddir" + + make DESTDIR="$pkgdir" install +} + +debug() { + return +} + +vim() { + return +} + +_module() { + local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}" + local ver=$(getvar _${name}_ver) + + pkgdesc="Nginx module ${name//_/-}" + [ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)" + + url=$(getvar "_${name}_url" "$url") + sonames=$(getvar "_${name}_so" "ngx_${name}_module.so") + depends="$pkgname $(getvar "_${name}_depends")" + provides=$(getvar "_${name}_provides") + + # Numeric prefix for the module config to ensure that modules with + # dependencies on other modules will be loaded after their dependencies. + # For simplicity, we don't actually resolve dependency tree. Instead, + # we just prefix the module name with a number that reflects number of + # the module's dependencies times ten (e.g. 10, 20, 30, ...). + local conf_prefix="$(echo "$depends" | wc -w)0_" + + mkdir -p "$subpkgdir"/$_modules_dir + mkdir -p "$subpkgdir"/etc/nginx/modules + + cd "$subpkgdir" + + local soname; for soname in $sonames; do + mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname + echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf + done + + mkdir -p ./etc/nginx/naxsi/blocking/ + mkdir -p ./etc/nginx/naxsi/whitelists/ + + cd "$srcdir/.." + case "$name" in + http_naxsi) + install -m644 -D ../../../naxsi_rules/naxsi_core.rules \ + "$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules + install -m644 -D ../../../naxsi_rules/blocking/*.rules \ + "$subpkgdir/etc/nginx/naxsi/blocking/" + install -m644 -D ../../../naxsi_rules/whitelists/*.rules \ + "$subpkgdir/etc/nginx/naxsi/whitelists/" + ;; + esac +} + +# Print value of the specified variable, or the default if empty or not defined. +getvar() { + eval "printf '%s\n' \"\${$1:-$2}\"" +} + +sha512sums=" +8c21eeb62ab6e32e436932500f700bd2fb99fd2d29e43c08a5bfed4714c189c29c7141db551fcd5d2437303b7439f71758f7407dfd3e801e704e45e7daa78ddb nginx-1.18.0.tar.gz +b8ed5dedc55f4e1c60f3c0b97836096e83a9f928b13c125fe568f5d369bb35535224c7def05677f04adc9733a983ac9cc8aa2c7af94468085eb3121c1817dc45 CVE-2021-23017.patch +" diff --git a/dependencies/naxsi/distros/alpine/1.18.0-r15/CVE-2021-23017.patch b/dependencies/naxsi/distros/alpine/1.18.0-r15/CVE-2021-23017.patch new file mode 100644 index 0000000..9d551c2 --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.18.0-r15/CVE-2021-23017.patch @@ -0,0 +1,25 @@ +Patch-Source: http://nginx.org/download/patch.2021.resolver.txt + +diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c +--- a/src/core/ngx_resolver.c ++++ b/src/core/ngx_resolver.c +@@ -4008,15 +4008,15 @@ done: + n = *src++; + + } else { ++ if (dst != name->data) { ++ *dst++ = '.'; ++ } ++ + ngx_strlow(dst, src, n); + dst += n; + src += n; + + n = *src++; +- +- if (n != 0) { +- *dst++ = '.'; +- } + } + + if (n == 0) { diff --git a/dependencies/naxsi/distros/alpine/1.20.1-r3/APKBUILD b/dependencies/naxsi/distros/alpine/1.20.1-r3/APKBUILD new file mode 100644 index 0000000..ed813ff --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.20.1-r3/APKBUILD @@ -0,0 +1,221 @@ +# Maintainer: Giovanni Dante Grazioli +pkgname=nginx +pkgver=1.20.1 +pkgrel=3 +pkgdesc="HTTP and reverse proxy server (stable version)" +url="https://www.nginx.org/" +arch="all" +license="BSD-2-Clause" +depends="" +makedepends=" + brotli-dev + gd-dev + geoip-dev + libmaxminddb-dev + libxml2-dev + libxslt-dev + linux-headers + luajit-dev + openssl-dev + pcre-dev + perl-dev + pkgconf + zeromq-dev + zlib-dev + " +checkdepends=" + gd + perl + perl-fcgi + perl-io-socket-ssl + perl-net-ssleay + perl-protocol-websocket + tzdata + uwsgi-python3 + " +pkgusers="nginx" +_grp_ngx="nginx" +_grp_www="www-data" +pkggroups="$_grp_ngx $_grp_www" +install="" +subpackages="" +source="https://nginx.org/download/$pkgname-$pkgver.tar.gz" +builddir="$srcdir/$pkgname-$pkgver" + +_modules_dir="usr/lib/$pkgname/modules" + +# For simplicity we assume that module is hosted on GitHub. +_add_module() { + local name="$1" ver="$2" url="$3" subdir="$4" + local dirname=${url##*/}-${ver#v} + local varprefix="_${name//-/_}" + + eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'" + + # Don't add new flag and source if it's already there, i.e. two or more + # modules share the same source (e.g. geoip2 that provides http-geoip2 + # and stream-geoip2). + if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then + _module_path=$(realpath ../../../$subdir) + _extra_flags="$_extra_flags --add-dynamic-module=$_module_path" + fi + subpackages="$subpackages $pkgname-mod-$name:_module" +} + +_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src" +_naxsi_provides="$pkgname-naxsi" # for backward compatibility + +prepare() { + local file; for file in $source; do + file=${file%%::*} + + case $file in + *~*.patch) + msg $file + cd "$srcdir"/${file%%~*}-* + patch -p 1 -i "$srcdir/$file" + ;; + *.patch) + msg $file + cd "$builddir" + patch -p 1 -i "$srcdir/$file" + ;; + esac + done +} + +_build() { + ./configure \ + --prefix=/var/lib/$pkgname \ + --sbin-path=/usr/sbin/$pkgname \ + --modules-path=/$_modules_dir \ + --conf-path=/etc/$pkgname/$pkgname.conf \ + --pid-path=/run/$pkgname/$pkgname.pid \ + --lock-path=/run/$pkgname/$pkgname.lock \ + --http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \ + --http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \ + --http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \ + --http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \ + --http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \ + --with-perl_modules_path=/usr/lib/perl5/vendor_perl \ + \ + --user=$pkgusers \ + --group=$_grp_ngx \ + --with-threads \ + --with-file-aio \ + \ + --with-http_ssl_module \ + --with-http_v2_module \ + --with-http_realip_module \ + --with-http_addition_module \ + --with-http_xslt_module=dynamic \ + --with-http_image_filter_module=dynamic \ + --with-http_geoip_module=dynamic \ + --with-http_sub_module \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_mp4_module \ + --with-http_gunzip_module \ + --with-http_gzip_static_module \ + --with-http_auth_request_module \ + --with-http_random_index_module \ + --with-http_secure_link_module \ + --with-http_degradation_module \ + --with-http_slice_module \ + --with-http_stub_status_module \ + --with-http_perl_module=dynamic \ + --with-mail=dynamic \ + --with-mail_ssl_module \ + --with-stream=dynamic \ + --with-stream_ssl_module \ + --with-stream_realip_module \ + --with-stream_geoip_module=dynamic \ + --with-stream_ssl_preread_module \ + \ + $_extra_flags \ + "$@" + + make -j +} + +build() { + cd "$builddir" + + _build --with-debug + mv objs objs-debug + + make clean + _build +} + +check() { + msg "Ignore nginx tests..." +} + +package() { + cd "$builddir" + + make DESTDIR="$pkgdir" install +} + +debug() { + return +} + +vim() { + return +} + +_module() { + local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}" + local ver=$(getvar _${name}_ver) + + pkgdesc="Nginx module ${name//_/-}" + [ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)" + + url=$(getvar "_${name}_url" "$url") + sonames=$(getvar "_${name}_so" "ngx_${name}_module.so") + depends="$pkgname $(getvar "_${name}_depends")" + provides=$(getvar "_${name}_provides") + + # Numeric prefix for the module config to ensure that modules with + # dependencies on other modules will be loaded after their dependencies. + # For simplicity, we don't actually resolve dependency tree. Instead, + # we just prefix the module name with a number that reflects number of + # the module's dependencies times ten (e.g. 10, 20, 30, ...). + local conf_prefix="$(echo "$depends" | wc -w)0_" + + mkdir -p "$subpkgdir"/$_modules_dir + mkdir -p "$subpkgdir"/etc/nginx/modules + + cd "$subpkgdir" + + local soname; for soname in $sonames; do + mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname + echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf + done + + mkdir -p ./etc/nginx/naxsi/blocking/ + mkdir -p ./etc/nginx/naxsi/whitelists/ + + cd "$srcdir/.." + case "$name" in + http_naxsi) + install -m644 -D ../../../naxsi_rules/naxsi_core.rules \ + "$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules + install -m644 -D ../../../naxsi_rules/blocking/*.rules \ + "$subpkgdir/etc/nginx/naxsi/blocking/" + install -m644 -D ../../../naxsi_rules/whitelists/*.rules \ + "$subpkgdir/etc/nginx/naxsi/whitelists/" + ;; + esac +} + +# Print value of the specified variable, or the default if empty or not defined. +getvar() { + eval "printf '%s\n' \"\${$1:-$2}\"" +} + +sha512sums=" +3d9fd4bf2740eaf20fcc3c77260a3556aaf9dff2879afc2dbb5fff364dea27313ffbc51d335e9fc9c0186a2a44dac055ef60fde0d411b8cf842fdf661478c961 nginx-1.20.1.tar.gz +" diff --git a/dependencies/naxsi/distros/alpine/1.20.2-r0/APKBUILD b/dependencies/naxsi/distros/alpine/1.20.2-r0/APKBUILD new file mode 100644 index 0000000..0c0cae2 --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.20.2-r0/APKBUILD @@ -0,0 +1,221 @@ +# Maintainer: Giovanni Dante Grazioli +pkgname=nginx +pkgver=1.20.2 +pkgrel=0 +pkgdesc="HTTP and reverse proxy server (stable version)" +url="https://www.nginx.org/" +arch="all" +license="BSD-2-Clause" +depends="" +makedepends=" + brotli-dev + gd-dev + geoip-dev + libmaxminddb-dev + libxml2-dev + libxslt-dev + linux-headers + luajit-dev + openssl-dev + pcre-dev + perl-dev + pkgconf + zeromq-dev + zlib-dev + " +checkdepends=" + gd + perl + perl-fcgi + perl-io-socket-ssl + perl-net-ssleay + perl-protocol-websocket + tzdata + uwsgi-python3 + " +pkgusers="nginx" +_grp_ngx="nginx" +_grp_www="www-data" +pkggroups="$_grp_ngx $_grp_www" +install="" +subpackages="" +source="https://nginx.org/download/$pkgname-$pkgver.tar.gz" +builddir="$srcdir/$pkgname-$pkgver" + +_modules_dir="usr/lib/$pkgname/modules" + +# For simplicity we assume that module is hosted on GitHub. +_add_module() { + local name="$1" ver="$2" url="$3" subdir="$4" + local dirname=${url##*/}-${ver#v} + local varprefix="_${name//-/_}" + + eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'" + + # Don't add new flag and source if it's already there, i.e. two or more + # modules share the same source (e.g. geoip2 that provides http-geoip2 + # and stream-geoip2). + if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then + _module_path=$(realpath ../../../$subdir) + _extra_flags="$_extra_flags --add-dynamic-module=$_module_path" + fi + subpackages="$subpackages $pkgname-mod-$name:_module" +} + +_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src" +_naxsi_provides="$pkgname-naxsi" # for backward compatibility + +prepare() { + local file; for file in $source; do + file=${file%%::*} + + case $file in + *~*.patch) + msg $file + cd "$srcdir"/${file%%~*}-* + patch -p 1 -i "$srcdir/$file" + ;; + *.patch) + msg $file + cd "$builddir" + patch -p 1 -i "$srcdir/$file" + ;; + esac + done +} + +_build() { + ./configure \ + --prefix=/var/lib/$pkgname \ + --sbin-path=/usr/sbin/$pkgname \ + --modules-path=/$_modules_dir \ + --conf-path=/etc/$pkgname/$pkgname.conf \ + --pid-path=/run/$pkgname/$pkgname.pid \ + --lock-path=/run/$pkgname/$pkgname.lock \ + --http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \ + --http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \ + --http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \ + --http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \ + --http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \ + --with-perl_modules_path=/usr/lib/perl5/vendor_perl \ + \ + --user=$pkgusers \ + --group=$_grp_ngx \ + --with-threads \ + --with-file-aio \ + \ + --with-http_ssl_module \ + --with-http_v2_module \ + --with-http_realip_module \ + --with-http_addition_module \ + --with-http_xslt_module=dynamic \ + --with-http_image_filter_module=dynamic \ + --with-http_geoip_module=dynamic \ + --with-http_sub_module \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_mp4_module \ + --with-http_gunzip_module \ + --with-http_gzip_static_module \ + --with-http_auth_request_module \ + --with-http_random_index_module \ + --with-http_secure_link_module \ + --with-http_degradation_module \ + --with-http_slice_module \ + --with-http_stub_status_module \ + --with-http_perl_module=dynamic \ + --with-mail=dynamic \ + --with-mail_ssl_module \ + --with-stream=dynamic \ + --with-stream_ssl_module \ + --with-stream_realip_module \ + --with-stream_geoip_module=dynamic \ + --with-stream_ssl_preread_module \ + \ + $_extra_flags \ + "$@" + + make -j +} + +build() { + cd "$builddir" + + _build --with-debug + mv objs objs-debug + + make clean + _build +} + +check() { + msg "Ignore nginx tests..." +} + +package() { + cd "$builddir" + + make DESTDIR="$pkgdir" install +} + +debug() { + return +} + +vim() { + return +} + +_module() { + local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}" + local ver=$(getvar _${name}_ver) + + pkgdesc="Nginx module ${name//_/-}" + [ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)" + + url=$(getvar "_${name}_url" "$url") + sonames=$(getvar "_${name}_so" "ngx_${name}_module.so") + depends="$pkgname $(getvar "_${name}_depends")" + provides=$(getvar "_${name}_provides") + + # Numeric prefix for the module config to ensure that modules with + # dependencies on other modules will be loaded after their dependencies. + # For simplicity, we don't actually resolve dependency tree. Instead, + # we just prefix the module name with a number that reflects number of + # the module's dependencies times ten (e.g. 10, 20, 30, ...). + local conf_prefix="$(echo "$depends" | wc -w)0_" + + mkdir -p "$subpkgdir"/$_modules_dir + mkdir -p "$subpkgdir"/etc/nginx/modules + + cd "$subpkgdir" + + local soname; for soname in $sonames; do + mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname + echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf + done + + mkdir -p ./etc/nginx/naxsi/blocking/ + mkdir -p ./etc/nginx/naxsi/whitelists/ + + cd "$srcdir/.." + case "$name" in + http_naxsi) + install -m644 -D ../../../naxsi_rules/naxsi_core.rules \ + "$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules + install -m644 -D ../../../naxsi_rules/blocking/*.rules \ + "$subpkgdir/etc/nginx/naxsi/blocking/" + install -m644 -D ../../../naxsi_rules/whitelists/*.rules \ + "$subpkgdir/etc/nginx/naxsi/whitelists/" + ;; + esac +} + +# Print value of the specified variable, or the default if empty or not defined. +getvar() { + eval "printf '%s\n' \"\${$1:-$2}\"" +} + +sha512sums=" +8b65e881ea4ac6162cbf32e5e95cf47a6d5418819f8763ca4a781cffa38187dd7886d4bc195d000a7046111a27121ff25800f8645405174995247e6738b4279a nginx-1.20.2.tar.gz +" diff --git a/dependencies/naxsi/distros/alpine/1.20.2-r1/APKBUILD b/dependencies/naxsi/distros/alpine/1.20.2-r1/APKBUILD new file mode 100644 index 0000000..802dc9a --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.20.2-r1/APKBUILD @@ -0,0 +1,223 @@ +# Maintainer: Giovanni Dante Grazioli +pkgname=nginx +pkgver=1.20.2 +pkgrel=1 +pkgdesc="HTTP and reverse proxy server (stable version)" +url="https://www.nginx.org/" +arch="all" +license="BSD-2-Clause" +depends="" +makedepends=" + brotli-dev + gd-dev + geoip-dev + libmaxminddb-dev + libxml2-dev + libxslt-dev + linux-headers + luajit-dev + openssl-dev + pcre-dev + perl-dev + pkgconf + zeromq-dev + zlib-dev + " +checkdepends=" + gd + perl + perl-fcgi + perl-io-socket-ssl + perl-net-ssleay + perl-protocol-websocket + tzdata + uwsgi-python3 + " +pkgusers="nginx" +_grp_ngx="nginx" +_grp_www="www-data" +pkggroups="$_grp_ngx $_grp_www" +install="" +subpackages="" +source="https://nginx.org/download/$pkgname-$pkgver.tar.gz + CVE-2021-3618.patch" +builddir="$srcdir/$pkgname-$pkgver" + +_modules_dir="usr/lib/$pkgname/modules" + +# For simplicity we assume that module is hosted on GitHub. +_add_module() { + local name="$1" ver="$2" url="$3" subdir="$4" + local dirname=${url##*/}-${ver#v} + local varprefix="_${name//-/_}" + + eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'" + + # Don't add new flag and source if it's already there, i.e. two or more + # modules share the same source (e.g. geoip2 that provides http-geoip2 + # and stream-geoip2). + if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then + _module_path=$(realpath ../../../$subdir) + _extra_flags="$_extra_flags --add-dynamic-module=$_module_path" + fi + subpackages="$subpackages $pkgname-mod-$name:_module" +} + +_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src" +_naxsi_provides="$pkgname-naxsi" # for backward compatibility + +prepare() { + local file; for file in $source; do + file=${file%%::*} + + case $file in + *~*.patch) + msg $file + cd "$srcdir"/${file%%~*}-* + patch -p 1 -i "$srcdir/$file" + ;; + *.patch) + msg $file + cd "$builddir" + patch -p 1 -i "$srcdir/$file" + ;; + esac + done +} + +_build() { + ./configure \ + --prefix=/var/lib/$pkgname \ + --sbin-path=/usr/sbin/$pkgname \ + --modules-path=/$_modules_dir \ + --conf-path=/etc/$pkgname/$pkgname.conf \ + --pid-path=/run/$pkgname/$pkgname.pid \ + --lock-path=/run/$pkgname/$pkgname.lock \ + --http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \ + --http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \ + --http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \ + --http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \ + --http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \ + --with-perl_modules_path=/usr/lib/perl5/vendor_perl \ + \ + --user=$pkgusers \ + --group=$_grp_ngx \ + --with-threads \ + --with-file-aio \ + \ + --with-http_ssl_module \ + --with-http_v2_module \ + --with-http_realip_module \ + --with-http_addition_module \ + --with-http_xslt_module=dynamic \ + --with-http_image_filter_module=dynamic \ + --with-http_geoip_module=dynamic \ + --with-http_sub_module \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_mp4_module \ + --with-http_gunzip_module \ + --with-http_gzip_static_module \ + --with-http_auth_request_module \ + --with-http_random_index_module \ + --with-http_secure_link_module \ + --with-http_degradation_module \ + --with-http_slice_module \ + --with-http_stub_status_module \ + --with-http_perl_module=dynamic \ + --with-mail=dynamic \ + --with-mail_ssl_module \ + --with-stream=dynamic \ + --with-stream_ssl_module \ + --with-stream_realip_module \ + --with-stream_geoip_module=dynamic \ + --with-stream_ssl_preread_module \ + \ + $_extra_flags \ + "$@" + + make -j +} + +build() { + cd "$builddir" + + _build --with-debug + mv objs objs-debug + + make clean + _build +} + +check() { + msg "Ignore nginx tests..." +} + +package() { + cd "$builddir" + + make DESTDIR="$pkgdir" install +} + +debug() { + return +} + +vim() { + return +} + +_module() { + local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}" + local ver=$(getvar _${name}_ver) + + pkgdesc="Nginx module ${name//_/-}" + [ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)" + + url=$(getvar "_${name}_url" "$url") + sonames=$(getvar "_${name}_so" "ngx_${name}_module.so") + depends="$pkgname $(getvar "_${name}_depends")" + provides=$(getvar "_${name}_provides") + + # Numeric prefix for the module config to ensure that modules with + # dependencies on other modules will be loaded after their dependencies. + # For simplicity, we don't actually resolve dependency tree. Instead, + # we just prefix the module name with a number that reflects number of + # the module's dependencies times ten (e.g. 10, 20, 30, ...). + local conf_prefix="$(echo "$depends" | wc -w)0_" + + mkdir -p "$subpkgdir"/$_modules_dir + mkdir -p "$subpkgdir"/etc/nginx/modules + + cd "$subpkgdir" + + local soname; for soname in $sonames; do + mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname + echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf + done + + mkdir -p ./etc/nginx/naxsi/blocking/ + mkdir -p ./etc/nginx/naxsi/whitelists/ + + cd "$srcdir/.." + case "$name" in + http_naxsi) + install -m644 -D ../../../naxsi_rules/naxsi_core.rules \ + "$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules + install -m644 -D ../../../naxsi_rules/blocking/*.rules \ + "$subpkgdir/etc/nginx/naxsi/blocking/" + install -m644 -D ../../../naxsi_rules/whitelists/*.rules \ + "$subpkgdir/etc/nginx/naxsi/whitelists/" + ;; + esac +} + +# Print value of the specified variable, or the default if empty or not defined. +getvar() { + eval "printf '%s\n' \"\${$1:-$2}\"" +} + +sha512sums=" +8b65e881ea4ac6162cbf32e5e95cf47a6d5418819f8763ca4a781cffa38187dd7886d4bc195d000a7046111a27121ff25800f8645405174995247e6738b4279a nginx-1.20.2.tar.gz +5896417268cdd4cde1cc6a4cf9ebc3aa2c82cb4b27a68c1fa4e9c1065cf4e5f0eebc13cfdb2ac3ebe29fdc5332022a61681aceefe1c72c5402ce73fab3f03f5a CVE-2021-3618.patch +" diff --git a/dependencies/naxsi/distros/alpine/1.20.2-r1/CVE-2021-3618.patch b/dependencies/naxsi/distros/alpine/1.20.2-r1/CVE-2021-3618.patch new file mode 100644 index 0000000..5c3441e --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.20.2-r1/CVE-2021-3618.patch @@ -0,0 +1,92 @@ +Patch-Source: https://github.com/nginx/nginx/commit/173f16f736c10eae46cd15dd861b04b82d91a37a +commit 173f16f736c10eae46cd15dd861b04b82d91a37a +Author: Maxim Dounin +Date: Wed May 19 03:13:31 2021 +0300 + + Mail: max_errors directive. + + Similarly to smtpd_hard_error_limit in Postfix and smtp_max_unknown_commands + in Exim, specifies the number of errors after which the connection is closed. + +diff --git a/src/mail/ngx_mail.h b/src/mail/ngx_mail.h +index 07104df6..21178c3e 100644 +--- a/src/mail/ngx_mail.h ++++ b/src/mail/ngx_mail.h +@@ -115,6 +115,8 @@ typedef struct { + ngx_msec_t timeout; + ngx_msec_t resolver_timeout; + ++ ngx_uint_t max_errors; ++ + ngx_str_t server_name; + + u_char *file_name; +@@ -231,6 +233,7 @@ typedef struct { + ngx_uint_t command; + ngx_array_t args; + ++ ngx_uint_t errors; + ngx_uint_t login_attempt; + + /* used to parse POP3/IMAP/SMTP command */ +diff --git a/src/mail/ngx_mail_core_module.c b/src/mail/ngx_mail_core_module.c +index 40831242..115671ca 100644 +--- a/src/mail/ngx_mail_core_module.c ++++ b/src/mail/ngx_mail_core_module.c +@@ -85,6 +85,13 @@ static ngx_command_t ngx_mail_core_commands[] = { + offsetof(ngx_mail_core_srv_conf_t, resolver_timeout), + NULL }, + ++ { ngx_string("max_errors"), ++ NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, ++ ngx_conf_set_num_slot, ++ NGX_MAIL_SRV_CONF_OFFSET, ++ offsetof(ngx_mail_core_srv_conf_t, max_errors), ++ NULL }, ++ + ngx_null_command + }; + +@@ -163,6 +170,8 @@ ngx_mail_core_create_srv_conf(ngx_conf_t *cf) + cscf->timeout = NGX_CONF_UNSET_MSEC; + cscf->resolver_timeout = NGX_CONF_UNSET_MSEC; + ++ cscf->max_errors = NGX_CONF_UNSET_UINT; ++ + cscf->resolver = NGX_CONF_UNSET_PTR; + + cscf->file_name = cf->conf_file->file.name.data; +@@ -182,6 +191,7 @@ ngx_mail_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) + ngx_conf_merge_msec_value(conf->resolver_timeout, prev->resolver_timeout, + 30000); + ++ ngx_conf_merge_uint_value(conf->max_errors, prev->max_errors, 5); + + ngx_conf_merge_str_value(conf->server_name, prev->server_name, ""); + +diff --git a/src/mail/ngx_mail_handler.c b/src/mail/ngx_mail_handler.c +index 57503e9a..246ba97c 100644 +--- a/src/mail/ngx_mail_handler.c ++++ b/src/mail/ngx_mail_handler.c +@@ -874,7 +874,20 @@ ngx_mail_read_command(ngx_mail_session_t *s, ngx_connection_t *c) + return NGX_MAIL_PARSE_INVALID_COMMAND; + } + +- if (rc == NGX_IMAP_NEXT || rc == NGX_MAIL_PARSE_INVALID_COMMAND) { ++ if (rc == NGX_MAIL_PARSE_INVALID_COMMAND) { ++ ++ s->errors++; ++ ++ if (s->errors >= cscf->max_errors) { ++ ngx_log_error(NGX_LOG_INFO, c->log, 0, ++ "client sent too many invalid commands"); ++ s->quit = 1; ++ } ++ ++ return rc; ++ } ++ ++ if (rc == NGX_IMAP_NEXT) { + return rc; + } + diff --git a/dependencies/naxsi/distros/alpine/1.22.0-r1/APKBUILD b/dependencies/naxsi/distros/alpine/1.22.0-r1/APKBUILD new file mode 100644 index 0000000..827c03a --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.22.0-r1/APKBUILD @@ -0,0 +1,225 @@ +# Maintainer: Giovanni Dante Grazioli +pkgname=nginx +pkgver=1.22.0 +pkgrel=1 +pkgdesc="HTTP and reverse proxy server (stable version)" +url="https://www.nginx.org/" +arch="all" +license="BSD-2-Clause" +depends="" +makedepends=" + brotli-dev + gd-dev + geoip-dev + libmaxminddb-dev + libxml2-dev + libxslt-dev + linux-headers + luajit-dev + openssl-dev + pcre-dev + perl-dev + pkgconf + zeromq-dev + zlib-dev + " +checkdepends=" + gd + perl + perl-fcgi + perl-io-socket-ssl + perl-net-ssleay + perl-protocol-websocket + tzdata + uwsgi-python3 + " +pkgusers="nginx" +_grp_ngx="nginx" +_grp_www="www-data" +pkggroups="$_grp_ngx $_grp_www" +install="" +subpackages="" +source="https://nginx.org/download/$pkgname-$pkgver.tar.gz" +builddir="$srcdir/$pkgname-$pkgver" + +_modules_dir="usr/lib/$pkgname/modules" + +# For simplicity we assume that module is hosted on GitHub. +_add_module() { + local name="$1" ver="$2" url="$3" subdir="$4" + local dirname=${url##*/}-${ver#v} + local varprefix="_${name//-/_}" + + eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'" + + # Don't add new flag and source if it's already there, i.e. two or more + # modules share the same source (e.g. geoip2 that provides http-geoip2 + # and stream-geoip2). + if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then + _module_path=$(realpath ../../../$subdir) + _extra_flags="$_extra_flags --add-dynamic-module=$_module_path" + fi + subpackages="$subpackages $pkgname-mod-$name:_module" +} + +_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src" +_naxsi_provides="$pkgname-naxsi" # for backward compatibility + +prepare() { + local file; for file in $source; do + file=${file%%::*} + + case $file in + *~*.patch) + msg $file + cd "$srcdir"/${file%%~*}-* + patch -p 1 -i "$srcdir/$file" + ;; + *.patch) + msg $file + cd "$builddir" + patch -p 1 -i "$srcdir/$file" + ;; + esac + done +} + +_build() { + # --without-pcre2 - Lua module is not compatible with PCRE2 yet + # https://github.com/openresty/lua-nginx-module/issues/1984 + ./configure \ + --prefix=/var/lib/$pkgname \ + --sbin-path=/usr/sbin/$pkgname \ + --modules-path=/$_modules_dir \ + --conf-path=/etc/$pkgname/$pkgname.conf \ + --pid-path=/run/$pkgname/$pkgname.pid \ + --lock-path=/run/$pkgname/$pkgname.lock \ + --http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \ + --http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \ + --http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \ + --http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \ + --http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \ + --with-perl_modules_path=/usr/lib/perl5/vendor_perl \ + \ + --user=$pkgusers \ + --group=$_grp_ngx \ + --with-threads \ + --with-file-aio \ + \ + --without-pcre2 \ + \ + --with-http_ssl_module \ + --with-http_v2_module \ + --with-http_realip_module \ + --with-http_addition_module \ + --with-http_xslt_module=dynamic \ + --with-http_image_filter_module=dynamic \ + --with-http_geoip_module=dynamic \ + --with-http_sub_module \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_mp4_module \ + --with-http_gunzip_module \ + --with-http_gzip_static_module \ + --with-http_auth_request_module \ + --with-http_random_index_module \ + --with-http_secure_link_module \ + --with-http_degradation_module \ + --with-http_slice_module \ + --with-http_stub_status_module \ + --with-http_perl_module=dynamic \ + --with-mail=dynamic \ + --with-mail_ssl_module \ + --with-stream=dynamic \ + --with-stream_ssl_module \ + --with-stream_realip_module \ + --with-stream_geoip_module=dynamic \ + --with-stream_ssl_preread_module \ + \ + $_extra_flags \ + "$@" + + make -j +} + +build() { + cd "$builddir" + + _build --with-debug + mv objs objs-debug + + make clean + _build +} + +check() { + msg "Ignore nginx tests..." +} + +package() { + cd "$builddir" + + make DESTDIR="$pkgdir" install +} + +debug() { + return +} + +vim() { + return +} + +_module() { + local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}" + local ver=$(getvar _${name}_ver) + + pkgdesc="Nginx module ${name//_/-}" + [ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)" + + url=$(getvar "_${name}_url" "$url") + sonames=$(getvar "_${name}_so" "ngx_${name}_module.so") + depends="$pkgname $(getvar "_${name}_depends")" + provides=$(getvar "_${name}_provides") + + # Numeric prefix for the module config to ensure that modules with + # dependencies on other modules will be loaded after their dependencies. + # For simplicity, we don't actually resolve dependency tree. Instead, + # we just prefix the module name with a number that reflects number of + # the module's dependencies times ten (e.g. 10, 20, 30, ...). + local conf_prefix="$(echo "$depends" | wc -w)0_" + + mkdir -p "$subpkgdir"/$_modules_dir + mkdir -p "$subpkgdir"/etc/nginx/modules + + cd "$subpkgdir" + + local soname; for soname in $sonames; do + mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname + echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf + done + + mkdir -p ./etc/nginx/naxsi/blocking/ + mkdir -p ./etc/nginx/naxsi/whitelists/ + + cd "$srcdir/.." + case "$name" in + http_naxsi) + install -m644 -D ../../../naxsi_rules/naxsi_core.rules \ + "$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules + install -m644 -D ../../../naxsi_rules/blocking/*.rules \ + "$subpkgdir/etc/nginx/naxsi/blocking/" + install -m644 -D ../../../naxsi_rules/whitelists/*.rules \ + "$subpkgdir/etc/nginx/naxsi/whitelists/" + ;; + esac +} + +# Print value of the specified variable, or the default if empty or not defined. +getvar() { + eval "printf '%s\n' \"\${$1:-$2}\"" +} + +sha512sums=" +074782dba9cd5f8f493fbb57e20bda6dc9171814d919a47ee9f825d93f12c9f9d496e25d063c983191b55ad6a236bcef252ce16ecc1d253dc8b23433557559b1 nginx-1.22.0.tar.gz +" diff --git a/dependencies/naxsi/distros/alpine/1.22.1-r0/APKBUILD b/dependencies/naxsi/distros/alpine/1.22.1-r0/APKBUILD new file mode 100644 index 0000000..c12aebe --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.22.1-r0/APKBUILD @@ -0,0 +1,225 @@ +# Maintainer: Giovanni Dante Grazioli +pkgname=nginx +pkgver=1.22.1 +pkgrel=0 +pkgdesc="HTTP and reverse proxy server (stable version)" +url="https://www.nginx.org/" +arch="all" +license="BSD-2-Clause" +depends="" +makedepends=" + brotli-dev + gd-dev + geoip-dev + libmaxminddb-dev + libxml2-dev + libxslt-dev + linux-headers + luajit-dev + openssl-dev + pcre-dev + perl-dev + pkgconf + zeromq-dev + zlib-dev + " +checkdepends=" + gd + perl + perl-fcgi + perl-io-socket-ssl + perl-net-ssleay + perl-protocol-websocket + tzdata + uwsgi-python3 + " +pkgusers="nginx" +_grp_ngx="nginx" +_grp_www="www-data" +pkggroups="$_grp_ngx $_grp_www" +install="" +subpackages="" +source="https://nginx.org/download/$pkgname-$pkgver.tar.gz" +builddir="$srcdir/$pkgname-$pkgver" + +_modules_dir="usr/lib/$pkgname/modules" + +# For simplicity we assume that module is hosted on GitHub. +_add_module() { + local name="$1" ver="$2" url="$3" subdir="$4" + local dirname=${url##*/}-${ver#v} + local varprefix="_${name//-/_}" + + eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'" + + # Don't add new flag and source if it's already there, i.e. two or more + # modules share the same source (e.g. geoip2 that provides http-geoip2 + # and stream-geoip2). + if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then + _module_path=$(realpath ../../../$subdir) + _extra_flags="$_extra_flags --add-dynamic-module=$_module_path" + fi + subpackages="$subpackages $pkgname-mod-$name:_module" +} + +_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src" +_naxsi_provides="$pkgname-naxsi" # for backward compatibility + +prepare() { + local file; for file in $source; do + file=${file%%::*} + + case $file in + *~*.patch) + msg $file + cd "$srcdir"/${file%%~*}-* + patch -p 1 -i "$srcdir/$file" + ;; + *.patch) + msg $file + cd "$builddir" + patch -p 1 -i "$srcdir/$file" + ;; + esac + done +} + +_build() { + # --without-pcre2 - Lua module is not compatible with PCRE2 yet + # https://github.com/openresty/lua-nginx-module/issues/1984 + ./configure \ + --prefix=/var/lib/$pkgname \ + --sbin-path=/usr/sbin/$pkgname \ + --modules-path=/$_modules_dir \ + --conf-path=/etc/$pkgname/$pkgname.conf \ + --pid-path=/run/$pkgname/$pkgname.pid \ + --lock-path=/run/$pkgname/$pkgname.lock \ + --http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \ + --http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \ + --http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \ + --http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \ + --http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \ + --with-perl_modules_path=/usr/lib/perl5/vendor_perl \ + \ + --user=$pkgusers \ + --group=$_grp_ngx \ + --with-threads \ + --with-file-aio \ + \ + --without-pcre2 \ + \ + --with-http_ssl_module \ + --with-http_v2_module \ + --with-http_realip_module \ + --with-http_addition_module \ + --with-http_xslt_module=dynamic \ + --with-http_image_filter_module=dynamic \ + --with-http_geoip_module=dynamic \ + --with-http_sub_module \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_mp4_module \ + --with-http_gunzip_module \ + --with-http_gzip_static_module \ + --with-http_auth_request_module \ + --with-http_random_index_module \ + --with-http_secure_link_module \ + --with-http_degradation_module \ + --with-http_slice_module \ + --with-http_stub_status_module \ + --with-http_perl_module=dynamic \ + --with-mail=dynamic \ + --with-mail_ssl_module \ + --with-stream=dynamic \ + --with-stream_ssl_module \ + --with-stream_realip_module \ + --with-stream_geoip_module=dynamic \ + --with-stream_ssl_preread_module \ + \ + $_extra_flags \ + "$@" + + make -j +} + +build() { + cd "$builddir" + + _build --with-debug + mv objs objs-debug + + make clean + _build +} + +check() { + msg "Ignore nginx tests..." +} + +package() { + cd "$builddir" + + make DESTDIR="$pkgdir" install +} + +debug() { + return +} + +vim() { + return +} + +_module() { + local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}" + local ver=$(getvar _${name}_ver) + + pkgdesc="Nginx module ${name//_/-}" + [ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)" + + url=$(getvar "_${name}_url" "$url") + sonames=$(getvar "_${name}_so" "ngx_${name}_module.so") + depends="$pkgname $(getvar "_${name}_depends")" + provides=$(getvar "_${name}_provides") + + # Numeric prefix for the module config to ensure that modules with + # dependencies on other modules will be loaded after their dependencies. + # For simplicity, we don't actually resolve dependency tree. Instead, + # we just prefix the module name with a number that reflects number of + # the module's dependencies times ten (e.g. 10, 20, 30, ...). + local conf_prefix="$(echo "$depends" | wc -w)0_" + + mkdir -p "$subpkgdir"/$_modules_dir + mkdir -p "$subpkgdir"/etc/nginx/modules + + cd "$subpkgdir" + + local soname; for soname in $sonames; do + mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname + echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf + done + + mkdir -p ./etc/nginx/naxsi/blocking/ + mkdir -p ./etc/nginx/naxsi/whitelists/ + + cd "$srcdir/.." + case "$name" in + http_naxsi) + install -m644 -D ../../../naxsi_rules/naxsi_core.rules \ + "$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules + install -m644 -D ../../../naxsi_rules/blocking/*.rules \ + "$subpkgdir/etc/nginx/naxsi/blocking/" + install -m644 -D ../../../naxsi_rules/whitelists/*.rules \ + "$subpkgdir/etc/nginx/naxsi/whitelists/" + ;; + esac +} + +# Print value of the specified variable, or the default if empty or not defined. +getvar() { + eval "printf '%s\n' \"\${$1:-$2}\"" +} + +sha512sums=" +1d468dcfa9bbd348b8a5dc514ac1428a789e73a92384c039b73a51ce376785f74bf942872c5594a9fcda6bbf44758bd727ce15ac2395f1aa989c507014647dcc nginx-1.22.1.tar.gz +" diff --git a/dependencies/naxsi/distros/alpine/1.24.0-r3/APKBUILD b/dependencies/naxsi/distros/alpine/1.24.0-r3/APKBUILD new file mode 100644 index 0000000..c9db1d5 --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.24.0-r3/APKBUILD @@ -0,0 +1,227 @@ +# Maintainer: Giovanni Dante Grazioli +pkgname=nginx +pkgver=1.24.0 +pkgrel=3 +pkgdesc="HTTP and reverse proxy server (stable version)" +url="https://www.nginx.org/" +arch="all" +license="BSD-2-Clause" +depends="" +makedepends=" + brotli-dev + gd-dev + geoip-dev + hiredis-dev + jansson-dev + libmaxminddb-dev + libxml2-dev + libxslt-dev + linux-headers + luajit-dev + openssl-dev + pcre-dev + perl-dev + pkgconf + zeromq-dev + zlib-dev + " +checkdepends=" + gd + perl + perl-fcgi + perl-io-socket-ssl + perl-net-ssleay + perl-protocol-websocket + tzdata + uwsgi-python3 + " +pkgusers="nginx" +_grp_ngx="nginx" +_grp_www="www-data" +pkggroups="$_grp_ngx $_grp_www" +install="" +subpackages="" +source="https://nginx.org/download/$pkgname-$pkgver.tar.gz" +builddir="$srcdir/$pkgname-$pkgver" + +_modules_dir="usr/lib/$pkgname/modules" + +# For simplicity we assume that module is hosted on GitHub. +_add_module() { + local name="$1" ver="$2" url="$3" subdir="$4" + local dirname=${url##*/}-${ver#v} + local varprefix="_${name//-/_}" + + eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'" + + # Don't add new flag and source if it's already there, i.e. two or more + # modules share the same source (e.g. geoip2 that provides http-geoip2 + # and stream-geoip2). + if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then + _module_path=$(realpath ../../../$subdir) + _extra_flags="$_extra_flags --add-dynamic-module=$_module_path" + fi + subpackages="$subpackages $pkgname-mod-$name:_module" +} + +_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src" +_naxsi_provides="$pkgname-naxsi" # for backward compatibility + +prepare() { + local file; for file in $source; do + file=${file%%::*} + + case $file in + *~*.patch) + msg $file + cd "$srcdir"/${file%%~*}-* + patch -p 1 -i "$srcdir/$file" + ;; + *.patch) + msg $file + cd "$builddir" + patch -p 1 -i "$srcdir/$file" + ;; + esac + done +} + +_build() { + # --without-pcre2 - Lua module is not compatible with PCRE2 yet + # https://github.com/openresty/lua-nginx-module/issues/1984 + ./configure \ + --prefix=/var/lib/$pkgname \ + --sbin-path=/usr/sbin/$pkgname \ + --modules-path=/$_modules_dir \ + --conf-path=/etc/$pkgname/$pkgname.conf \ + --pid-path=/run/$pkgname/$pkgname.pid \ + --lock-path=/run/$pkgname/$pkgname.lock \ + --http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \ + --http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \ + --http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \ + --http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \ + --http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \ + --with-perl_modules_path=/usr/lib/perl5/vendor_perl \ + \ + --user=$pkgusers \ + --group=$_grp_ngx \ + --with-threads \ + --with-file-aio \ + \ + --without-pcre2 \ + \ + --with-http_ssl_module \ + --with-http_v2_module \ + --with-http_realip_module \ + --with-http_addition_module \ + --with-http_xslt_module=dynamic \ + --with-http_image_filter_module=dynamic \ + --with-http_geoip_module=dynamic \ + --with-http_sub_module \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_mp4_module \ + --with-http_gunzip_module \ + --with-http_gzip_static_module \ + --with-http_auth_request_module \ + --with-http_random_index_module \ + --with-http_secure_link_module \ + --with-http_degradation_module \ + --with-http_slice_module \ + --with-http_stub_status_module \ + --with-http_perl_module=dynamic \ + --with-mail=dynamic \ + --with-mail_ssl_module \ + --with-stream=dynamic \ + --with-stream_ssl_module \ + --with-stream_realip_module \ + --with-stream_geoip_module=dynamic \ + --with-stream_ssl_preread_module \ + \ + $_extra_flags \ + "$@" + + make -j +} + +build() { + cd "$builddir" + + _build --with-debug + mv objs objs-debug + + make clean + _build +} + +check() { + msg "Ignore nginx tests..." +} + +package() { + cd "$builddir" + + make DESTDIR="$pkgdir" install +} + +debug() { + return +} + +vim() { + return +} + +_module() { + local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}" + local ver=$(getvar _${name}_ver) + + pkgdesc="Nginx module ${name//_/-}" + [ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)" + + url=$(getvar "_${name}_url" "$url") + sonames=$(getvar "_${name}_so" "ngx_${name}_module.so") + depends="$pkgname $(getvar "_${name}_depends")" + provides=$(getvar "_${name}_provides") + + # Numeric prefix for the module config to ensure that modules with + # dependencies on other modules will be loaded after their dependencies. + # For simplicity, we don't actually resolve dependency tree. Instead, + # we just prefix the module name with a number that reflects number of + # the module's dependencies times ten (e.g. 10, 20, 30, ...). + local conf_prefix="$(echo "$depends" | wc -w)0_" + + mkdir -p "$subpkgdir"/$_modules_dir + mkdir -p "$subpkgdir"/etc/nginx/modules + + cd "$subpkgdir" + + local soname; for soname in $sonames; do + mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname + echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf + done + + mkdir -p ./etc/nginx/naxsi/blocking/ + mkdir -p ./etc/nginx/naxsi/whitelists/ + + cd "$srcdir/.." + case "$name" in + http_naxsi) + install -m644 -D ../../../naxsi_rules/naxsi_core.rules \ + "$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules + install -m644 -D ../../../naxsi_rules/blocking/*.rules \ + "$subpkgdir/etc/nginx/naxsi/blocking/" + install -m644 -D ../../../naxsi_rules/whitelists/*.rules \ + "$subpkgdir/etc/nginx/naxsi/whitelists/" + ;; + esac +} + +# Print value of the specified variable, or the default if empty or not defined. +getvar() { + eval "printf '%s\n' \"\${$1:-$2}\"" +} + +sha512sums=" +1114e37de5664a8109c99cfb2faa1f42ff8ac63c932bcf3780d645e5ed32c0b2ac446f80305b4465994c8f9430604968e176ae464fd80f632d1cb2c8f6007ff3 nginx-1.24.0.tar.gz +" diff --git a/dependencies/naxsi/distros/alpine/1.24.0-r6/APKBUILD b/dependencies/naxsi/distros/alpine/1.24.0-r6/APKBUILD new file mode 100644 index 0000000..fc8f5cf --- /dev/null +++ b/dependencies/naxsi/distros/alpine/1.24.0-r6/APKBUILD @@ -0,0 +1,227 @@ +# Maintainer: Giovanni Dante Grazioli +pkgname=nginx +pkgver=1.24.0 +pkgrel=6 +pkgdesc="HTTP and reverse proxy server (stable version)" +url="https://www.nginx.org/" +arch="all" +license="BSD-2-Clause" +depends="" +makedepends=" + brotli-dev + gd-dev + geoip-dev + hiredis-dev + jansson-dev + libmaxminddb-dev + libxml2-dev + libxslt-dev + linux-headers + luajit-dev + openssl-dev + pcre-dev + perl-dev + pkgconf + zeromq-dev + zlib-dev + " +checkdepends=" + gd + perl + perl-fcgi + perl-io-socket-ssl + perl-net-ssleay + perl-protocol-websocket + tzdata + uwsgi-python3 + " +pkgusers="nginx" +_grp_ngx="nginx" +_grp_www="www-data" +pkggroups="$_grp_ngx $_grp_www" +install="" +subpackages="" +source="https://nginx.org/download/$pkgname-$pkgver.tar.gz" +builddir="$srcdir/$pkgname-$pkgver" + +_modules_dir="usr/lib/$pkgname/modules" + +# For simplicity we assume that module is hosted on GitHub. +_add_module() { + local name="$1" ver="$2" url="$3" subdir="$4" + local dirname=${url##*/}-${ver#v} + local varprefix="_${name//-/_}" + + eval "${varprefix}_ver='$ver'; ${varprefix}_url='$url'" + + # Don't add new flag and source if it's already there, i.e. two or more + # modules share the same source (e.g. geoip2 that provides http-geoip2 + # and stream-geoip2). + if ! printf '%s\n' $_extra_flags | grep -qFw "$srcdir/$dirname"; then + _module_path=$(realpath ../../../$subdir) + _extra_flags="$_extra_flags --add-dynamic-module=$_module_path" + fi + subpackages="$subpackages $pkgname-mod-$name:_module" +} + +_add_module "http-naxsi" "1.7" "https://github.com/wargio/naxsi" "naxsi_src" +_naxsi_provides="$pkgname-naxsi" # for backward compatibility + +prepare() { + local file; for file in $source; do + file=${file%%::*} + + case $file in + *~*.patch) + msg $file + cd "$srcdir"/${file%%~*}-* + patch -p 1 -i "$srcdir/$file" + ;; + *.patch) + msg $file + cd "$builddir" + patch -p 1 -i "$srcdir/$file" + ;; + esac + done +} + +_build() { + # --without-pcre2 - Lua module is not compatible with PCRE2 yet + # https://github.com/openresty/lua-nginx-module/issues/1984 + ./configure \ + --prefix=/var/lib/$pkgname \ + --sbin-path=/usr/sbin/$pkgname \ + --modules-path=/$_modules_dir \ + --conf-path=/etc/$pkgname/$pkgname.conf \ + --pid-path=/run/$pkgname/$pkgname.pid \ + --lock-path=/run/$pkgname/$pkgname.lock \ + --http-client-body-temp-path=/var/lib/$pkgname/tmp/client_body \ + --http-proxy-temp-path=/var/lib/$pkgname/tmp/proxy \ + --http-fastcgi-temp-path=/var/lib/$pkgname/tmp/fastcgi \ + --http-uwsgi-temp-path=/var/lib/$pkgname/tmp/uwsgi \ + --http-scgi-temp-path=/var/lib/$pkgname/tmp/scgi \ + --with-perl_modules_path=/usr/lib/perl5/vendor_perl \ + \ + --user=$pkgusers \ + --group=$_grp_ngx \ + --with-threads \ + --with-file-aio \ + \ + --without-pcre2 \ + \ + --with-http_ssl_module \ + --with-http_v2_module \ + --with-http_realip_module \ + --with-http_addition_module \ + --with-http_xslt_module=dynamic \ + --with-http_image_filter_module=dynamic \ + --with-http_geoip_module=dynamic \ + --with-http_sub_module \ + --with-http_dav_module \ + --with-http_flv_module \ + --with-http_mp4_module \ + --with-http_gunzip_module \ + --with-http_gzip_static_module \ + --with-http_auth_request_module \ + --with-http_random_index_module \ + --with-http_secure_link_module \ + --with-http_degradation_module \ + --with-http_slice_module \ + --with-http_stub_status_module \ + --with-http_perl_module=dynamic \ + --with-mail=dynamic \ + --with-mail_ssl_module \ + --with-stream=dynamic \ + --with-stream_ssl_module \ + --with-stream_realip_module \ + --with-stream_geoip_module=dynamic \ + --with-stream_ssl_preread_module \ + \ + $_extra_flags \ + "$@" + + make -j +} + +build() { + cd "$builddir" + + _build --with-debug + mv objs objs-debug + + make clean + _build +} + +check() { + msg "Ignore nginx tests..." +} + +package() { + cd "$builddir" + + make DESTDIR="$pkgdir" install +} + +debug() { + return +} + +vim() { + return +} + +_module() { + local name="${subpkgname#$pkgname-mod-}"; name="${name//-/_}" + local ver=$(getvar _${name}_ver) + + pkgdesc="Nginx module ${name//_/-}" + [ "$ver" ] && pkgdesc="Nginx third-party module ${name//_/-} (version $ver)" + + url=$(getvar "_${name}_url" "$url") + sonames=$(getvar "_${name}_so" "ngx_${name}_module.so") + depends="$pkgname $(getvar "_${name}_depends")" + provides=$(getvar "_${name}_provides") + + # Numeric prefix for the module config to ensure that modules with + # dependencies on other modules will be loaded after their dependencies. + # For simplicity, we don't actually resolve dependency tree. Instead, + # we just prefix the module name with a number that reflects number of + # the module's dependencies times ten (e.g. 10, 20, 30, ...). + local conf_prefix="$(echo "$depends" | wc -w)0_" + + mkdir -p "$subpkgdir"/$_modules_dir + mkdir -p "$subpkgdir"/etc/nginx/modules + + cd "$subpkgdir" + + local soname; for soname in $sonames; do + mv "$pkgdir"/$_modules_dir/$soname ./$_modules_dir/$soname + echo "load_module \"modules/$soname\";" >> ./etc/nginx/modules/${conf_prefix}$name.conf + done + + mkdir -p ./etc/nginx/naxsi/blocking/ + mkdir -p ./etc/nginx/naxsi/whitelists/ + + cd "$srcdir/.." + case "$name" in + http_naxsi) + install -m644 -D ../../../naxsi_rules/naxsi_core.rules \ + "$subpkgdir/etc/nginx/naxsi/"naxsi_core.rules + install -m644 -D ../../../naxsi_rules/blocking/*.rules \ + "$subpkgdir/etc/nginx/naxsi/blocking/" + install -m644 -D ../../../naxsi_rules/whitelists/*.rules \ + "$subpkgdir/etc/nginx/naxsi/whitelists/" + ;; + esac +} + +# Print value of the specified variable, or the default if empty or not defined. +getvar() { + eval "printf '%s\n' \"\${$1:-$2}\"" +} + +sha512sums=" +1114e37de5664a8109c99cfb2faa1f42ff8ac63c932bcf3780d645e5ed32c0b2ac446f80305b4465994c8f9430604968e176ae464fd80f632d1cb2c8f6007ff3 nginx-1.24.0.tar.gz +" diff --git a/dependencies/naxsi/distros/alpine/aport-main-nginx.hashes b/dependencies/naxsi/distros/alpine/aport-main-nginx.hashes new file mode 100644 index 0000000..fd77a16 --- /dev/null +++ b/dependencies/naxsi/distros/alpine/aport-main-nginx.hashes @@ -0,0 +1,65 @@ +v3.13.0/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5 +v3.13.1/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5 +v3.13.2/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5 +v3.13.3/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5 +v3.13.4/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5 +v3.13.5/APKBUILD 0e2793dcb53ef7eb67af9a4a2290eaec33f4e2b5 + +v3.13.6/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97 +v3.13.7/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97 +v3.13.8/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97 +v3.13.9/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97 +v3.13.10/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97 +v3.13.11/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97 +v3.13.12/APKBUILD 0058fec14cef94e23e783713c762ae2dc2a8aa97 + +v3.14.0/APKBUILD dcd672113394581d9ed4713c6c31164fe6117403 +v3.14.1/APKBUILD dcd672113394581d9ed4713c6c31164fe6117403 +v3.14.2/APKBUILD dcd672113394581d9ed4713c6c31164fe6117403 +v3.14.3/APKBUILD dcd672113394581d9ed4713c6c31164fe6117403 + +v3.14.4/APKBUILD 5a25cbe63dc00436cce8eb712bbf52c592b9e530 +v3.14.5/APKBUILD 5a25cbe63dc00436cce8eb712bbf52c592b9e530 +v3.14.6/APKBUILD 5a25cbe63dc00436cce8eb712bbf52c592b9e530 + +v3.14.7/APKBUILD 7ede836bb36baf850a2e911cec1bec938715bddf +v3.14.8/APKBUILD 7ede836bb36baf850a2e911cec1bec938715bddf +v3.14.9/APKBUILD 7ede836bb36baf850a2e911cec1bec938715bddf + +v3.14.10/APKBUILD 82c4a602c17a8b9dfce1fc833c968d37ce797cfe + +v3.15.0/APKBUILD 8c79aefdcd91f96faa5166e40a0a554fba000e45 +v3.15.1/APKBUILD 8c79aefdcd91f96faa5166e40a0a554fba000e45 +v3.15.2/APKBUILD 8c79aefdcd91f96faa5166e40a0a554fba000e45 +v3.15.3/APKBUILD 8c79aefdcd91f96faa5166e40a0a554fba000e45 +v3.15.4/APKBUILD 8c79aefdcd91f96faa5166e40a0a554fba000e45 + +v3.15.5/APKBUILD 7fbd4506cd2fc7c402d96f93f955344b9661d293 +v3.15.6/APKBUILD 7fbd4506cd2fc7c402d96f93f955344b9661d293 +v3.15.7/APKBUILD 7fbd4506cd2fc7c402d96f93f955344b9661d293 + +v3.15.8/APKBUILD 934f7d64c39b23cfd0be976bda5c3c3fc8e2fb9f +v3.15.9/APKBUILD 934f7d64c39b23cfd0be976bda5c3c3fc8e2fb9f + +v3.16.0/APKBUILD 9d141041a3dd31d8f63d2fb9e491b36066847ab5 + +v3.16.1/APKBUILD ae51a127df402f10a3510bbb3a0db986ed3f362f +v3.16.2/APKBUILD ae51a127df402f10a3510bbb3a0db986ed3f362f + +v3.16.3/APKBUILD cf21abf069b99df0466109da431e257be35e5fd2 +v3.16.4/APKBUILD cf21abf069b99df0466109da431e257be35e5fd2 + +v3.16.5/APKBUILD 741f460e98d96286e3178f0892e43e4b24c105ba +v3.16.6/APKBUILD 741f460e98d96286e3178f0892e43e4b24c105ba + +v3.17.0/APKBUILD a454a4380d8319d944ecf689d7e4c68a3e3c3a77 +v3.17.1/APKBUILD a454a4380d8319d944ecf689d7e4c68a3e3c3a77 +v3.17.2/APKBUILD a454a4380d8319d944ecf689d7e4c68a3e3c3a77 + +v3.17.3/APKBUILD 755ae65dbf1112735fbe16c987ce0a1ee9962223 +v3.17.4/APKBUILD 755ae65dbf1112735fbe16c987ce0a1ee9962223 + +v3.18.0/APKBUILD 5ac489bf563ac1f9fd8389f5f227a6fcd260e6e4 + +v3.18.1/APKBUILD 3047d360052cbd089f7c960b7c72727b9fe1a390 +v3.18.2/APKBUILD 3047d360052cbd089f7c960b7c72727b9fe1a390 diff --git a/dependencies/naxsi/distros/alpine/build-ci.sh b/dependencies/naxsi/distros/alpine/build-ci.sh new file mode 100755 index 0000000..8a3dd60 --- /dev/null +++ b/dependencies/naxsi/distros/alpine/build-ci.sh @@ -0,0 +1,58 @@ +#!/bin/sh +set -e + +NAXSI_ROOT="$PWD" +BUILD_DIR="$NAXSI_ROOT/build" +ALPINE_VERSION=$(cat /etc/alpine-release) +VERSION="unknown" + +case "v$ALPINE_VERSION" in + "v3.13.0" | "v3.13.1" | "v3.13.2" | "v3.13.3" | "v3.13.4" | "v3.13.5") + VERSION="1.18.0-r13" + ;; + "v3.13.6" | "v3.13.7" | "v3.13.8" | "v3.13.9" | "v3.13.10" | "v3.13.11" | "v3.13.12") + VERSION="1.18.0-r15" + ;; + "v3.14.0" | "v3.14.1" | "v3.14.2" | "v3.14.3") + VERSION="1.20.1-r3" + ;; + "v3.14.4" | "v3.14.5" | "v3.14.6" | "v3.15.0" | "v3.15.1" | "v3.15.2" | "v3.15.3" | "v3.15.4") + VERSION="1.20.2-r0" + ;; + "v3.14.7" | "v3.14.8" | "v3.14.9" | "v3.14.10" | "v3.15.5" | "v3.15.6" | "v3.15.7" | "v3.15.8" | "v3.15.9" | "v3.16.0") + VERSION="1.20.2-r1" + ;; + "v3.16.1" | "v3.16.2") + VERSION="1.22.0-r1" + ;; + "v3.16.3" | "v3.16.4" | "v3.16.5" | "v3.16.6" | "v3.17.0" | "v3.17.1" | "v3.17.2" | "v3.17.3" | "v3.17.4") + VERSION="1.22.1-r0" + ;; + "v3.18.0") + VERSION="1.24.0-r3" + ;; + "v3.18.1" | "v3.18.2") + VERSION="1.24.0-r6" + ;; + *) + echo "error: unsupported version, please open an issue on github." + exit 1 + ;; +esac + +echo "Alpine $ALPINE_VERSION, using $VERSION APKBUILD..." + +if [ -d "$BUILD_DIR" ]; then + rm -rf "$BUILD_DIR" +fi +mkdir "$BUILD_DIR" + +echo "$BUILD_DIR/naxsi.key" | abuild-keygen -a +cp -v "$BUILD_DIR/naxsi.key.pub" /etc/apk/keys + +cd "$NAXSI_ROOT/distros/alpine/$VERSION" + +SRCDEST="$BUILD_DIR" abuild -F fetch +SRCDEST="$BUILD_DIR" abuild -F -c -r -P "$BUILD_DIR" + +find "$BUILD_DIR" -name "*.apk" | grep naxsi | xargs -I % mv -v % "$BUILD_DIR" diff --git a/dependencies/naxsi/distros/arch/PKGBUILD b/dependencies/naxsi/distros/arch/PKGBUILD new file mode 100644 index 0000000..e946ee1 --- /dev/null +++ b/dependencies/naxsi/distros/arch/PKGBUILD @@ -0,0 +1,69 @@ +# Maintainer: Giovanni Dante (deroad) Grazioli + +pkgname=nginx-mod-naxsi-git +pkgver=1.7 +pkgrel=1 +epoch=1 +_modname=naxsi +pkgdesc='Nginx Anti XSS & SQL Injection' +arch=('x86_64') +depends=('nginx') +makedepends=('nginx-src') +url="https://github.com/wargio/naxsi" +license=('GPL3') +backup=('etc/nginx/naxsi_core.rules') +conflicts=('nginx-mod-naxsi') +source=( + "$pkgname::git+https://github.com/wargio/$_modname.git" +) +sha256sums=('SKIP') + +pkgver () { + cd ${srcdir}/${pkgname} + printf $(grep "NAXSI_VERSION" naxsi_src/naxsi_const.h | cut -d ' ' -f3 | sed 's/"//g') +} + +prepare() { + cd ${pkgname} + git submodule init + git config submodule.libinjection.url "${srcdir}/${pkgname}/naxsi_src/libinjection" + git submodule update + + mkdir -p ${srcdir}/build + cd ${srcdir}/build + + ln -sf /usr/src/nginx/auto + ln -sf /usr/src/nginx/src +} + +build() { + cd ${srcdir}/build + local GCC_PATH=$(which gcc) + /usr/src/nginx/configure --with-cc="$GCC_PATH" --with-compat --add-dynamic-module="${srcdir}/${pkgname}/naxsi_src" + make modules +} + +package() { + cd $srcdir/build/objs + for mod in *.so; do + install -Dm755 $mod "$pkgdir"/usr/lib/nginx/modules/$mod + done + + mkdir -p "$pkgdir"/etc/nginx/naxsi/whitelists + mkdir -p "$pkgdir"/etc/nginx/naxsi/blocking + + install -Dm644 "$srcdir/${pkgname}"/distros/nginx/naxsi_block_mode.conf "$pkgdir"/etc/nginx/naxsi/naxsi_block_mode.conf + install -Dm644 "$srcdir/${pkgname}"/distros/nginx/naxsi_denied_url.conf "$pkgdir"/etc/nginx/naxsi/naxsi_denied_url.conf + install -Dm644 "$srcdir/${pkgname}"/distros/nginx/naxsi_learning_mode.conf "$pkgdir"/etc/nginx/naxsi/naxsi_learning_mode.conf + install -Dm644 "$srcdir/${pkgname}"/naxsi_rules/naxsi_core.rules "$pkgdir"/etc/nginx/naxsi/naxsi_core.rules + + cd "$srcdir/${pkgname}"/naxsi_rules/whitelists/ + for rule in *.rules; do + install -Dm644 $rule "$pkgdir"/etc/nginx/naxsi/whitelists/$rule + done + + cd "$srcdir/${pkgname}"/naxsi_rules/blocking/ + for rule in *.rules; do + install -Dm644 $rule "$pkgdir"/etc/nginx/naxsi/blocking/$rule + done +} diff --git a/dependencies/naxsi/distros/deb/control.install b/dependencies/naxsi/distros/deb/control.install new file mode 100644 index 0000000..e56743a --- /dev/null +++ b/dependencies/naxsi/distros/deb/control.install @@ -0,0 +1,9 @@ +PACKAGE="libnginx-mod-http-naxsi" +VERSION="@NAXSI_VERSION@" +SECTION="httpd" +ARCHITECTURE="amd64" +DEPENDENCIES="@NGINX_PACKAGE@ (>= @NGINX_VERSION@), @LIBPCRE_PACKAGE@ (>= @LIBPCRE_VERSION@)" +MAINTAINER_NAME="Giovanni Dante Grazioli" +MAINTAINER_EMAIL="deroad@libero.it" +HOMEPAGE="https://github.com/wargio/naxsi" +DESCRIPTION="NAXSI, a web application firewall for Nginx." \ No newline at end of file diff --git a/dependencies/naxsi/distros/deb/mod-http-naxsi.conf b/dependencies/naxsi/distros/deb/mod-http-naxsi.conf new file mode 100644 index 0000000..340b92c --- /dev/null +++ b/dependencies/naxsi/distros/deb/mod-http-naxsi.conf @@ -0,0 +1 @@ +load_module modules/ngx_http_naxsi_module.so; \ No newline at end of file diff --git a/dependencies/naxsi/distros/deb/postinstall.script b/dependencies/naxsi/distros/deb/postinstall.script new file mode 100644 index 0000000..a81e426 --- /dev/null +++ b/dependencies/naxsi/distros/deb/postinstall.script @@ -0,0 +1,30 @@ +#!/bin/sh +set -e +# Automatically added by dh_nginx/UNDECLARED +for confpair in mod-http-naxsi.conf:50-mod-http-naxsi.conf ; do + from=$(echo $confpair | cut -d: -f1) + to=$(echo $confpair | cut -d: -f2) + + if [ -L /etc/nginx/modules-enabled/$to.removed ]; then + rm /etc/nginx/modules-enabled/$to.removed + removed_link=true + else + removed_link=false + fi + + # Symlink on + # 1) Fresh installations + # 2) Reinstalls after automatic removes (preserve admin actions) + if [ -z "$2" -o "$removed_link" = "true" ]; then + ln -sf /usr/share/nginx/modules-available/$from \ + /etc/nginx/modules-enabled/$to + fi +done + +if [ "$1" = "configure" ] ; then + if which dpkg-trigger >/dev/null 2>&1 ; then + dpkg-trigger --no-await nginx-reload + fi + +fi +# End automatically added section \ No newline at end of file diff --git a/dependencies/naxsi/distros/deb/postremove.script b/dependencies/naxsi/distros/deb/postremove.script new file mode 100644 index 0000000..0564f63 --- /dev/null +++ b/dependencies/naxsi/distros/deb/postremove.script @@ -0,0 +1,32 @@ +#!/bin/sh +set -e +# Automatically added by dh_nginx/UNDECLARED +if [ "$1" = "purge" ] ; then + for confpair in mod-http-naxsi.conf:50-mod-http-naxsi.conf ; do + from=$(echo $confpair | cut -d: -f1) + to=$(echo $confpair | cut -d: -f2) + + if [ -L /etc/nginx/modules-enabled/$to ]; then + rm /etc/nginx/modules-enabled/$to + fi + if [ -L /etc/nginx/modules-enabled/$to.removed ]; then + rm /etc/nginx/modules-enabled/$to.removed + fi + done +fi + +if [ "$1" = "remove" ] ; then + for confpair in mod-http-naxsi.conf:50-mod-http-naxsi.conf ; do + from=$(echo $confpair | cut -d: -f1) + to=$(echo $confpair | cut -d: -f2) + + if [ -L /etc/nginx/modules-enabled/$to ]; then + mv /etc/nginx/modules-enabled/$to /etc/nginx/modules-enabled/$to.removed + fi + done + + if which dpkg-trigger >/dev/null 2>&1 ; then + dpkg-trigger --no-await nginx-reload + fi +fi +# End automatically added section \ No newline at end of file diff --git a/dependencies/naxsi/distros/deb/preremove.script b/dependencies/naxsi/distros/deb/preremove.script new file mode 100644 index 0000000..ad6a039 --- /dev/null +++ b/dependencies/naxsi/distros/deb/preremove.script @@ -0,0 +1,14 @@ +#!/bin/sh +set -e +# Automatically added by dh_nginx/UNDECLARED +if [ "$1" = "remove" ] || [ "$1" = "deconfigure" ] ; then + for confpair in mod-http-naxsi.conf:50-mod-http-naxsi.conf ; do + from=$(echo $confpair | cut -d: -f1) + to=$(echo $confpair | cut -d: -f2) + + if [ -L /etc/nginx/modules-enabled/$to ]; then + mv /etc/nginx/modules-enabled/$to /etc/nginx/modules-enabled/$to.removed + fi + done +fi +# End automatically added section \ No newline at end of file diff --git a/dependencies/naxsi/distros/nginx/naxsi_block_mode.conf b/dependencies/naxsi/distros/nginx/naxsi_block_mode.conf new file mode 100644 index 0000000..db9b2be --- /dev/null +++ b/dependencies/naxsi/distros/nginx/naxsi_block_mode.conf @@ -0,0 +1,15 @@ +SecRulesEnabled; #enable naxsi +LibInjectionSql; #enable libinjection support for SQLI +LibInjectionXss; #enable libinjection support for XSS + +#the location where naxsi will redirect the request when it is blocked +DeniedUrl "/NaxsiRequestDenied"; + +#the action to take when the $SQL score is superior or equal to 8 +CheckRule "$SQL >= 8" BLOCK; +CheckRule "$RFI >= 8" BLOCK; +CheckRule "$TRAVERSAL >= 5" BLOCK; +CheckRule "$UPLOAD >= 5" BLOCK; +CheckRule "$XSS >= 8" BLOCK; +CheckRule "$UWA >= 8" BLOCK; +CheckRule "$EVADE >= 8" BLOCK; \ No newline at end of file diff --git a/dependencies/naxsi/distros/nginx/naxsi_denied_url.conf b/dependencies/naxsi/distros/nginx/naxsi_denied_url.conf new file mode 100644 index 0000000..65b23a8 --- /dev/null +++ b/dependencies/naxsi/distros/nginx/naxsi_denied_url.conf @@ -0,0 +1,4 @@ +location /NaxsiRequestDenied { + internal; + return 418; #I'm a teapot \o/ +} \ No newline at end of file diff --git a/dependencies/naxsi/distros/nginx/naxsi_learning_mode.conf b/dependencies/naxsi/distros/nginx/naxsi_learning_mode.conf new file mode 100644 index 0000000..9586ca5 --- /dev/null +++ b/dependencies/naxsi/distros/nginx/naxsi_learning_mode.conf @@ -0,0 +1,16 @@ +SecRulesEnabled; #enable naxsi +LearningMode; #enable learning mode +LibInjectionSql; #enable libinjection support for SQLI +LibInjectionXss; #enable libinjection support for XSS + +#the location where naxsi will redirect the request when it is blocked +DeniedUrl "/NaxsiRequestDenied"; + +#the action to take when the $SQL score is superior or equal to 8 +CheckRule "$SQL >= 8" BLOCK; +CheckRule "$RFI >= 8" BLOCK; +CheckRule "$TRAVERSAL >= 5" BLOCK; +CheckRule "$UPLOAD >= 5" BLOCK; +CheckRule "$XSS >= 8" BLOCK; +CheckRule "$UWA >= 8" BLOCK; +CheckRule "$EVADE >= 8" BLOCK; \ No newline at end of file diff --git a/dependencies/naxsi/docs/basic-configuration.md b/dependencies/naxsi/docs/basic-configuration.md new file mode 100644 index 0000000..ccad16d --- /dev/null +++ b/dependencies/naxsi/docs/basic-configuration.md @@ -0,0 +1,139 @@ +# **Naxsi Basic Configuration** + +To get started with Naxsi, you can explore the following basic configuration. + +## **Configuring Naxsi** + +Naxsi must be configured based on what it is going to protect. + +The first step, once compiled dynamically compiled, you will have a shared library which will need to be loaded by nginx by adding an entry to the `/etc/nginx/nginx.conf` file. + +```nginx +load_module /usr/lib/nginx/modules/ngx_http_naxsi_module.so; +``` + +Once the module is added to the NGINX configuration, the next step is to **include global rules**; in the Naxsi repository you can find the [**`naxsi_core.rules`**](https://github.com/wargio/naxsi/blob/main/naxsi_rules/naxsi_core.rules) which gives to the user the ability to add the most basic ruleset to Naxsi itself. + +> 💡 Tip +> +> It is possible to include these rules directly in `/etc/nginx/nginx.conf`. + +```nginx +include /etc/nginx/naxsi/naxsi_core.rules +``` + +The next step is configuring each website which will need to be protected by Naxsi; this happens by adding the directives `SecRulesEnabled`, `DeniedUrl` and `CheckRule` to a `location` block. + +* `SecRulesEnabled`: is used to enable Naxsi in the `location` block. +* `DeniedUrl`: specifies where blocked requests will be redirected (**this is an internal redirect for NGINX** and requires a different `location` block as destination). +* `CheckRule`: takes an action (`LOG`, `BLOCK`, `DROP`, `ALLOW`) based on a specific score associated with the request. + +For more details, check the [Directive chapter](directives.md) + +```nginx +location / { + SecRulesEnabled; + DeniedUrl "/RequestDenied"; + CheckRule "$FOO >= 8" BLOCK; +} + +# The location where all the blocked request will be internally redirected. +location /RequestDenied { + internal; + return 403; +} +``` + +The last steps are create whitelists and configure the logging. + +```nginx +# example of whitelist (global and location-defined) +MainRule wl:1000,1009,1315 "mz:$BODY_VAR:_wp_http_referer"; +BasicRule wl:1000,1009,1315 "mz:$BODY_VAR:_wp_http_referer"; + +# Enable JSON logs for Naxsi +set $naxsi_json_log 1; +``` + +## **Example Configuration** + +This NGINX configuration for `/etc/nginx/nginx.conf` where we define a reverse proxy towards a webservice hosted on `internal-ip-address` on port `80`. + +```nginx +# load module +load_module /etc/nginx/modules/ngx_http_naxsi_module.so; + +server { + listen 80; + server_name example.com; + + set $naxsi_json_log 1; # Enable JSON logs for Naxsi + include /etc/nginx/naxsi/naxsi_core.rules; # Include core rules (see below) + + location / { + proxy_pass http://internal-ip-address:80; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + + SecRulesEnabled; #enable naxsi for this `location` + # LearningMode; #When enable, BLOCK CheckRule are considered as LOG. + LibInjectionSql; #enable libinjection support for SQL injection detection + LibInjectionXss; #enable libinjection support for XSS detection + + # Internal denied request. + DeniedUrl "/RequestDenied"; + + # Include additional rules + include /etc/nginx/naxsi/blocking/*.rules; + + # The following CheckRules are mandatory when using the rules found in the naxsi repository. + # For more info, please check: + # - https://github.com/wargio/naxsi/tree/main/naxsi_rules/blocking + # - https://github.com/wargio/naxsi/blob/main/naxsi_rules/naxsi_core.rules + + CheckRule "$SQL >= 8" BLOCK; # SQL injection action (unrelated to libinjection) + CheckRule "$XSS >= 8" BLOCK; # XSS action (unrelated to libinjection) + CheckRule "$RFI >= 8" BLOCK; # Remote File Inclusion action + CheckRule "$UWA >= 8" BLOCK; # Unwanted Access action + CheckRule "$EVADE >= 8" BLOCK; # Evade action (some tools may try to avoid detection). + CheckRule "$UPLOAD >= 5" BLOCK; # Malicious upload action + CheckRule "$TRAVERSAL >= 5" BLOCK; # Traversal access action + CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; # libinjection XSS action + CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; # libinjection SQLi action + } + + # The location where all the blocked request will be internally redirected. + location /RequestDenied { + internal; + return 403; + } +} +``` + +This configuration enables NAXSI and sets up basic rules for blocking requests based on various threat levels. + +> 📣 Important +> +> The `SecRulesEnabled` directive is mandatory to enable NAXSI in a location. + +Some key directives used in this example include: + +* `LearningMode`: if enabled, `BLOCK` CheckRule will be considered as `LOG`, thus not blocking the requests. +* `LibInjectionXss` and `LibInjectionSql`: When defined, enables libinjection support for SQLi & XSS and requires to define `$LIBINJECTION_XSS` & `$LIBINJECTION_SQL` **`**CheckRules**. +* `include`: This directive allows to include other configuration files within the current scope, this can be useful if the system owner wants to have the same configuration for multiple websites without copy-pasting the same lines. + +Additionally, this configuration includes directives for enabling libinjection's XSS and SQLi detection features. + +> ⚠️ Warning +> +> **Be aware that Nginx will fail to load the configuration, if `ngx_http_naxsi_module.so` is not loaded**. + +> 💡 Tip +> +> It is possible to test the NGINX configuration by using `nginx -t` from the command line. + +# Go Back + +[Table of Contents](index.md). diff --git a/dependencies/naxsi/docs/build-naxsi.md b/dependencies/naxsi/docs/build-naxsi.md new file mode 100644 index 0000000..3239826 --- /dev/null +++ b/dependencies/naxsi/docs/build-naxsi.md @@ -0,0 +1,171 @@ +# **Installing Naxsi** + +In this section you can find how to install and build naxsi on various distributions. + +## **Ubuntu/Debian** + +Ubuntu & Debian do not provide a package for this, but you can easily compile naxsi using `apt-get source` to fetch the correct version of nginx as follows. + +1. **Download the required software** + +> ℹ️ Info +> +> Some Debian and Ubuntu distributions uses **`libpcre2-dev`** instad of `libpcre3-dev`. + +> ℹ️ Info +> +> Debian bookworm requires also **`libperl-dev`** + +```bash +# Install required software +apt-get install build-essential ca-certificates \ + dpkg-dev zlib1g-dev libgd-dev libgeoip-dev \ + libpcre3-dev libperl-dev libssl-dev libxslt1-dev \ + gzip git nginx tar wget +``` + +We also need to download **Naxsi** + +```bash +NAXSI_VERSION=X.Y +wget "https://github.com/wargio/naxsi/releases/download/$NAXSI_VERSION/naxsi-$NAXSI_VERSION-src-with-deps.tar.gz" +mkdir -p naxsi +tar -C naxsi -xzf naxsi-$NAXSI_VERSION-src-with-deps.tar.gz +``` + +And fetch the NGINX source via `apt-get source`. + +```bash +apt-get source nginx +``` + +2. **Retrieve the distro compile flags** + +To correctly build Naxsi for Debian/Ubuntu, you will need to retrieve the configure arguments (also called `compile flags`) using `nginx -V`, as shown below. + +```bash +nginx -V +``` + +Example of output: + +``` +nginx version: nginx/1.18.0 (Ubuntu) +built with OpenSSL 1.1.1f 31 Mar 2020 +TLS SNI support enabled +configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-lUTckl/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_gzip_static_module --without-http_browser_module --without-http_geo_module --without-http_limit_req_module --without-http_limit_conn_module --without-http_memcached_module --without-http_referer_module --without-http_split_clients_module --without-http_userid_module --add-dynamic-module=/build/nginx-lUTckl/nginx-1.18.0/debian/modules/http-echo +``` + +To simplify this process, you can use the following command, which takes the output of `nginx -V` and modifies it; this can be used as a quick way to get "ready-to-use" configure arguments for building NGINX. + +```bash +nginx -V 2>&1 | grep "configure arguments:" | cut -d ":" -f2- | sed -e "s#/build/nginx-[A-Za-z0-9]*/#./#g" | sed 's/--add-dynamic-module=[A-Za-z0-9\/\._-]*//g' +``` + +Example of output: + +``` +--with-cc-opt='-g -O2 -fdebug-prefix-map=./nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-compat --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_gzip_static_module --without-http_browser_module --without-http_geo_module --without-http_limit_req_module --without-http_limit_conn_module --without-http_memcached_module --without-http_referer_module --without-http_split_clients_module --without-http_userid_module +``` + +3. **Build NGINX with Naxsi as module** + +Now we will build Naxsi using NGINX sources: + +```bash +# Build NGINX with Naxsi +cd nginx-* +NGINX_BUILD_FLAGS=$(nginx -V 2>&1 | grep "configure arguments:" | cut -d ":" -f2- | sed -e "s#/build/nginx-[A-Za-z0-9]*/#./#g" | sed 's/--add-dynamic-module=[A-Za-z0-9\/\._-]*//g') +./configure $NGINX_BUILD_FLAGS --add-dynamic-module=../naxsi/naxsi_src/ +make modules +``` + +You will find the built module at the following path: + +``` +nginx-/objs/ngx_http_naxsi_module.so +``` + +The other files you will need, are **the rules**, which can be found at the following path: + +``` +naxsi/naxsi_rules +``` + +> ⚠️ Warning +> +> **Be aware that you may encounter the following error related to `libinjection`, which can be safely ignored.** + +``` +[truncated output ...] +configuring additional dynamic modules +adding module in ../naxsi/naxsi_src +Package libinjection was not found in the pkg-config search path. +Perhaps you should add the directory containing `libinjection.pc' +to the PKG_CONFIG_PATH environment variable +No package 'libinjection' found +Package libinjection was not found in the pkg-config search path. +Perhaps you should add the directory containing `libinjection.pc' +to the PKG_CONFIG_PATH environment variable +No package 'libinjection' found +Using submodule libinjection + + naxsi was configured +``` + +# **Compiling Naxsi from Sources** + +> ℹ️ Info +> +> You will need to have a working C dev environment installed on your system, for tools like `gcc` or `clang` and `make`, in order to compile Naxsi. + +> ⚠️ Warning +> +> You will need to have `libpcre` or `libpcre2` or `libpcre3` installed to correctly build Naxsi. + +To compile Naxsi from source code, follow these steps: + +1. **Get Naxsi sources** + +```bash +NAXSI_VERSION=X.Y +wget "https://github.com/wargio/naxsi/releases/download/$NAXSI_VERSION/naxsi-$NAXSI_VERSION-src-with-deps.tar.gz" +mkdir -p naxsi +tar -C naxsi -xzf naxsi-$NAXSI_VERSION-src-with-deps.tar.gz +``` + +2. **Get NGINX sources** + +```bash +NGINX_VERSION=X.Y.Z +wget https://nginx.org/download/nginx-$NGINX_VERSION.tar.gz +mkdir -p nginx +tar -C nginx -xzf nginx-$NGINX_VERSION.tar.gz +``` + +3. **Build NGINX and Naxsi** + +``` +cd nginx +./configure --add-dynamic-module=../naxsi/naxsi_src/ +make modules +``` + +4. **Install Nginx and Naxsi** + +You can automatically install the files using `make install` or alternatively you can manually install the built module using: + +You will find the built module at the following path: + +``` +nginx/objs/ngx_http_naxsi_module.so +``` + +The other files you will need, are **the rules**, which can be found at the following path: + +``` +naxsi/naxsi_rules +``` + +# Next + +[Basic Configuration](basic-configuration.md). \ No newline at end of file diff --git a/dependencies/naxsi/docs/directives.md b/dependencies/naxsi/docs/directives.md new file mode 100644 index 0000000..8cddf22 --- /dev/null +++ b/dependencies/naxsi/docs/directives.md @@ -0,0 +1,252 @@ +# **Naxsi Directives** + +This section explains all the directives, with examples, that are available when the Naxsi module (`ngx_http_naxsi_module.so`) is enabled. + +## **SecRulesEnabled** + +> ℹ️ Info +> +> NGINX block: `location` + +This directive is mandatory to `enable` naxsi in a NGINX `location`. + +### Example: + +```nginx +location / { + SecRulesEnabled; +} +``` + +## **CheckRule** + +> ℹ️ Info +> +> NGINX block: `location` + +This directive is required to instruct Naxsi on which action to take when there is a rule match. + +The directive requires you to specify a **score** with a variable name and its min/max value (for example `$FOO_BAR >= 4`); the score is then followed by an action to take (`LOG`, `BLOCK`, `DROP`, or `ALLOW`) when is met. + +> 📣 Important +> +> Score variable names must starts with a "dollar sign" `$` and can contains "underscores" `_`. + +> ⚠️ Warning +> +> The action `BLOCK` will behave like `DROP` only when `LearningMode` is not enabled. + +### Example: + +```nginx +location / { + CheckRule "$FOO_UU >= 8" LOG; + CheckRule "$BARRRR < 99" DROP; + CheckRule "$SOMETHING <= 33" BLOCK; +} +``` + +## **LibInjectionXss** + +> ℹ️ Info +> +> NGINX block: `location` + +When defined, this directive enables [libinjection's](https://github.com/libinjection/libinjection) xss detection on *all* requests. + +> 📣 Important +> +> The detected XSS will increase the score `$LIBINJECTION_XSS` by `1` for each match; this means that is required to define `$LIBINJECTION_XSS` as a `CheckRule`. + +### Example: + +```nginx +location / { + # enable libinjection xss + LibInjectionXss; + # define LIBINJECTION_XSS for libinjection + CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; +} +``` + +## **LibInjectionSql** + +> ℹ️ Info +> +> NGINX block: `location` + +When defined, this directive enables [libinjection's](https://github.com/libinjection/libinjection) sqli detection on *all* requests. + +> 📣 Important +> +> The detected SQLi will increase the score `$LIBINJECTION_SQL` by `1` for each match; this means that is required to define `$LIBINJECTION_SQL` as a `CheckRule`. + +### Example: + +```nginx +location / { + # enable libinjection sqli + LibInjectionSql; + # define LIBINJECTION_SQL for libinjection + CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; +} +``` + +## **LearningMode** + +> ℹ️ Info +> +> NGINX block: `location` + +This directive instructs Naxsi that to not honor `CheckRules` which defines actions as `BLOCK` in a NGINX `location`. + +All the `BLOCK` actions will be interpreted as `LOG`; this is a useful mode when deploying a new web application and detect all false positives that might be generated by the WAF. + +> 📣 Important +> +> Keep in mind that internal rules (those with an `id` inferior to 1000) will drop the request even in learning mode, because it means something fishy is going on and Naxsi can't correctly process the request. You can of course apply whitelists if those are false positives. + +### Example: + +```nginx +location / { + # enable Naxsi learning mode + LearningMode; +} +``` + +## **DeniedUrl** + +> ℹ️ Info +> +> NGINX block: `location` + +This directive is used to define where Naxsi has to redirect (it's an NGINX's internal redirect) when blocking, dropping or logging requests. + +The following headers that are added are when blocking, dropping or logging requests: + - `x-orig_url` + - `x-orig_args` + - `x-naxsi_sig` + +> 💡 Tip +> +> It is **strongly** suggested to mark the `DeniedUrl` location as `internal` to prevent possible pre-detection of the WAF as per example. + +### Example: + +```nginx +location / { + DeniedUrl "/RequestDenied"; +} + +location /RequestDenied { + # Mark this location as internal only to prevent possible pre-detection of the WAF + internal; + # return code of the location. + return 403; +} +``` + +## **MainRule** + +> ℹ️ Info +> +> NGINX block: `http` + +This directive is required to declare a **global** [rule](rules.md) or a [whitelist](whitelist.md). + +> 💡 Tip +> +> You can define these within a config file and use the `include` directive to include them within the NGINX configuration. + +You can find within the [Naxsi source code a list of global rules](https://github.com/wargio/naxsi/blob/main/naxsi_rules/) which provides a basic ruleset to protect any web application; these rules requires to include the following `CheckRules`: + +```nginx + CheckRule "$SQL >= 8" BLOCK; + CheckRule "$RFI >= 8" BLOCK; + CheckRule "$TRAVERSAL >= 5" BLOCK; + CheckRule "$UPLOAD >= 5" BLOCK; + CheckRule "$XSS >= 8" BLOCK; + CheckRule "$UWA >= 8" BLOCK; + CheckRule "$EVADE >= 8" BLOCK; +``` + +### Example: + +```nginx +http { + # global whitelist + MainRule wl:12345 "mz:$URL:/robots.txt|URL"; + # global rule + MainRule id:45678 "s:$UWA:8" "str:nmap" "mz:$HEADERS_VAR:User-Agent" "msg:nmap in user-agent"; +} +``` + +## **BasicRule** + +> ℹ️ Info +> +> NGINX block: `location` + +This directive is required to declare a **location-specific** (i.e. not global) [rule](rules.md) or a [whitelist](whitelist.md). + +> 💡 Tip +> +> You can define these within a config file and use the `include` directive to include them within the NGINX configuration. + +> 💡 Tip +> +> You can find within the [Naxsi source code a list of location-specific whitelist](https://github.com/wargio/naxsi/tree/main/naxsi_rules/whitelists) which can be used for known web applications like Wordpress, Etherpad, Drupal, and more... + +### Example: + +```nginx +location / { + # location-specific whitelist + BasicRule wl:12345 "mz:$URL:/robots.txt|URL"; + # location-specific rule + BasicRule id:45678 "s:$UWA:8" "str:nmap" "mz:$HEADERS_VAR:User-Agent" "msg:nmap in user-agent"; +} +``` + +## **IgnoreIP** + +> ℹ️ Info +> +> NGINX block: `location` + +This directive can be used to whitelist requests from certain IPs. + +> 💡 Tip +> +> You can define these within a config file and use the `include` directive to include them within the NGINX configuration. + +### Example: + +```nginx +location / { + IgnoreIP "1.2.3.4"; + IgnoreIP "2001:4860:4860::8844"; +} +``` + +## **IgnoreCIDR** + +> ℹ️ Info +> +> NGINX block: `location` + +This directive can be used to whitelist requests from certain IP ranges. + +> 💡 Tip +> +> You can define these within a config file and use the `include` directive to include them within the NGINX configuration. + +### Example: + +```nginx +location / { + IgnoreCIDR "192.168.0.0/24"; + IgnoreCIDR "2001:4860:4860::/112"; +} +``` diff --git a/dependencies/naxsi/docs/index.md b/dependencies/naxsi/docs/index.md new file mode 100644 index 0000000..921a0bc --- /dev/null +++ b/dependencies/naxsi/docs/index.md @@ -0,0 +1,79 @@ +# **Naxsi Web Application Firewall Documentation** + +Naxsi is a Free Open Source Web Application Firewall which runs under NGINX. + +## What is a Web Application Firewall (WAF)? + +A Web Application Firewall (WAF) is a security system that sits in front of a web application to inspect, filter, and block malicious traffic. It acts as an intermediary between the internet and your website or web application, examining HTTP requests and responses for potential threats. + +One of the key features of WAFs is virtual patching, which allows them to protect against known vulnerabilities without requiring actual patches to be applied to the underlying code. Here's how it works on Naxsi: + +1. **Rule-based detection**: The WAF has a list of known patterns, i.e. malicious request, which are used to block requests. +2. **Request analysis**: When an incoming HTTP request is received, the WAF analyzes its contents against the list of patterns. +3. **Threat identification**: If the request matches a known pattern, the WAF first checks if there is a whitelist rule and if not, then it assigns a score to the request; if this score exceeds the score limits then the request is blocked. + +Naxsi is also capable to employ a whitelisting strategy, where all incoming traffic is initially blocked by default. In this case, only the requests that match specific rules are then allowed to pass through and reach the web application behind the WAF. This approach provides an added layer of security by assuming all unknown traffic poses a potential threat until proven otherwise. + +## Virtual patching + +Sometimes it happens that the web application behind the WAF might have a security vulnerability that cannot be patched immediately by the system owner; Naxsi can apply "virtual patches" to block the vulnerability without requiring changes to the underlying web application code. + +By using virtual patching, the system owner can: + +* Protect against zero-day attacks and unknown vulnerabilities +* Prevent exploitation of unpatched or outdated software versions +* Reduce the attack surface by blocking suspicious requests before they reach your website + +These virtual patches are expressed in form of Naxsi rules and can be applied to RAW requests or specific fields within the request. + +## What does it run on? + +Naxsi should be compatible with any NGINX version, and is reported to work great on NetBSD, FreeBSD, OpenBSD, Debian, Ubuntu and CentOS based systems. + +## Why is it different? + +Contrary to most Web Application Firewalls, Naxsi doesn't rely on a signature base like an antivirus, and thus cannot be circumvented by an "unknown" attack pattern. + +# Getting Started + +* **Installing Naxsi**: [Learn how to compile and install Naxsi from source code.](build-naxsi.md) +* **Basic Configuration**: [A basic configuration for Naxsi](basic-configuration.md). + +# Configuration Options + +* **Directives**: [Explains all the directives that are available when the Naxsi module is enabled.](directives.md) +* **Rules**: [Understand the different types of rules you can create in Naxsi.](rules.md) +* **Internal Rules**: [The full list of internal rules that are hardcoded in Naxsi](internal_rules.md) +* **Whitelists**: [Whitelisting to resolve false positives in Naxsi.](whitelist.md) +* **Matchzones**: [How zones can be used to filter rules or whitelists.](matchzones.md) +* **Logs**: [Log format and their content.](logs.md) +* **Packaging Naxsi**: [Build your own distro packages from sources.](packaging-naxsi.md) + +# Support & Bugs + +Questions & bug reports regarding NAXSI can be addressed via issues. + +[Click here to open an issue](https://github.com/wargio/naxsi/issues/new) + +# Vulnerability disclosure + +When disclosing vulnerabilities, please send first an email to `deroad at kumo.xn--q9jyb4c` (gpg keyid: `29656E856786B9A1FBF983CFA219F52A8217B1FE`) + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- +mDMEXR3FZhYJKwYBBAHaRw8BAQdAfuSDE68TEppjJfUAApXSTsHrKtGefVJXvz7f +YIO0gci0MUdpb3Zhbm5pIERhbnRlIEdyYXppb2xpIDxkZXJvYWRAa3Vtby54bi0t +cTlqeWI0Yz6IkAQTFggAOAIbAwULCQgHAgYVCgkICwIEFgIDAQIeAQIXgBYhBCll +boVnhrmh+/mDz6IZ9SqCF7H+BQJg9+CGAAoJEKIZ9SqCF7H+X04BAPXz7R856z72 +f8nsZZjj4q3YaJbXA3pSVLIJ9uDQniCsAP9PaPBcbr231M3cjjBMo7ovlrElfFor +zCWA3NhRb4Y2DLg4BF0dxWYSCisGAQQBl1UBBQEBB0AVby+EIQcIoqSDZelvkqt8 +dV1kvF4f/J0jj0k3OEKNcAMBCAeIeAQYFggAIAIbDBYhBCllboVnhrmh+/mDz6IZ +9SqCF7H+BQJg9+C4AAoJEKIZ9SqCF7H+ZfQBAOFb7iZm7t8j5ymiXyJFcuM/nF9+ +bx4+KJJUTR9r6zBFAQD3Ea5Ya4lny/v9WKNSpBfZFEs3pkDnfgxw3o8vc4iSAQ== +=d/IR +-----END PGP PUBLIC KEY BLOCK----- +``` + +# **Deprecated Documentation** + +The deprecated/old documentation is accessible [here](old/index.md). diff --git a/dependencies/naxsi/docs/internal_rules.md b/dependencies/naxsi/docs/internal_rules.md new file mode 100644 index 0000000..f19f142 --- /dev/null +++ b/dependencies/naxsi/docs/internal_rules.md @@ -0,0 +1,178 @@ +# **Internal Rules** + +Naxsi has some internal rules that are hardcoded within the WAF; these rules are defined by **ids** lower than **1000**. + +> 📣 Important +> +> The internal blocking rules can be whitelisted. + +> ⚠️ Warning +> +> No rules shall be defined with **ids** lower than 1000. + +## Internal Rule 1 - Weird Request + +> ❌ **Deprecated** +> +> Number: **1** +> Name: **Weird Request** +> Action: **BLOCK** + +The internal rule `1` refers to any request that contains weird request which failed to be parsed by Naxsi. + +## Internal Rule 2 - Big Request + +> ℹ️ Info +> +> Number: **2** +> Name: **Big Request** +> Action: **BLOCK** + +The internal rule `2` refers to any request that is too big to be parsed; this only happens when NGINX has to create a temporary file on the filesystem or when the content-size mismatch with the actual body size. + +## Internal Rule 10 - Hex Encoded Null-Bytes + +> ℹ️ Info +> +> Number: **10** +> Name: **Null-Byte Hex Encoding** +> Action: **BLOCK** + +The internal rule `10` refers to any request that contains one or many hex encoded null-bytes (i.e. `0x00` or `\x00`). + +## Internal Rule 11 - Uncommon Content Type + +> ℹ️ Info +> +> Number: **11** +> Name: **Uncommon Content Type** +> Action: **BLOCK** + +The internal rule `11` refers to any request that contains uncommon content type; this happens when `Content-Type` header is missing or during a POST request, the `Content-Type` is not one of the followings: + +- `"application/x-www-form-urlencoded"` +- `"multipart/form-data"` +- `"application/json"` +- `"application/vnd.api+json"` +- `"application/csp-report"` + +## Internal Rule 12 - Invalid formatted URL + +> ℹ️ Info +> +> Number: **12** +> Name: **Invalid formatted URL** +> Action: **BLOCK** + +The internal rule `12` refers to any request that contains a badly formatted URL; this happens when the HTTP request has an invalid URL (this may be caught before-hand by NGINX which may return 400). + +## Internal Rule 13 - Malformed POST Format + +> ℹ️ Info +> +> Number: **13** +> Name: **Malformed POST Format** +> Action: **BLOCK** + +The internal rule `13` refers to any request that contains a malformed POST, for example missing `content-disposition`, malformed boundary line, missing name, missing `Content-Type`, etc... + +## Internal Rule 14 - Malformed POST Boundary + +> ℹ️ Info +> +> Number: **14** +> Name: **Malformed POST Boundary** +> Action: **BLOCK** + +The internal rule `14` refers to any request that contains a malformed POST boundary. + +## Internal Rule 15 - Malformed JSON + +> ℹ️ Info +> +> Number: **15** +> Name: **Malformed JSON** +> Action: **BLOCK** + +The internal rule `15` refers to any request that contains malformed JSON. + +## Internal Rule 16 - Empty POST Body + +> ℹ️ Info +> +> Number: **16** +> Name: **Empty POST Body** +> Action: **BLOCK** + +The internal rule `16` refers to any request that contains empty POST body. + +## Internal Rule 17 - libinjection SQLi + +> ℹ️ Info +> +> Number: **17** +> Name: **libinjection SQLi** +> Score: **$LIBINJECTION_SQL** + +> ⚠️ Warning +> +> This rule does not block a request, but increases the score `$LIBINJECTION_SQL` by **1**. + +The internal rule `17` refers to any request that contains sql injections detected by libinjection. + +See also [Directive `LibInjectionSql`](directives.md#libinjectionsql) for more details. + +## Internal Rule 18 - libinjection XSS + +> ℹ️ Info +> +> Number: **18** +> Name: **libinjection Xss** +> Score: **$LIBINJECTION_XSS** + +> ⚠️ Warning +> +> This rule does not block a request, but increases the score `$LIBINJECTION_XSS` by **1**. + +The internal rule `18` refers to any request that contains XSS injections detected by libinjection. + +See also [Directive `LibInjectionXss`](directives.md#libinjectionxss) for more details. + +## Internal Rule 19 - No Rules Loaded + +> ℹ️ Info +> +> Number: **19** +> Name: **No Rules** +> Action: **DROP** + +The internal rule `19` is triggered only when the WAF is enabled but no global and no location-specific rules has been loaded at the current location. + +## Internal Rule 20 - Malformed UTF-8 + +> ℹ️ Info +> +> Number: **20** +> Name: **Malformed UTF-8** +> Action: **DROP** + +The internal rule `20` refers to any request that contains malformed UTF-8. + +## Internal Rule 21 - Illegal Host in Header + +> ℹ️ Info +> +> Number: **21** +> Name: **Illegal Host in Header** +> Action: **DROP** + +The internal rule `21` refers to any request that contains a host header with an illegal ip: + +- `0.0.0.0/8` +- `255.255.255.255/32` +- `0000:0000:0000:0000:0000:0000:0000:0000/128` +- `ff00:0000:0000:0000:0000:0000:0000:0000/8` + +# Go Back + +[Rules](rules.md). diff --git a/dependencies/naxsi/docs/logs.md b/dependencies/naxsi/docs/logs.md new file mode 100644 index 0000000..30fc8a9 --- /dev/null +++ b/dependencies/naxsi/docs/logs.md @@ -0,0 +1,116 @@ +# **Naxsi Logs** + +Naxsi utilizes NGINX's `error_log` feature to produce logs; specifically, it offers two types of error logs that can be generated: one in **URL-encoded format** (which is the default option) and another in **JSON format**. + +These logs are `action log` and `extended log`. They include detailed information about the triggered rules, content identified, paths and request IDs for comprehensive security monitoring and analysis. + +> ⚠️ Warning +> +> Due to hardcoded limitations of NGINX (see `NGX_MAX_ERROR_STR` defined by `ngx_log.h` in the NGINX source code), these logs may be truncated if too long. +> +> It is strongly recommanded to increase the line limit to `8192` or higher by patching NGINX itself. +> +> Example of patch: `sed -i 's#NGX_MAX_ERROR_STR 2048#NGX_MAX_ERROR_STR 8192#g' src/core/ngx_log.h` + +## Action Logs + +Action logs contains the following information: + +- `ip`: Client IP +- `server`: Nginx server name +- `uri`: Request URI +- `config`: Configuration of naxsi for the applied rule, this can be one of the following values: + - `learning` [Learning Mode active](directives.md#learningmode), i.e. The [action taken is `LOG`](directives.md#checkrule) and the **request was NOT dropped**. + - `learning-drop` [Learning Mode active](directives.md#learningmode) but request was dropped, i.e. [The action taken is `DROP`](directives.md#checkrule). + - `drop` The request was dropped, i.e. [The action taken is `DROP`](directives.md#checkrule). + - `block` The request was dropped, i.e. [The action taken is `BLOCK`](directives.md#checkrule). + - `ignore` The request was supposed to be dropped/blocked, but it was ignored due to matching [`IgnoreIP`](directives.md#ignoreip) or [`IgnoreCIDR`](directives.md#ignorecidr), i.e. [The action taken is `LOG`](directives.md#checkrule). +- `rid`: Request Identifier (matches the `request_id` NGINX value). +- `id`: Matched rule identifier +- `cscore`: Request score name (see [Check Rules](directives.md#checkrule)), for example `$SQL`. +- `score`: Request score value (see [Check Rules](directives.md#checkrule)), for example `8`. +- `zone`: Request [matchzone](matchzones.md), for example `URL`. +- `var_name`: Request variable name where the match has happen, for example `foo_bar[]`. + +> ℹ️ Info +> +> The `` is a counter that always starts from `0` for each request and is used for listing all the matched rules and their info (`id`, `cscore`, etc..). +> +> For example, a request can have multiple matching rules and these will be logged by Naxsi as follows: +> +> The first rule (`=0`) is logged as `id0=`, `cscore0=`, `score0=`, `zone0=`, `var_name0=`; the second rule (`=1`) is going to be `id1=`, `cscore1=`, `score1=`, `zone1=`, `var_name1=`, the third (`=2`), etc... +> +> If the rule score name is the same for multiple rules, the first `cscoreX` defined in the logs will contain the sum of the total score of multiple rules. + +## Extended Logs + +Extended logs needs to be enabled by adding `set $naxsi_extensive_log 1;` or via the runtime modifier `naxsi_extensive_log` to the NGINX configuration and logs all the matches of a request: + +- `ip`: Client IP +- `server`: Nginx server name +- `rid`: Request Identifier (matches the `request_id` NGINX value). +- `uri`: Request URI +- `id`: Matched rule identifier +- `zone`: Request [matchzone](matchzones.md), for example `URL`. +- `var_name`: Request variable name where the match has happen, for example `foo_bar[]`. +- `content`: The matched content, for example `malicious` (can be truncated if too long). + + +*Action format logs* can be distinguished by *extended logs* the presence of `cscore` & `score` keywords; *Extended logs* are also the only ones having the `content` keyword. + +## URL Encoded logs + +**This is the default logging format for Naxsi**; These logs are always preceded by `NAXSI_FMT` (action logs) or `NAXSI_EXLOG` (extended logs) and the values of each logged info is `url-encoded`. + +Example: + +``` +2024/12/26 12:27:44 [error] 3829059#0: *4 NAXSI_EXLOG: ip=127.0.0.1&server=localhost&rid=70d8cd8818e7e27a11d14df63c676227&uri=%2Fx%2Cy&id=1015&zone=URL&var_name=&content=%2Fx%2Cy, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost" +2024/12/26 12:27:44 [error] 3829059#0: *4 NAXSI_EXLOG: ip=127.0.0.1&server=localhost&rid=70d8cd8818e7e27a11d14df63c676227&uri=%2Fx%2Cy&id=1015&zone=ARGS&var_name=uuu&content=b%2Cc, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost" +2024/12/26 12:27:44 [error] 3829059#0: *4 NAXSI_FMT: ip=127.0.0.1&server=localhost&uri=%2Fx%2Cy&config=learning&rid=70d8cd8818e7e27a11d14df63c676227&cscore0=$SQL&score0=8&zone0=URL&id0=1015&var_name0=&zone1=ARGS&id1=1015&var_name1=uuu, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost" +``` + +## JSON logs + +This logs format needs to be enabled via `set $naxsi_json_log 1;` or via the runtime modifier `naxsi_json_log`. + +*Action logs* can be distinguished by *extended logs* the presence of `cscore` & `score` keywords; *Extended logs* are also the only ones having the `content` keyword. + +``` +2024/12/26 12:28:37 [error] 3829158#0: *4 {"ip":"127.0.0.1","server":"localhost","rid":"1d27ac3c0b10bbb8783d109213f3f4cd","uri":"/x,y","id":1015,"zone":"URL","var_name":"","content":"/x,y"}, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost" +2024/12/26 12:28:37 [error] 3829158#0: *4 {"ip":"127.0.0.1","server":"localhost","rid":"1d27ac3c0b10bbb8783d109213f3f4cd","uri":"/x,y","id":1015,"zone":"ARGS","var_name":"uuu","content":"b,c"}, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost" +2024/12/26 12:28:37 [error] 3829158#0: *4 {"ip":"127.0.0.1","server":"localhost","uri":"/x,y","config":"block","rid":"1d27ac3c0b10bbb8783d109213f3f4cd","cscore0":"$SQL","score0":8,"zone0":"URL","id0":1015,"var_name0":"","zone1":"ARGS","id1":1015,"var_name1":"uuu"}, client: 127.0.0.1, server: localhost, request: "GET /x,y?uuu=b,c HTTP/1.1", host: "localhost" +``` + +Here is an example of how the previous JSON logs appears when formatted by utilities such as `jq`: + +```json +// Action Log +{ + "ip": "127.0.0.1", + "server": "localhost", + "uri": "/x,y", + "config": "block", + "rid": "1d27ac3c0b10bbb8783d109213f3f4cd", + "cscore0": "$SQL", + "score0": 8, + "zone0": "URL", + "id0": 1015, + "var_name0": "", + "zone1": "ARGS", + "id1": 1015, + "var_name1": "uuu" +} + +// Extended Log +{ + "ip": "127.0.0.1", + "server": "localhost", + "rid": "1d27ac3c0b10bbb8783d109213f3f4cd", + "uri": "/x,y", + "id": 1015, + "zone": "URL", + "var_name": "", + "content": "/x,y" +} +``` \ No newline at end of file diff --git a/dependencies/naxsi/docs/matchzones.md b/dependencies/naxsi/docs/matchzones.md new file mode 100644 index 0000000..7383565 --- /dev/null +++ b/dependencies/naxsi/docs/matchzones.md @@ -0,0 +1,222 @@ +# **Naxsi Matchzones** + +**Matchzones**, denoted by the prefix `mz:`, are crucial components of **rules** and **whitelists**. They act like filters to define specific locations where a pattern should be searched or allowed. + +Here's how they function differently based on the context: + +- **Rules:** In this case, matchzones work with an **OR** logic (like `BODY` OR `HEADERS`). This means that as long as one of the specified conditions is met, the rule triggers. + +- **Whitelists:** Here, matchzones operate under an **AND** logic (like `url` must be `/foo` AND must occur in `ARGS`). It requires that *both conditions* within a whitelist be satisfied before the pattern is allowed. + +> 📣 Important +> +> Naxsi decodes any `url-encoded` or `hexadecimal` sequence, this means the string or regex to search for must be of the decoded content (**this applies also to URLs**). +> +> Example: `1%20UnioN%20SeLEct%201` becomes `1 UnioN SeLEct 1` before applying rules. + +## Any Matchzone + +This special matchzone designated by `ANY` allows to define **rules and whitelists which matches in any area of a request**. + +For instance, the rule `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:ANY";` is equivalent of writing the following rules but in one line. + +``` +MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:ARGS|HEADERS|BODY|URL"; +MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:RAW_BODY"; +MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:FILE_EXT"; +``` + +> 📣 Important +> +> This can be used also for whitelists, but it is possible to disable a rule by just not declaring any matchzone (see the [Whitelist matchzones notes](whitelist.md#matchzone)). + +## Filter by HTTP Headers + +HTTP headers let the client and the server pass additional information with a message in a request or response; Naxsi allows to filter rules and whitelists by headers as follows: + +### Filter by Any HTTP header value + +This Matchzone designated by `HEADERS` is specifically tailored to identify **only the content found within HTTP headers**. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:HEADERS";` detects the occurrence of the string `malicious` exclusively within the HTTP headers values transmitted in a request. +- A whitelist entry like `BasicRule wl:12345 "mz:HEADERS";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP header values. + +### Filter by Any HTTP header name + +This Matchzone designated by `HEADERS|NAME` is specifically tailored to identify **only the name of the header found within HTTP request**. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8" "str:x-forward-to" "mz:HEADERS|NAME";` detects the occurrence of the string `X-Forward-To` exclusively within the HTTP headers names transmitted in a request. +- A whitelist entry like `BasicRule wl:12345 "mz:HEADERS|NAME";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP header name. + +### Filter by HTTP header name + +This Matchzone designated by `$HEADERS_VAR:foo` and `$HEADERS_VAR_X:^foo$` is specifically tailored to identify **only the content found within an HTTP header named `foo`**. + +- `$HEADERS_VAR:` can be used to filter by header name (**case-insensitive**) via a string. +- `$HEADERS_VAR_X:` can be used to filter by header name (**case-insensitive**) via a regex. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:curl" "mz:$HEADERS_VAR:user-agent|$HEADERS_VAR:cookie";` detects the occurrence of the string `curl` exclusively within the value of the HTTP headers `User-Agent` and `Cookie` (**case-insensitive**). +- A whitelist entry like `BasicRule wl:12345 "mz:$HEADERS_VAR_X:^cookie$";` negates the match of any rule with id `12345` if the match occurs within the value of the HTTP header `Cookie` via regex. + +> 📣 Important +> +> This can be mixed with `|NAME` to perform the filtering at argument name instead of value. +> Example: `mz:$HEADERS_VAR_X:^foo\d+$|NAME` matches only the HTTP header named `foo`. + +## Filter by GET query + +HTTP GET requests can carry information, referred as queries, in the form of key=value pairs; Naxsi allows to filter rules and whitelists by these arguments as follows: + +### Filter by Any GET query value + +This Matchzone designated by `ARGS` is specifically tailored to identify **only the value found within HTTP GET query**. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:ARGS";` detects the occurrence of the string `malicious` exclusively within the HTTP GET queries values transmitted in a request. +- A whitelist entry like `BasicRule wl:12345 "mz:ARGS";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP GET queries values. + +### Filter by Any GET query name + +This Matchzone designated by `ARGS|NAME` is specifically tailored to identify **only the name of the GET query found within HTTP request**. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8" "str:delete_action" "mz:ARGS|NAME";` detects the occurrence of the string `delete_action` exclusively within the HTTP GET queries names transmitted in a request. +- A whitelist entry like `BasicRule wl:12345 "mz:ARGS|NAME";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP GET queries names. + +### Filter by GET query value or name + +This Matchzone designated by `$ARGS_VAR:foo` and `$ARGS_VAR_X:^foo$` is specifically tailored to identify **only the content found within an HTTP GET query named `foo`**. + +- `$ARGS_VAR:` can be used to filter by argument name (**case-insensitive**) via a string. +- `$ARGS_VAR_X:` can be used to filter by argument name (**case-insensitive**) via a regex. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:evil" "mz:$ARGS_VAR:foo|$ARGS_VAR:bar";` detects the occurrence of the string `evil` exclusively within the value of the GET queries `User-Agent` (**case-insensitive**). +- A whitelist entry like `BasicRule wl:12345 "mz:$ARGS_VAR_X:^cookie$";` negates the match of any rule with id `12345` if the match occurs within the value of the HTTP header `Cookie` via regex. + +> 📣 Important +> +> This can be mixed with `|NAME` to perform the filtering at argument name instead of value. +> Example: `mz:$ARGS_VAR_X:^foo\d+$|NAME` matches only the GET query named `foo`. + +## Filter by POST Requests + +HTTP POST requests carries information in the HTTP body; the request data can have multiple formats: + +- `application/x-www-form-urlencoded` contains key=value pairs. +- `multipart/form-data` contains boundaries with the raw data. + +Naxsi allows to filter these in rules and whitelists as follows: + +### Filter by Any `application/x-www-form-urlencoded` Value + +This Matchzone designated by `BODY` is specifically tailored to identify **only the value found within HTTP POST body**. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:BODY";` detects the occurrence of the string `malicious` exclusively within the HTTP POST body values (key=value format) transmitted in a request. +- A whitelist entry like `BasicRule wl:12345 "mz:BODY";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP POST body values. + +### Filter by Any `application/x-www-form-urlencoded` Key + +This Matchzone designated by `BODY|NAME` is specifically tailored to identify **only the name of the header found within HTTP request**. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8" "str:delete_action" "mz:BODY|NAME";` detects the occurrence of the string `delete_action` exclusively within the HTTP POST arguments names transmitted in a request. +- A whitelist entry like `BasicRule wl:12345 "mz:BODY|NAME";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP POST arguments names. + +### Filter by Any `application/x-www-form-urlencoded` Key and Value + +This Matchzone designated by `$BODY_VAR:foo` and `$BODY_VAR_X:^foo$` is specifically tailored to identify **only the content found within an HTTP POST body named `foo`**. + +- `$BODY_VAR:` can be used to filter by POST form name (**case-insensitive**) via a string. +- `$BODY_VAR_X:` can be used to filter by POST form name (**case-insensitive**) via a regex. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:malicious" "mz:$BODY_VAR:foo|$BODY_VAR:bar";` detects the occurrence of the string `malicious` exclusively within the value of the POST form keys `foo` and `body` (**case-insensitive**). +- A whitelist entry like `BasicRule wl:12345 "mz:$BODY_VAR_X:^foo$";` negates the match of any rule with id `12345` if the match occurs within the value of the POST form named `foo` via regex. + +> 📣 Important +> +> This can be mixed with `|NAME` to perform the filtering at argument name instead of value. +> Example: `mz:$BODY_VAR_X:^foo\d+$|NAME` matches only the POST argument named `foo`. + +### Filter by Any `multipart/form-data` filename + +This Matchzone designated by `FILE_EXT` is specifically tailored to match **only the filename found within HTTP multipart POST request**. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:.php" "mz:FILE_EXT";` detects the occurrence of the string `.php` exclusively within the filename of the HTTP multipart POST request. +- A whitelist entry like `BasicRule wl:12345 "mz:FILE_EXT";` negates the match of any rule with id `12345` if the match itself occurs in the filename of the HTTP multipart POST request. + +## Filter by HTTP Raw Body + +This Matchzone designated by `RAW_BODY` is specifically tailored to match **any byte sequence in an unparsed HTTP body**. + +For instance: + +- A rule such as `BasicRule id:12345 "s:$EXECUTABLE:8" "rx:MZ\x90" "mz:RAW_BODY";` detects the occurrence of a byte sequence (Windows PE magic) within the HTTP body of the request. +- A whitelist entry like `BasicRule wl:12345 "mz:RAW_BODY";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP body of the request. + +> 📣 Important +> +> This matchzone is internally converted as `BODY` zone, thus the `BasicRule wl:12345 "mz:BODY";` and `BasicRule wl:12345 "mz:RAW_BODY";` are equivalent. + +## Filter by HTTP URL + +Naxsi supports filtering by HTTP URL as follows: + +### Filter by HTTP URL (global) + +This Matchzone designated by `URL` is specifically tailored to identify **only the value found within HTTP URL**. + +For instance: + +- A rule such as `MainRule id:12345 "s:$FOO:8,$BAR:4" "str:/admin" "mz:URL";` detects the occurrence of the string `/admin` exclusively within the HTTP URL transmitted in a request. +- A whitelist entry like `BasicRule wl:12345 "mz:URL";` negates the match of any rule with id `12345` if the match itself occurs in the HTTP URL. + +> 📣 Important +> +> This matchzone is globally applied, it is possible to restrict the matchzone to a specific URL or substring in the URL via `$URL` or `$URL_X` (see below). + +### Filter by HTTP URL (restricted) + +This Matchzone designated by `$URL:/foo` and `$URL_X:^/foo$` is specifically tailored to identify **only the URL containing the string `/foo`**. + +- `$URL:` can be used to filter by string (**case-insensitive**). +- `$URL_X:` can be used to filter by regex (**case-insensitive**). + +These can be mixed with all the previous matchzones as follows: + +In rules context, `$URL` or `$URL_X` *must* be satisfied if present. Any other condition is treated as *OR* (opposite to whitelists). + +- The rule `BasicRule str:Y id:X "mz:ARGS|BODY";` is interpreted as _pattern 'Y' will be matched against *any* GET and POST arguements_ +- The rule `BasicRule str:Y id:X "mz:ARGS|BODY|$URL:/foo";` is interpreted as _pattern 'Y' will be matched against *any* GET and POST arguements as long as URL is `/foo`_ + +In whitelist context, *all* conditions must be satisfied, so a whitelist like `BasicRule wl:X "mz:$ARGS_VAR:foo|$URL:/bar";` is interpreted as _id X is whitelisted in GET variable `foo` on URL `/bar`_ + +> ⚠️ Warning +> +> **You CANNOT mix `$URL_X:` and `$ARGS_VAR:`, `$BODY_VAR:` and `$HEADERS_VAR:` in a rule or whitelist.** +> +> It is allowed instead to mix `$URL_X:` with `$ARGS_VAR_X:`, `$BODY_VAR_X:` and `$HEADERS_VAR_X:` and to mix `$URL:` with `$ARGS_VAR:`, `$BODY_VAR:` and `$HEADERS_VAR:`. + +> ℹ️ Info +> +> It is allowed to mix `FILE_EXT` and `RAW_BODY` with `$URL_X:` and `$URL:`. + +# Go Back + +[Table of Contents](index.md). diff --git a/dependencies/naxsi/docs/old/Contributing.md b/dependencies/naxsi/docs/old/Contributing.md new file mode 100644 index 0000000..28c8f5e --- /dev/null +++ b/dependencies/naxsi/docs/old/Contributing.md @@ -0,0 +1,18 @@ +## Contributing to naxsi + +We're happily taking patches, contributions, improvements, please see below : + +### Naxsi Core Requirements (runtime) + + * Unit tests with a decent (>90%) coverage + * Peer review by core devs in terms of quality/security impacts + * For all runtime code, please fuzz the code (see `fuzz` Makefile's target) + * For all runtime code, merge will require that we get clean static analysis results (coverity) + +### NxTool/NxAPI + + * Peer review by other developers + * General interest for the feature + +Thanks in advance ! + diff --git a/dependencies/naxsi/docs/old/IgnoreIP-and-IgnoreCIDR.md b/dependencies/naxsi/docs/old/IgnoreIP-and-IgnoreCIDR.md new file mode 100644 index 0000000..44ee3dd --- /dev/null +++ b/dependencies/naxsi/docs/old/IgnoreIP-and-IgnoreCIDR.md @@ -0,0 +1,22 @@ +You can list which IP or CIDR (i.e 192.168.0.1/24), should be always allowed and never blocked. + +IP is taken from `X-Forwarder-for` header (when available or from the client IP). + +Your load balancer, some proxy could add it already, but if not you can add it with `proxy_set_header X-Forwarded-For $remote_addr;` + +Usage: + +``` +location / { + SecRulesEnabled; + IgnoreIP "1.2.3.4"; + IgnoreCIDR "192.168.0.0/24"; + DeniedUrl "/RequestDenied"; + CheckRule "$SQL >= 8" BLOCK; + CheckRule "$RFI >= 8" BLOCK; + CheckRule "$TRAVERSAL >= 4" BLOCK; + CheckRule "$XSS >= 8" BLOCK; + root /var/www/html/; + index index.html index.htm; +} +``` \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/Images/Cachegrind_callgraph_full_denied.png b/dependencies/naxsi/docs/old/Images/Cachegrind_callgraph_full_denied.png new file mode 100644 index 0000000..5a10198 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/Cachegrind_callgraph_full_denied.png differ diff --git a/dependencies/naxsi/docs/old/Images/Cachegrind_callgraph_naxsi_disabled.png b/dependencies/naxsi/docs/old/Images/Cachegrind_callgraph_naxsi_disabled.png new file mode 100644 index 0000000..adec965 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/Cachegrind_callgraph_naxsi_disabled.png differ diff --git a/dependencies/naxsi/docs/old/Images/Cachegrind_callgraph_no_block.png b/dependencies/naxsi/docs/old/Images/Cachegrind_callgraph_no_block.png new file mode 100644 index 0000000..6279dd3 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/Cachegrind_callgraph_no_block.png differ diff --git a/dependencies/naxsi/docs/old/Images/Railroad-Diagram-Generator.png b/dependencies/naxsi/docs/old/Images/Railroad-Diagram-Generator.png new file mode 100644 index 0000000..c282e3d Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/Railroad-Diagram-Generator.png differ diff --git a/dependencies/naxsi/docs/old/Images/Whitelist.png b/dependencies/naxsi/docs/old/Images/Whitelist.png new file mode 100644 index 0000000..09fffb3 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/Whitelist.png differ diff --git a/dependencies/naxsi/docs/old/Images/appscandetails1.png b/dependencies/naxsi/docs/old/Images/appscandetails1.png new file mode 100644 index 0000000..e9fdd1c Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/appscandetails1.png differ diff --git a/dependencies/naxsi/docs/old/Images/appscandetails2.png b/dependencies/naxsi/docs/old/Images/appscandetails2.png new file mode 100644 index 0000000..4ca980c Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/appscandetails2.png differ diff --git a/dependencies/naxsi/docs/old/Images/appscandetails3.png b/dependencies/naxsi/docs/old/Images/appscandetails3.png new file mode 100644 index 0000000..d420ba4 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/appscandetails3.png differ diff --git a/dependencies/naxsi/docs/old/Images/appscanfull.png b/dependencies/naxsi/docs/old/Images/appscanfull.png new file mode 100644 index 0000000..47a71ae Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/appscanfull.png differ diff --git a/dependencies/naxsi/docs/old/Images/checkrule.png b/dependencies/naxsi/docs/old/Images/checkrule.png new file mode 100644 index 0000000..4cc6e81 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/checkrule.png differ diff --git a/dependencies/naxsi/docs/old/Images/keyword.png b/dependencies/naxsi/docs/old/Images/keyword.png new file mode 100644 index 0000000..970e8b5 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/keyword.png differ diff --git a/dependencies/naxsi/docs/old/Images/kibana.png b/dependencies/naxsi/docs/old/Images/kibana.png new file mode 100644 index 0000000..faaa322 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/kibana.png differ diff --git a/dependencies/naxsi/docs/old/Images/msg.png b/dependencies/naxsi/docs/old/Images/msg.png new file mode 100644 index 0000000..13baa7a Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/msg.png differ diff --git a/dependencies/naxsi/docs/old/Images/mz.png b/dependencies/naxsi/docs/old/Images/mz.png new file mode 100644 index 0000000..cc7bd24 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/mz.png differ diff --git a/dependencies/naxsi/docs/old/Images/mz_rx.png b/dependencies/naxsi/docs/old/Images/mz_rx.png new file mode 100644 index 0000000..2e262cd Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/mz_rx.png differ diff --git a/dependencies/naxsi/docs/old/Images/mz_str.png b/dependencies/naxsi/docs/old/Images/mz_str.png new file mode 100644 index 0000000..eaecbba Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/mz_str.png differ diff --git a/dependencies/naxsi/docs/old/Images/naxsi-workflow.png b/dependencies/naxsi/docs/old/Images/naxsi-workflow.png new file mode 100644 index 0000000..766971a Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/naxsi-workflow.png differ diff --git a/dependencies/naxsi/docs/old/Images/naxsi-workflow.svg b/dependencies/naxsi/docs/old/Images/naxsi-workflow.svg new file mode 100755 index 0000000..81f3870 --- /dev/null +++ b/dependencies/naxsi/docs/old/Images/naxsi-workflow.svg @@ -0,0 +1,4 @@ + + + + diff --git a/dependencies/naxsi/docs/old/Images/pattern.png b/dependencies/naxsi/docs/old/Images/pattern.png new file mode 100644 index 0000000..a5772d1 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/pattern.png differ diff --git a/dependencies/naxsi/docs/old/Images/rule.png b/dependencies/naxsi/docs/old/Images/rule.png new file mode 100644 index 0000000..34cc18b Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/rule.png differ diff --git a/dependencies/naxsi/docs/old/Images/score.png b/dependencies/naxsi/docs/old/Images/score.png new file mode 100644 index 0000000..0f40172 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/score.png differ diff --git a/dependencies/naxsi/docs/old/Images/whitelist.png b/dependencies/naxsi/docs/old/Images/whitelist.png new file mode 100644 index 0000000..6e9ca7c Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/whitelist.png differ diff --git a/dependencies/naxsi/docs/old/Images/wl.png b/dependencies/naxsi/docs/old/Images/wl.png new file mode 100644 index 0000000..3c81618 Binary files /dev/null and b/dependencies/naxsi/docs/old/Images/wl.png differ diff --git a/dependencies/naxsi/docs/old/checkrules-bnf.md b/dependencies/naxsi/docs/old/checkrules-bnf.md new file mode 100644 index 0000000..ae6fe98 --- /dev/null +++ b/dependencies/naxsi/docs/old/checkrules-bnf.md @@ -0,0 +1,31 @@ +# Checkrules + +CheckRules instruct naxsi to take an action (`LOG`, `BLOCK`, `DROP`, `ALLOW`) based on a specific score associated to the request. This _score_ has usually been set by one or several [rule(s)](rules-bnf.md). + +`CheckRule` must be present at location level. + +![CheckRule schema](Images/checkrule.png) + +### Basic Usage + +A typical `CheckRule` is : + +``` +CheckRule "$SQL >= 8" BLOCK; +``` + +If the `$SQL` is equal or superior to '8', apply BLOCK flag to the request. Request will only be blocked if location is _not_ in learning mode. + +### Other Usages + +`CheckRule(s)` can as well be used to mix white and black-lists. +Having a configuration mixing virtual-patching (see [rules](rules-bnf.md)) and `naxsi_core.rules`, it is possible to have : + +``` +CheckRule "$UWA >= 4" DROP; +CheckRule "$XSS >= 8" BLOCK; +``` + +Thus - even in learning mode - any request with `$UWA` score equal to 4 will block the requests, while requests with `$XSS` score (even superior to 8) will only be blocked on location(s) *not* in learning. + + diff --git a/dependencies/naxsi/docs/old/directives.md b/dependencies/naxsi/docs/old/directives.md new file mode 100644 index 0000000..789aa90 --- /dev/null +++ b/dependencies/naxsi/docs/old/directives.md @@ -0,0 +1,177 @@ +# Directives + +## DeniedUrl + * alias: denied_url + * context: location + +`DeniedUrl` is a directive that indicates where naxsi will redirect (nginx's internal redirect) blocked requests. + +As the request might be modified during redirect (url & arguments), extra http headers orig_url (original url), +orig_args (original GET args) and naxsi_sig (NAXSI_FMT) are added. + +The headers that are forwarded to the location denied page are : + +NAXSI_HEADER_ORIG_URL "x-orig_url" +NAXSI_HEADER_ORIG_ARGS "x-orig_args" +NAXSI_HEADER_NAXSI_SIG "x-naxsi_sig" + +example: +``` +location / { +... +DeniedUrl "/RequestDenied"; +} + +location /RequestDenied { +return 418; #I'm a teapot +} +``` + +## LearningMode + * alias: learning_mode + * context: location + +`LearningMode` if instructs naxsi to enable learning mode (don't honor `BLOCK` directive) in the location. + +For example: + +```nginx +location /a { +# request triggering BLOCK score won't be blocked here, but simply logued. +LearningMode; +} +``` + +Keep in mind that internal rules (those with an `id` inferior to 1000) will drop the request even in learning mode, because it means that something fishy is going on, since naxsi can't correctly process the request. +You can of course apply [whitelist](whitelists-bnf.md) if those are false-positives. + +## SecRulesEnabled + * alias: rules_enabled + * context: location + +`SecRulesEnabled` is a mandatory keyword to enable naxsi in a location. + +## SecRulesDisabled + * alias: rules_disabled + * context: location + +`SecRulesDisabled` can be used to explicitely disable naxsi in a location. + +## CheckRule + * alias: check_rule + * context: location + +See [CheckRule](checkrules-bnf.md) + +## BasicRule + * alias: basic_rule + * context: location + +A directive used to declare a [rule](rules-bnf.md) or a [whitelist](whitelist-bnf.md). + +## MainRule + * alias: main_rule + * context: http + +A directive used to declare a [rule](rule-bnf.md) or a [whitelist](whitelist-bnf.md). + +## LibInjectionXss + * alias: libinjection_xss + * context: location + +A directive to enable [libinjection's xss detection](libinjection-integration.md) on *all* part of the http request. + +## LibInjectionSql + * alias: libinjection_sql + * context: location + +A directive to enable [libinjection's sqli detection](libinjection-integration.md) on *all* part of the http request. + +## naxsi_extensive_log + * context: server + +A flag that can be set at [runtime](runtime-modifiers.md) to enable [naxsi extensive logs](naxsilogs.md#naxsi_exlog). + +``` +server { +... + + if ($remote_addr = "1.2.3.4") { + set $naxsi_extensive_log 1; + } + +location / { + ... + } +} +``` + +## naxsi_json_log + * context: server + +Enable JSON in logs. Examples: + +``` +# normal log in JSON format +2022/12/22 20:36:35 [error] 1189262#0: *1 {"ip":"127.0.0.1","server":"localhost","uri":"/a","config":"block","rid":"a0333f697ff8f12b6a200a24117ff320","cscore0":"$SQL","score0":"8","cscore1":"$XSS","score1":"8","zone0":"ARGS","id0":"1001","var_name0":"b"}, client: 127.0.0.1, server: localhost, request: "GET /a?b="\dasdasdasdadsa HTTP/1.1", host: "localhost" +# extended log in json format +2022/12/22 20:36:35 [error] 1189262#0: *1 {"ip":"127.0.0.1","server":"localhost","uri":"/a","config":"block","rid":"a0333f697ff8f12b6a200a24117ff320","cscore0":"$SQL","score0":"8","cscore1":"$XSS","score1":"8","zone0":"ARGS","id0":"1001","var_name0":"b"}, client: 127.0.0.1, server: localhost, request: "GET /a?b="\dasdasdasdadsa HTTP/1.1", host: "localhost" +``` + +TODO DOCUMENTATION + +## naxsi_flag_enable + * context: server + +A flag that can be set at [runtime](runtime-modifiers.md) to enable or disable naxsi. + +``` +server { + set $naxsi_flag_enable 1; + location / { + ... + } +} +``` + +## naxsi_flag_learning + * context: server + +A flag that can be set at [runtime](runtime-modifiers.md) to enable or disable learning. + +``` +server { + set $naxsi_flag_learning 1; + location / { + ... + } +} +``` + +## naxsi_flag_libinjection_sql + * context: server + +A flag that can be set at [runtime](runtime-modifiers.md) to enable or disable [libinjection's sql detection](libinjection-integration.md) + +``` +server { + set $naxsi_flag_libinjection_sql 1; + location / { + ... + } +} +``` + +## naxsi_flag_libinjection_xss + +A flag that can be set at [runtime](runtime-modifiers.md) to enable or disable [libinjection's xss detection](libinjection-integration.md) + +``` +server { + set $naxsi_flag_libinjection_xss 1; + location / { + ... + } +} +``` + diff --git a/dependencies/naxsi/docs/old/index.md b/dependencies/naxsi/docs/old/index.md new file mode 100644 index 0000000..a4e7bef --- /dev/null +++ b/dependencies/naxsi/docs/old/index.md @@ -0,0 +1,34 @@ +1. Setup + - [compiling nginx+naxsi](naxsi-compile.md) + - [Basic nginx/naxsi configuration](naxsi-setup.md) +2. Naxsi Configuration Directives + - [whitelists](whitelists-bnf.md) + - [rules](rules-bnf.md) + - [checkrules](checkrules-bnf.md) + - [requestdenied](requestdenied-bnf.md) + - [naxsi directives index](directives.md) + - [zoom : matchzones](matchzones-bnf.md) +3. Naxsi Extras + - [Raw Body Parsing](rawbody.md) + - [libinjection integration](libinjection-integration.md) + - [json support](json.md) + - [runtime modifiers](runtime-modifiers.md) +4. Examples + - [whitelists examples](whitelists-examples.md) + - [rules examples](rules-examples.md) +5. Going deeper + - [Understanding naxsi logs](naxsilogs.md) + - [Runtime Modifiers](runtime-modifiers.md) + - [Naxsi internal rules](internal-rules.md) + - [Contributing to naxsi](Contributing.md) +6. Integration + - [Fail2Ban integration](integration-fail2ban.md) + - [AppArmor profile for naxsi](integration-apparmor.md) +8. Legacy/old pages + - [LEGACY WIKI](legacy/legacy.md) + - [Old FAQ](legacy/olds-faq.md) + - [Old Vulnerability management](olds-Security-Advisories.md) + - Old Naxsi rules mamagement + - [installing nxapi](https://github.com/nbs-system/naxsi/tree/master/nxapi.md) (**deprecated**) + - [nxapi/nxtool](https://github.com/nbs-system/naxsi/tree/master/nxapi.md) (**deprecated**) + - [spike](http://github.com/nbs-system/spike.md) (**deprecated**) diff --git a/dependencies/naxsi/docs/old/integration-apparmor.md b/dependencies/naxsi/docs/old/integration-apparmor.md new file mode 100644 index 0000000..0a9a247 --- /dev/null +++ b/dependencies/naxsi/docs/old/integration-apparmor.md @@ -0,0 +1,118 @@ +# Introduction +If you care about process access control on a [AppArmor]( http://apparmor.net ) enabled *GNU/Linux* platform, and you are using Naxsi, this article is for you. + +Of course defining a AppArmor profile is not straight forward and must be customized. AppArmor developers know that and provided tools easing the creation of application profiles. + +Of course, path to files may change depending on your local setup. + +# Requirements + +You basically need: +* A GNU/Linux platform with kernel support for AppArmor, [Ubuntu]( http://www.ubuntu.com/ ) for example +* `apt-get install apparmor-utils` +* A running Nginx/Naxsi +* A couple of minutes + +# Generating the profile + +As root, run the following command to generate a profile: + +``` +aa-genprof /usr/local/sbin/nginx +``` + +Then answer the few questions: + +``` + Connecting to repository..... + + WARNING: Error fetching profiles from the repository: + RPC::XML::Client::send_request: HTTP server error: Not Found + + Writing updated profile for /usr/local/sbin/nginx. + Setting /usr/local/sbin/nginx to complain mode. + + Please start the application to be profiled in + another window and exercise its functionality now. + + Once completed, select the "Scan" button below in + order to scan the system logs for AppArmor events. + + For each AppArmor event, you will be given the + opportunity to choose whether the access should be + allowed or denied. + + Profiling: /usr/local/sbin/nginx + + [(S)can system log for SubDomain events] / (F)inish +``` + +Now stop, start, reload, restart Nginx in order to generate apparmor logs. Then press 'S' + +``` + Reading log entries from /var/log/messages. + Updating AppArmor profiles in /etc/apparmor.d. + Complain-mode changes: + + Profile: /usr/local/sbin/nginx + Path: /etc/nginx/mime.types + Mode: owner r + Severity: unknown + + [1 - /etc/nginx/mime.types] + + [(A)llow] / (D)eny / (G)lob / Glob w/(E)xt / (N)ew / Abo(r)t / (F)inish / (O)pts +``` + +Now we are starting to profile the program and it is then really up to you to decide which file need to be accessed, with which access rights, by Nginx. + +Once done with answering those questions, a apparmor profile for `/usr/local/sbin/nginx` will be created in `/etc/apparmor.d/usr.local.sbin.nginx`. + +Here is mine: + +```apparmor + # Last Modified: Wed Jul 25 11:33:59 2012 + #include + + /usr/local/sbin/nginx { + #include + #include + #include + + capability dac_override, + capability dac_read_search, + capability setgid, + capability setuid, + + owner /etc/nginx/** r, + owner /etc/ssl/openssl.cnf r, + /var/lib/certificates/* r, + owner /var/log/nginx/* a, + /var/log/nginx/* w, + owner /var/run/nginx.pid rw, + /var/www/** r, + } +``` + +# Updating the profile for some time +Unless you precisely know what the program is doing it is a good idea to let it live for some time and gather the logs that will improve your Apparmor profile. + +So we activate the complain mode of AppArmor: + + aa-complain /etc/apparmor.d/usr.local.sbin.nginx + +And after some time (depending on your usage of Nginx): + + aa-logprof /etc/apparmor.d/usr.local.sbin.nginx + +This command will simply go through the logs and ask you about updating Nginx profile. + +# Enforcing the profile and open up Naxsi to tougher guys + + aa-enforce /etc/apparmor.d/usr.local.sbin.nginx + +Yep that's all! + +BUT! Unauthorized access caught by AppArmor in enforce mode will NOT generate you extra logs! For that you need the “audit” mode (aa-audit). Sadly the audit mode also logs authorized access so it can rapidly become unreadable (you read dmesg output all the time don't you?) + +Enjoy Naxsi and Apparmor! \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/integration-fail2ban.md b/dependencies/naxsi/docs/old/integration-fail2ban.md new file mode 100644 index 0000000..4140f92 --- /dev/null +++ b/dependencies/naxsi/docs/old/integration-fail2ban.md @@ -0,0 +1,40 @@ +### Introduction + +[Fail2ban]( http://fail2ban.org ) is a nice piece of software allowing you to act on the IP address of someone abusing you, usually banning him using [netfilter]( http://netfilter.org ). Basically you want to ban all skids bruteforcing you SSH service or your webmail login form. + +We figured out that *dropping skids^Whackers is cool, banning them is even better*. So this howto will show you how to ban those who are appearing to much in your naxsi logs. + +# Requirements +* An OS running Fail2ban and Naxsi +* A few minutes + +# Configuration +Very simple, create `/etc/fail2ban/filter.d/nginx-naxsi.conf` with: + +```ini +[INCLUDES] +before = common.conf +[Definition] +failregex = NAXSI_FMT: ip=&server=.*&uri=.*&learning=0 + NAXSI_FMT: ip=.*&config=block +ignoreregex = NAXSI_FMT: ip=.*&config=learning +``` + +And add a section within `/etc/fail2ban/jail.conf` with: + +```ini +[nginx-naxsi] +enabled = true +port = http,https +filter = nginx-naxsi +logpath = /var/log/nginx/*error.log +maxretry = 6 +``` + +So in `/var/log/fail2ban.log`, any time the same IP triggers Naxsi 6 times in 5 minutes (`fail2ban findtime=600`) you should see: + +``` +2012-06-29 15:34:44,016 fail2ban.actions: WARNING [nginx-naxsi] Ban 88.z.x.y` +``` + +BONUS: Graph this new fail2ban jail with [Munin]( http://munin-monitoring.org/ ) so you can track how many guys are trying to abuse your website :) \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/internal-rules.md b/dependencies/naxsi/docs/old/internal-rules.md new file mode 100644 index 0000000..082154a --- /dev/null +++ b/dependencies/naxsi/docs/old/internal-rules.md @@ -0,0 +1,109 @@ +# Internal rules + +Internal rules are rules that can be fired by naxsi, when request is incorrect or extremely unusual - or naxsi is not able to parse the request (ie. unknown content-type). +Please note that those rules do not set an internal score, but usually just set the `block` flag of the request to `1`. + +You can whitelist those, but you should never have to do so. +When whitelisting an internal rule, you might be disabling naxsi at least partially, so think twice about it. + + + + +## weird_request + * id: 1 + * action: block + * impact: pass-thru + +A request that cannot be understood by naxsi. +When whitelisting this one, you are telling naxsi to blindly accept the request and not to parse it. + +## big_request + * id: 2 + * action: block + * impact : pass-thru + +A request that is buffered on file system because it's too big. +Naxsi doesn't parse buffered requests. You can always increase [client_body_buffer_size](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_buffer_size) in nginx's config. + +## uncommon_hex_encoding + * id: 10 + * action: block + * impact : partial loss of decoding + +Hex encoding that is not valid, and that naxsi cannot "url decode". + +## uncommon_content_type + * id: 11 + * action: block + * impact : pass-thru on BODY + +A content-type unknown to naxsi. Meaning naxsi cannot parse the body. +However, if id:11 is whitelisted and >= 0.55rc2, [RAW_BODY](rawbody) rules can be used. + +## uncommon_url + * id: 12 + * action: block + * impact: partial pass-thru on GET args + +An URL that is not standard (ie. `?x=foo&z=bar`). Can lead to uncorrectly parsed arguments when whitelisted. + + +# uncommon_post_format + * id: 13 + * action: block + * impact: pass-thru on BODY + +POST body is malformed, ie. + * bad content-disposition + * no variable name + * malformed attached file content-type + +## uncommon_post_boundary + * id: 14 + * action: block + * impact: pass-thru on BODY + +POST body is malformed, ie. + * bad content-type + * bad boundary (too short, too long, not rfc compliant) + +## invalid_json + * id: 15 + * action: block + * impact: pass-thru on BODY (json) + +JSON is malformed (ie. missing `} ]`). + + +## empty_body + * id: 16 + * action: block + * impact: pass-thru on BODY + +Raised when body is empty and/or content-length is zero. + + +## libinjection_sql + * id: 17 + * action: ?? + +See [libinjection](libinjection-integration.md). + +## libinjection_xss + * id: 18 + * action: ?? + +See [libinjection](libinjection-integration.md). + +## no_rules + * id: 19 + * action: drop + * impact: no rules checked + +Raised when naxsi isn't configured with any MainRules. + +## bad_utf8 + * id: 20 + * action: drop + +Raised when [surrogate utf8](https://tools.ietf.org/html/rfc3629) is detected. diff --git a/dependencies/naxsi/docs/old/json.md b/dependencies/naxsi/docs/old/json.md new file mode 100644 index 0000000..4130f2b --- /dev/null +++ b/dependencies/naxsi/docs/old/json.md @@ -0,0 +1,31 @@ +# JSON + + +POST/PUT request with content-type `application/json` will be handled by naxsi so that it should be transparent in the whitelist / signatures writting process : + * all rules targeting `BODY` are applied to json content as well + * whitelists (or rules) for specific variable use the classic `$BODY_VAR:xx` + + +However for JSON, naxsi does not keep track of depth, and has [a hardcoded limit of 10 (depth)](internal-rules.md#invalid_json). + +A request : +``` +POST ... + +{ + "this" : { "will" : ["work", "does"], + "it" : "??" }, + "tr= 8" BLOCK; + CheckRule "$RFI >= 8" BLOCK; + CheckRule "$TRAVERSAL >= 4" BLOCK; + CheckRule "$EVADE >= 4" BLOCK; + CheckRule "$XSS >= 8" BLOCK; +``` + +With the following setup : +* Naxsi will be enabled +* Naxsi will not block any requests (while LearningMode is active) +* To-be-blocked requests will generate event logs in your location's error.log file + +If you issue a request to `http://127.0.0.1/?a=<`, you'll get something like this in your logs: + +``` +2013/05/30 20:09:43 [error] 8404#0:*3 NAXSI_FMT: ip=127.0.0.1&server=127.0.0.1&uri=/&learning=0&vers=0.50&total_processed=3&total_blocked=1&zone0=ARGS&id0=1302&var_name0=a, client: 127.0.0.1, server: , request: "GET /?a=< HTTP/1.0", host: "127.0.0.1" +``` + +Once you get this kind of lines in your error log, you have naxsi running in LearningMode, congrats! You can now move on to [[generating whitelists|whitelists]]! \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/legacy/olds-deniedurl.md b/dependencies/naxsi/docs/old/legacy/olds-deniedurl.md new file mode 100644 index 0000000..64affea --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-deniedurl.md @@ -0,0 +1,19 @@ +**DeniedUrl** is used to indicate a location where blocked requests will be redirected (internally). + +In version before 0.49, by default, naxsi forwards blocked request there while in learning mode. Upon "real" request termination, using nginx's [post_action]( http://wiki.nginx.org/HttpCoreModule#post_action ) mechanism. + +This was due to usage of `nx_intercept`, which could intercept learning traffic in live. + +As the request might be modified during redirect (url & arguments), extra http headers `orig_url` (original url), `orig_args` (original GET args) and `naxsi_sig` (NAXSI_FMT) are added. + +If $naxsi_flag_post_action is set to "1", naxsi will perform post_action (while in learning) even in versions '''> 0.49'''. + + +The headers that are forwarded to the location denied page are : + +``` +./naxsi_runtime.c: #define NAXSI_HEADER_ORIG_URL "x-orig_url" +./naxsi_runtime.c: #define NAXSI_HEADER_ORIG_ARGS "x-orig_args" +./naxsi_runtime.c: #define NAXSI_HEADER_NAXSI_SIG "x-naxsi_sig" +``` + diff --git a/dependencies/naxsi/docs/old/legacy/olds-dynamicmodifiers.md b/dependencies/naxsi/docs/old/legacy/olds-dynamicmodifiers.md new file mode 100644 index 0000000..52e6234 --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-dynamicmodifiers.md @@ -0,0 +1,75 @@ +### naxsi dynamic configuration (aka nginx vars) + +Since [0.49]( https://github.com/wargio/naxsi/tree/0.49 ), naxsi supports a limited set of boolean variables that can be set to `0` or `1` to override or modify its behaviour. + +* `naxsi_flag_learning` can override Naxsi learning flag. +* `naxsi_flag_post_action` may be used to disable `post_action` in learning mode. +* `naxsi_flag_enable` could override naxsi's `SecRulesEnabled`. +* `naxsi_extensive_log` can force naxsi to log the `CONTENT` of variable matching rules (see notes at bottom). + +### Gentle reminder +It is important to know that naxsi operates at the `REWRITE` phase of nginx. Thus, setting those variables directly in the location where Naxsi is present is ineffective (as naxsi will be called before variable set is effective). + +This is correct: + +```nginx + set $naxsi_flag_enable 0; + location / { + ... + } +``` + +But this is wrong: + +```nginx + location / { + set $naxsi_flag_learning 1; + ... + } +``` + +With that said, you can use the power of nginx, lua, etc. to change naxsi's behaviour. The presence of these variables will enable/disable learning mode, naxsi itself or force extensive logging. You can thus do things naxsi is usually not able to, like modifying its behaviour according to (nginx) variables set at run-time : + +```nginx + # Disable naxsi if client ip is 127.0.0.1 + if ($remote_addr = "127.0.0.1") { + set $naxsi_flag_enable 0; + } +``` + +Those variables can as well be set from lua scripts (see nginx's [mod_lua]( https://github.com/openresty/lua-nginx-module#readme )). + +### naxsi_flag_learning + +If the `naxsi_flag_learning` variable is present, this value will override naxsi's current static configuration regarding learning mode. + +```nginx + if ($remote_addr = "1.2.3.4") { + set $naxsi_flag_learning 1; + } + location / { + ... + } +``` + +### naxsi_flag_post_action + +The [post_action]( http://wiki.nginx.org/HttpCoreModule#post_action ) option can be used by naxsi to literally forward a request to the `DeniedUrl` location. It is on by default until [naxsi 0.50]( https://github.com/wargio/naxsi/tree/0.50 ) (a souvenir from `nx_intercept`) and is off by default since [naxsi 0.51]( https://github.com/wargio/naxsi/tree/0.51 ). + +### naxsi_flag_enable +If the `naxsi_flag_enable` variable is present and set to `0`, naxsi will be disabled in this request. This allows you to partially disable naxsi in specific conditions. To completely disable naxsi for "trusted" users : + +```nginx + set $naxsi_flag_enable 0; + location / { + ... + } +``` + +### naxsi_extensive_log +If present and set to `1`, this variable will force naxsi to log the CONTENT of variable matching rules. +Because of a potential impact on performance, use this with caution. Naxsi will log those to nginx’s error_log, ie: + +``` + NAXSI_EXLOG: ip=%V&server=%V&uri=%V&id=%d&zone=%s&var_name=%V&content=%V +``` diff --git a/dependencies/naxsi/docs/old/legacy/olds-embedded_rules.md b/dependencies/naxsi/docs/old/legacy/olds-embedded_rules.md new file mode 100644 index 0000000..509133e --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-embedded_rules.md @@ -0,0 +1,29 @@ + +# Internal rules + +Since its [0.53 release]( https://github.com/wargio/naxsi/tree/0.53 ), naxsi comes with a predefined set of rules with the following id: + +- `1` - "weird request" : This a generic exception used for improperly formatted requests. +- `2` - "big request" : Request is too big and has been buffered to disk by nginx. +- `10` - "uncommon hex encoding" : Encoding suggests this might be an escape attempt. +- `11` - "uncommon content-type" : Content-type of BODY is unknown / cannot be parsed. +- `12` - "uncommon URL" : URL is malformed +- `13` - "uncommon post format" : malformed boundary or content-disposition +- `14` - "uncommon post boundary" : BODY boundary line is malformed, or boundary breaks RFC +- `15` - invalid JSON - gets parsed when application/json is detected (experimental as of summer 2014) +- `16` - "empty body" : POST with empty BODY, available since [naxsi 0.53-1]( https://github.com/wargio/naxsi/tree/0.53 ), was merged with `id:11` before. +- `17` - "Libinjection SQL" : Libinjection SQL detection was triggered. +- `18` - "Libinjection XSS" : Libinjection XSS detection was triggered. + + +## naxsi-core.rules + +Naxsi ships with a [basic core-rule-set]( https://github.com/wargio/naxsi/blob/main/naxsi_rules/naxsi_core.rules ) +that protects against common attacks. Those Core-Rules should always be loaded. + +- [SQL-Injections]( https://www.owasp.org/index.php/SQL_Injection ) (1000-1099) +- Obvious [Remote File Inclusions]( https://www.owasp.org/index.php/OWASP_Periodic_Table_of_Vulnerabilities_-_Remote_File_Inclusion ) (1100-1199) +- [Directory Traversal]( https://www.owasp.org/index.php/Path_Traversal ) (1200-1299) +- [Cross Site Scripting]( https://www.owasp.org/index.php/XSS ) (1300-1399) +- [Basic Evading tricks]( https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet ) (1400-1500) +- [File uploads]( https://www.owasp.org/index.php/Unrestricted_File_Upload ) (1500-1600) diff --git a/dependencies/naxsi/docs/old/legacy/olds-faq.md b/dependencies/naxsi/docs/old/legacy/olds-faq.md new file mode 100644 index 0000000..cf66001 --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-faq.md @@ -0,0 +1,40 @@ +## Naxsi blocks all requests but no IDs are written + +If you see lines like : +``` +2013/09/03 00:11:45 [error] 14913#0: *1 NAXSI_FMT: ip=127.0.0.1&server=localhost&uri=/&learning=1&vers=0.50&total_processed=1&total_blocked=1, client: 127.0.0.1, server: , request: "GET / HTTP/1.0", host: "localhost" +``` + +It's usually because you forgot to include naxsi rules in your `http {}` block. Try adding `include /etc/nginx/naxsi_core.rules;` to it. + +## I compiled naxsi from source, I enabled NAXSI, but it doesn't seem to filter requests? + +Did you put naxsi directives first in your location configuration and `./configure`? +You **MUST** put naxsi's directives first in your location configuration. Please check as well your configuration at both `http {}` and `location {}` levels. + +## How to limit learning mode to some specific IPs/Users/locations? + +Naxsi supports [[DynamicModifiers]] to change behaviour at runtime. +You can as well rely on nginx's [HttpAllowModule]( http://wiki.nginx.org/HttpAccessModule ). +You could also set different vhosts (with associated locations) up, and define some to have `learningmode`, and others without. + +## How to test that naxsi is working? + +Setup your RequestDenied as follow : + +```nginx +location /RequestDenied { + return 500; +} +``` + +Check that `learningMode` is disabled, that `naxsi_core.rules` is included, and issue a request like `http:/.../?a=<>`. You should get a 500 from nginx, and get an entry in your nginx error log, starting with `NAXSI_FMT:`. + +## I downloaded / installed packages from X, but I don't have this feature / new learning tools? +Naxsi is a young and evolving project and distributions cannot always keep up. Use the source luke, as documented [[here|installation]]. + +## Why do you keep radically changing learning tools? +Because it's a not-that-easy problem, and we haven't found a satisfying solution yet. If you have ideas about how we could do it better, please tell us! + +## Can I run naxsi on Windows +No one tried that yet, but feel free to go down the [rabbit hole]( http://nginx-win.ecsds.eu/ ) \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/legacy/olds-installation.md b/dependencies/naxsi/docs/old/legacy/olds-installation.md new file mode 100644 index 0000000..3ce8407 --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-installation.md @@ -0,0 +1,82 @@ +You can install nginx+naxsi either from packages (available from official repositories on debian, freebsd, netbsd) or directly from source. +As Nginx does not yet support runtime module loading, lot of people will choose compiling from source to avoid package maintainers delay. + +## Installation From Packages + +Packages are available for NetBSD, FreeBSD and Debian, from distribution's repositories. +Naxsi project does not create/publish such packages. + +## Installation From Source + +Naxsi should be working with all Nginx versions superior to 0.8.X. +To install it from source, we need to fetch both nginx and naxsi sources. + +#### Import Source Signing Keys +Import [Nginx signing keys]( http://nginx.org/en/pgp_keys.html ) and [naxsi's one](https://pgp.mit.edu/pks/lookup?op=get&search=0x251A28DE2685AED4). + +_note_ : Signed releases of naxsi started at [0.54rc3]( https://github.com/nbs-system/naxsi/tree/0.54rc3 ). + +```shell +gpg --keyserver pgp.mit.edu --recv-keys 0x251A28DE2685AED4 7BD9BF62 A1C052F8 +``` + +#### Download Sources +Note: replace `TAG_NAME` with the [tagged release](https://github.com/nbs-system/naxsi/tags) you want. + +```shell +wget http://nginx.org/download/nginx-x.x.xx.tar.gz +wget http://nginx.org/download/nginx-x.x.xx.tar.gz.asc +wget https://github.com/nbs-system/naxsi/archive/TAG_NAME.tar.gz +wget https://github.com/nbs-system/naxsi/releases/download/TAG_NAME/TAG_NAME.tar.gz.asc +``` + +#### Verify Sources + +```shell +gpg --verify nginx-*.tar.gz.asc nginx-*.tar.gz +gpg --verify TAG_NAME.tar.gz.asc TAG_NAME.tar.gz +``` + +Both source verifications should present you a message that says: + +``` +> gpg: Good signature from ... +``` + +#### Unpack Sources +If both sources verify, then it is safe to unpack and proceed to compilation. + +```shell +tar -xvzf nginx-*.tar.gz +tar -xvzf TAG_NAME.tar.gz +``` + +#### Compiling +Install `libpcre` (and `libssl` if you want https, along with `zlib` for gzip support) with your favorite package manager, naxsi relies on it for regex. + +```shell +cd nginx-* +./configure --add-module=../naxsi-x.xx/naxsi_src/ [add/remove your favorite/usual options] +make +make install +``` + +My personal "building" options being here : + +```shell +./configure --conf-path=/etc/nginx/nginx.conf --add-module=../naxsi-x.xx/naxsi_src/ \ +--error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body \ +--http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log \ +--http-proxy-temp-path=/var/lib/nginx/proxy --lock-path=/var/lock/nginx.lock \ +--pid-path=/var/run/nginx.pid --with-http_ssl_module \ +--without-mail_pop3_module --without-mail_smtp_module \ +--without-mail_imap_module --without-http_uwsgi_module \ +--without-http_scgi_module --with-ipv6 --prefix=/usr +``` + +# IMPORTANT + +You need to remember this : +NGINX will decide the order of modules according the order of the module's directive in nginx's `./configure`. So, no matter what (except you really know what you are doing) put naxsi first in your `./configure`. + +If you don't do so, you might run into various problems, from random / unpredictable behaviours to non-effective WAF. \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/legacy/olds-libinjection.md b/dependencies/naxsi/docs/old/legacy/olds-libinjection.md new file mode 100644 index 0000000..72fc463 --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-libinjection.md @@ -0,0 +1,22 @@ +Libinjection is being integrated into naxsi, starting at 0.54rc0 + + * https://github.com/nbs-system/naxsi/releases/tag/0.54rc0 + +We are looking for people to test it and provide feedback on it. + +Usage : + + * By default, Libinjection (sql/xss) is disabled, it needs to be enabled at location level using one of these directives : LibInjectionSql / LibInjectionXss (or libinjection_sql / libinjection_xss in nginx style). + * It can as well be dynamically enabled / disabled using : +``` +set $naxsi_libinjection_xss 0|1; +set $naxsi_libinjection_sql 0|1; +``` + * When triggered, libinjection sql/xss will trigger internal rules : + * libinjection_sql, with internal ID of 17, will increase $LIBINJECTION_SQL of 8 + * libinjection_xss, with internal ID of 18, will increase $LIBINJECTION_XSS of 8 + + * If you want to add action uppon trigger, write your CheckRules on those scores ;) (as for other rules, LOG/BLOCK/DROP is allowed!) + + + diff --git a/dependencies/naxsi/docs/old/legacy/olds-naxsilogs.md b/dependencies/naxsi/docs/old/legacy/olds-naxsilogs.md new file mode 100644 index 0000000..ef20cd9 --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-naxsilogs.md @@ -0,0 +1,78 @@ +### NAXSI_FMT + +NAXSI_FMT are the lines you can see in your error.log : + +``` +2013/11/10 07:36:19 [error] 8278#0: *5932 NAXSI_FMT: ip=X.X.X.X&server=Y.Y.Y.Y&uri=/phpMyAdmin-2.8.2/scripts/setup.php&learning=0&vers=0.52&total_processed=472&total_blocked=204&block=0&cscore0=$UWA&score0=8&zone0=HEADERS&id0=42000227&var_name0=user-agent, client: X.X.X.X, server: blog.memze.ro, request: "GET /phpMyAdmin-2.8.2/scripts/setup.php HTTP/1.1", host: "X.X.X.X" +``` + +Here, client `X.X.X.X` request to server `Y.Y.Y.Y` did trigger the rule `42000227` in the var named `user-agent` in the`HEADERS` zone. `id X` might seem obscure, but you can see the meaning in [naxsi_core.rules]( https://github.com/nbs-system/naxsi/blob/master/naxsi_config/naxsi_core.rules ): + +``` +MainRule "str:<" "msg:html open tag" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1302; +``` + +NAXSI_FMT is composed of different items : + +- `ip` : Client's ip +- `server` : Requested Hostname (as seen in http header `Host`) +- `uri`: Requested URI (without arguments, stops at `?`) +- `learning`: tells if naxsi was in learning mode (0/1) +- `vers` : Naxsi version, only since [0.51]( https://github.com/nbs-system/naxsi/tree/0.51 ) +- `total_processed`: Total number of requests processed by nginx's worker +- `total_blocked`: Total number of requests blocked by (naxsi) nginx's worker +- `zoneN`: Zone in which match happened (see "Zones" in the table below) +- `idN`: The rule id that matched +- `var_name`: Variable name in which match happened (optional) + +Several groups of zone, id, var_name can be present in a single line. + +Existing zones can be are the following: + +- `ARGS`: GET args +- `$ARGS_VAR `: named GET argument +- `$ARGS_VAR_X`: regex matching the name of a GET argument +- `HEADERS `: HTTP Headers +- `$HEADERS_VAR ` : named HTTP header +- `$HEADERS_VAR_X`: regex matching a named HTTP header +- `BODY `: POST args (and RAW_BODY) +- `$BODY_VAR `: named POST argument +- `$BODY_VAR_X`: regex matching the name of a POST argument +- `URL`: The URL (before '?') +- `$URL`: The specified URL +- `$URL_X`: regex matching the URL (before '?') +- `FILE_EXT`: Filename (in a multipart POST containing a file) + +A zone can be suffixed with "|NAME", meaning the rule matched in the name of the variable, not its content. + +As well, several scores can be present since [0.53]( https://github.com/nbs-system/naxsi/tree/0.53 ): + +```ini +cscoreX=[score_tag] +scoreX=[score_value] +``` + +### NAXSI_EXLOG + +NAXSI_EXLOG is a complement to [[naxsilogs]]. Along with exceptions, it contains actual content of the matched request. While NAXSI_FMT only contains IDs and location of exception, NAXSI_EXLOG provides actual content, allowing you to easily decide if it's a false positive or not. + +Learning tools uses this at his advantage. Extensive log is enabled by adding the following line in your server {} section but **out** of your location. + +```javascript +set $naxsi_extensive_log 1; +``` + +This feature is provided by [[DynamicModifiers]]. + +``` +2013/05/30 20:47:05 [debug] 10804#0:*1 NAXSI_EXLOG: ip=127.0.0.1&server=127.0.0.1&uri=/&id=1302&zone=ARGS&var_name=a&content=a<>bcd +2013/05/30 20:47:05 [error] 10804#0:*1 NAXSI_FMT: ip=127.0.0.1&server=127.0.0.1&uri=/&learning=0&vers=0.50&total_processed=1&total_blocked=1&zone0=ARGS&id0=1302&var_name0=a, client: 127.0.0.1, server: , request: "GET /?a=a<>bcd HTTP/1.0", host: "127.0.0.1" +``` + +### Naxsi Internal IDs + +"User defined" rules are supposed to have IDs > `1000`. + +IDs inferior `1000` are reserved for [[naxsi internal rules|embedded_rules]], which are usually related to protocol sanity and things that cannot be expressed through regular expressions or string matches. + +Think twice before whitelisting one of those IDs, as it might partially/totally disable naxsi. \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/legacy/olds-naxsivsappscan.md b/dependencies/naxsi/docs/old/legacy/olds-naxsivsappscan.md new file mode 100644 index 0000000..7db94f6 --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-naxsivsappscan.md @@ -0,0 +1,47 @@ +# Classical benchmark : Web Vuln Scanner vs WAF + +Here we will present the results of (IBM) [AppScan]( https://www-03.ibm.com/software/products/en/appscan/ ) vs naxsi. + +Why AppScan ? Because, it's one of the less worse commercial scanner available, because they offer a target/demo (read : highly vulnerable) website, and, unlike [Acunetix]( https://www.acunetix.com/ ), you can run full tests on the target website. + +# Overall Results + +As you will see bellow, AppScan is not able to find any vulnerabilities that it can exploit. The only vulnerabilities detected are probed with extremely simple patterns (read : nearly full ascii) that are not (and will not) be blocked by naxsi (to avoid false positives). + +## Raw results + +When running AppScan against [demo.testfire.net]( http://demo.testfire.net ) with naxsi (set-up as forward proxy for this purpose), the following vulnerabilities will appear: + +![appscanfull](Images/appscanfull.png) + +I won't make an exhaustive diff list between naxsi and raw results since, as you can expect, original scan results have a LOT of vulnerabilities, as this website is designed to show all the vulnerabilities AppScan can detect/exploit. + +Let's go through all the "remaining" bugs : + +## Blind SQL Injections + +The scan result shows at least 2 Blind SQL Injection remaining. Actually, the attack pattern used by AppScan is the following : + +![details 1](Images/appscandetails1.png) +![details 2](Images/appscandetails2.png) + + +The first test pattern `listAccounts=0%2B0%2B0%2B1001160141` is decoded to `listAccounts=0+0+0+1001160141`, and the seconde one, `before=1234+and+7659%3D7659` to `before=1234 and 7659=7659`. Appscan is able to detect the vulnerability, but it will not be able to exploit it. + +## Database Error Pattern + +During the scan, AppScan was able to detect several "Database Error Pattern" (read : MSSQL/MySQL/... error messages in webpage) + +![details 3](Images/appscandetails3.png) + +The test pattern used by AppScan is `100116014WFXSSProbe`, it's a generic one to *trace back* injected data into a webpage. Here, the scanner is able to trigger the bug by entering a non-numeric value in a numeric field, making the page yield a SQL error message. Obviously, you cannot do anything here except blocking the scanner's pattern, which would be dumb and inefficient. Obviously, the injected characters won't allow any kind of exploitation of the vulnerability, only a probe. + +## Other vulnerabilities + +The other vulnerabilities reported by AppScan : + +* Weak credentials : Because it's possible to login with admin/admin. No comment Out of scope for a WAF. +* Session Reuse : When logging / logging off and logging in again, AppScan notices that the Cookie (session) doesn't change. (Out of scope for a WAF) +* Weak Cookies : Sensitive information is stored in the user's cookie, enabling cookie theft if someone can access the user's workstation. (Out of scope for a WAF) +* No account lock : An attacker can brute-force passwords. (Out of scope for a WAF, but nginx with req_limit might help you solving that !) +* CSRF : This is more touchy, because it can be blocked by NAXSI, by adding a rule like `BasicRule "rx:http://demo.testfire.net/*" "mz:$HEADERS:Referer";`, but we didn't add it, because we wanted this scan to be really "out of the box" with no customization. \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/legacy/olds-naxsivsobfuscated.md b/dependencies/naxsi/docs/old/legacy/olds-naxsivsobfuscated.md new file mode 100644 index 0000000..cdb4dd6 --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-naxsivsobfuscated.md @@ -0,0 +1,193 @@ +### Introduction/Disclaimer + +First of all, and to prevent any trolls : We're **not** saying that naxsi is better than [mod_security]( https://modsecurity.org/ ). We think that mod_security is a great project and we have a huge respect for its team. + +That being said, we will present you the results of the mod_security SQLi challenge. This challenge was organized by the mod_security people, and participants had to bypass mod_security to perform SQLi on various vulnerable web sites. + +As you will see, none of the attack patterns used will bypass naxsi, because naxsi isn't clever and doesn't try to interpret stuff in requests, avoiding the risk of getting bypassed by obfuscated syntax. + +Last but not least, the more uncommon a request is, the more chance they have to be blocked by naxsi. + +Detailed information about the mod_security challenge can be found [here]( http://blog.spiderlabs.com/2011/07/modsecurity-sql-injection-challenge-lessons-learned.html ) + +#### Bypass #1 : Johannes Dahse + +##### Payload +``` +http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=0+div+1+union%23foo*%2F*bar%0D%0Aselect%23foo%0D%0A1%2C2%2Ccurrent_user +``` + +##### Decoded + +``` +http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=0+div+1+union#foo*/*bar +select#foo +1,2,current_user +``` + +##### Explanation + +* Multiple SQL keywords +* SQL comments +* Uncommon characters : `, #*` + +#### Bypass #2 : Vladimir Vorontsov + +##### Payload + +``` +FromDate=a1%27+or&ToDate=%3C%3Eamount+and%27 +``` + +##### Decoded + +``` +FromDate=a1'+or&ToDate=<>amount+and' +``` + +##### Explanation +* Multiple quotes +* `<>` Signs + +#### Bypass #3 : PT Research + +##### Payload + +``` +after=1 AND (select DCount(last(username)&after=1&after=1) from users where username='ad1min')&before=d +``` + +##### Explanation +* Multiple SQL keywords +* Multiple parenthesis +* Multiple quotes +* Naxsi is immune to splitting attacks + +#### Bypass #4 : Ahmad Maulana + +##### Payload + +``` +ToDate=1'UNION/*!0SELECT user,2,3,4,5,6,7,8,9/*!0from/*!0mysql.user/*- +``` + +##### Explanation +* Multiple SQL keywords +* SQL comments +* Multiple quotes +* Uncommon characters : `, !` + +#### Bypass #5 : Travis Lee + +##### Payload + +``` +Cookie: ASP.NET_SessionId=c0tx0o455d0b10ylsdr03m55; amSessionId=14408158863; amUserInfo=UserName=YWRtaW4=& +Password=JyBvciAnMSc9JzEnLS0=; amUserId=1 union select username,password,3,4 from users +``` + +##### Explanation +* Multiple SQL keywords +* Multiple commas +* This one is really interesting, as mod_security was bypassed, not because of the pattern, but because of its location (Cookie Headers) + +#### Bypass #6 : Roberto Salgado + +##### Payload + +``` +http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=- +2%20div%201%20union%20all%23yeaah%0A%23yeah%20babc%0A%23fdsafdsafa%23fafsfaf%23%23yea%0A +%23yeah%20babc%0A%23fdsafdsafa%23fafsfaf%23%23yeaah%0A%23yeah%20babc%0A%23fdsafdsafa%23f +afsfaf%23%23yea%0A%23yeah%20babc%0A%23fdsafdsafa%23fafsfaf%23%23yeaah%0A%23yeah%20babc%0 +A%23fdsafdsafa%23fafsfaf%23%23yea... +truncated +...3fafsfaaf%23fafsfaaf%23fafsfaaf%23fafsfaaf% +0Aselect%200x00,%200x41%20like/*!31337table_name*/,3%20from%20information_schema.tables% +20limit%201 +``` + +##### Decoded + +``` +2 div 1 union all#yeaah +#yeah babc +#fdsafdsafa#fafsfaf##yea +#yeah babc +#fdsafdsafa#fafsfaf##yeaah... +truncated +... +like/*!31337table_name*/,3 from information_schema.tables... +``` + +##### Explanation +* Multiple SQL keywords +* SQL comments +* uncommon characters : `# , !` + +#### Bypass #7 : Sqlmap Developers + +##### Payload + +``` +http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=%40%40new%20union%23sqlmapsqlmap...%0Aselect%201,2,database%23sqlmap%0A%28%29 +``` + +##### Decoded + +``` +http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=@@new union#sqlmapsqlmap... +select 1,2,database#sqlmap +() +``` + +###### Explanation +* Multiple SQL keywords +* Uncommon characters : `.. # , ()` + +#### Bypass #8 : HackPlayers + +###### Payload + +``` +http://www.modsecurity.org/testphp.vulnweb.com/artists.php?artist=- +2%20div%201%20union%20all%23hack%0A%23hpys%20player%0A%23fabuloso%23great%0A%23hpys%20pl +ayer%0A%23fabuloso%23modsec%0A%23hpys%20player%0A%23fabuloso%23great%0A%23hpys%20player% +0A%23fabuloso%23modsec%0A%23h... +truncated +...23hpys%20player%0A%23fabuloso%23great%23%0A%23fabuloso%23great%23%0Aselect%200x00%2C%200 +x41%20not%20like%2F*%2100000table_name*%2F%2C3%20from%20information_schema.tables%20limi +t%201 +``` + +##### Decoded + +``` +-2 div 1 union all#hack +#hpys player +#fabuloso#great... +truncated +... +select 0x00, 0x41 not like/*!00000table_name*/,3 from information_schema.tables limit 1 +``` + +##### Explanation + +* Multiple SQL keywords +* SQL comments +* Uncommon characters : `# , ! ` + +#### Bypass #9 : Georgi Geshev + +##### Payload + +``` +http://www.modsecurity.org/testphp.vulnweb.com/listproducts.php?artist=1%0bAND(SELECT%0b1%20FROM%20mysql.x) +``` + +##### Explanation +* Multiple SQL keywords + + +### Final WORD +All those tests where realized on a 'out of the box' naxsi, we I did no customization nor any modifications whatsoever. diff --git a/dependencies/naxsi/docs/old/legacy/olds-rulessyntax.md b/dependencies/naxsi/docs/old/legacy/olds-rulessyntax.md new file mode 100644 index 0000000..d968b9a --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-rulessyntax.md @@ -0,0 +1,127 @@ +Naxsi is using a simple key-value system for its rules. For example `MainRule "msg:this is a message" "str:searchstring" "mz:URL|BODY|ARGS" "s:$XSS:8" id:12345678990;` is a *main* rule with the *id* 12345678990, that search the string `searchstring` in the *url*, the *body* and the *arguments* of the request, and upon match, it will increase the `XSS` score by 8. + +Everything must be quoted with double quotes, except the id part. + +``` + +MainRule "msg:this is a message" "str:searchstring" "mz:URL|BODY" "s:$XSS:8" id:12345; + | | | | | +-> UNIQUE ID + | | | | | + | | | | +-> SCORE + | | | | + | | | +-> MZ + | | | + | | +-> SearchString/RegEx + | | + | +-> MESSAGE + | + +-> RuleDesignator +``` + +## Designator +Either `MainRule` or `BasicRule`. + +BasicRule and MainRule can be used either for rules or whitelist. +The difference is the scope : BasicRule is valid in location {} context, while MainRule is valid at http {} context. + +## Match Pattern (str:... rx:...) + +**Match pattern** can be a regular expression or a string match: + +* `rx:foo|bar` : will match `foo` or `bar` +* `str:foo|bar` : will match `foo|bar` +* `d:libinj_xss` : will match if libinjection says it's XSS (**>= 0.55rc2**) +* `d:libinj_sql` : will match if libinjection says it's SQLi (**>= 0.55rc2**) + +Using plain string match when possible is recommended, as it's way faster. +All strings *must* be lowercase, since naxsi's matches are case insensitive. + +## Human readable message (msg:...) + +**msg** is a string describing the pattern. This is mostly used for analyzing and to have some human-understandable text. + + +## Score section (s:...) + +**s** is the score section. You can create "named" counters: `s:$FOOBAR:4` will increase counter `$FOOBAR` value by 4. One rule can increase several scores: `s:$FOO:4,$BAR:8` will increase both `$FOO` by `4` and `$BAR` by `8`. A rule can as well directly specifiy an action such a BLOCK (blocks the request in non-learning mode) or DROP (blocks the request **even** in learning mode) + +## Match Zone (mz:...) + +**mz** is the match zone, defining which part of the request will be inspected by the rule (or the whitelist, it works in the same way). + +`mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie` means that pattern will be searched in the whole *body* (content and name of each var), as well as in **url** (before the '?') and in the get **arguments** (content and name of each var). + +`$HEADERS_VAR:Cookie` means that the pattern will be as well applied to the HTTP header named `Cookie`. Filenames of file uploads can be check as well with the `FILE_EXT` zone. + +See [Whitelists generation]( whitelists ), as same `mz:` usage applies. ie. `mz:$URL:/foo|$ARGS_VAR:arg42` will create a rule that will only be looked against GET argument `arg42` of request to URL `/foo`. (**fixed in >= 0.55rc2**) + +You can as well use the `_X` (>= 0.52) equivalents, that allows you to create matchzone matching regular expressions, for example: `mz:$URL_X:^/foobar[0-9]+$` to match URLs such as `foobar1`, `foobar000`, etc. However, because of a known limitation, you can't use `|` character in your `_X` regular expressions, because it is used as a field separator by naxsi rule parsing. + +Starting from naxsi **0.55rc0**, for unknown content-types, you can use the `RAW_BODY` match-zone. `RAW_BODY` rules looks like that: + +``` +MainRule id:4241 s:DROP str:RANDOMTHINGS mz:RAW_BODY; +``` + +Rules in the `RAW_BODY` zone will only applied when: + - The *Content-type* is unknown (which means naxsi doesn't know how to properly parse the request) + - `id 11` (which is the internal blocking rule for 'unknown content-type') is whitelisted. + +Then, the full body (url decoded and with null-bytes replaced by '0') is passed to this set of rules. +The full body is matched again the regexes or string matches. + +Whitelists for `RAW_BODY` rules are actually written just like normal body rules, such as: + +``` +BasicRule wl:4241 "mz:$URL:/rata|BODY"; +``` + +### Valid *mz* + +- **URL** Full URI (server-path of a request) +- **ARGS** Request-Arguments (all the things behind the `?` character in a GET-Request) +- **BODY** Request-Data from a POST-Request +- **HEADERS** +- **$HEADERS_VAR:[value]** any HTTP-HEADERS-var that is available, eg + - **$HEADERS_VAR:User-Agent** + - **$HEADERS_VAR:Cookie** + - **$HEADERS_VAR:Content-Type** + - **$HEADERS_VAR:Connection** + - **$HEADERS_VAR:Accept-Encoding** +- **FILE_EXT** Filename (in a multipart POST containing a file) + +For rules, each item of the match zone is considered inclusive **OR** (with the exception of $URL / $URL_X that **must** be satisfied if present in match-zone). + +## ID (id:...) + +**id** is the ID of the rule, that will be used in `NAXSI_FMT` or to whitelist it. + +IDs inferior to `1000` are reserved for naxsi internal rules (protocol mismatch etc.) + +## Negative Keyword (negative) + +**negative** is a keyword that can be used to make a negative rule. +Score is applied when the rule doesn't match : + +``` +MainRule negative "rx:multipart/form-data|application/x-www-form-urlencoded" "msg:Content is neither mulipart/x-www-form.." "mz:$HEADERS_VAR:Content-type" "s:$EVADE:4" id:1402; +``` + +# Examples + +This will look for the string `Submit=Run` on the url `/script`, with the *POST* variable `Submit` present: +``` +MainRule "msg:detection Submit=Run in POST" "str:Submit=Run" "mz:$URL:/script|$BODY_VAR:Submit" "s:$ATTACK" id: 1230001; +``` + +This will look for accesses on the `/hidden.html` url: +``` +MainRule "msg:detection URL-Access" "str:/hidden.html" "mz:URL" "s:$ATTACK" id:1230002; +``` + +This will detect the string `jjoplmh` in the `cms` *GET* variable: +``` +MainRule "str:jjoplmh" "msg:Possible Wordpress-Plugin-Backdoor detected" "mz:$ARGS_VAR:cms" "s:$UWA:8" id:42000347; +``` + +naxsi_core.rules contains examples of rules. See as well mex's [[Doxi rules | https://bitbucket.org/lazy_dogtown/doxi-rules]] for more rules examples (doxi is third party rules that will focus on emerging threats). diff --git a/dependencies/naxsi/docs/old/legacy/olds-testing-and-stuff.md b/dependencies/naxsi/docs/old/legacy/olds-testing-and-stuff.md new file mode 100644 index 0000000..4bf333f --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-testing-and-stuff.md @@ -0,0 +1,21 @@ +# Unit Tests + +Naxsi comes with [unit tests]( https://github.com/nbs-system/naxsi/tree/master/t ). +This is very useful for people who wants to modify naxsi, build packages, test it on exotic setups, … +We try to keep our [code coverage]( http://codecov.io/github/nbs-system/naxsi?branch=master ) as high as possible. + +This is how you can run them: + +1. Untar [nginx code source]( http://nginx.org/en/download.html ) in `/tmp/nginx/`. +2. Setup naxsi for unit testing (from [naxsi_src]( https://github.com/nbs-system/naxsi/tree/master/naxsi_src )). + * `make re` will compile naxsi to run from `/tmp/` + * `make deploy ` will deploy a minimal naxsi in `/tmp/naxsi_ut/` (running on high port) + * `make test` will run the unit tests +3. It will give you a pass/fail result. +4. Look at the resulting `/tmp/naxsicov.html/` to get a code coverage report. + +If you're too lazy to run them, no worries, [travis-ci]( https://travis-ci.org/nbs-system/naxsi ) is running them for every pull-request that you'll submit! + +## Coverity + +[Coverity]( https://scan.coverity.com/projects/1883 ) is cool enough to allow open-source projects to use their cloud solutions for free. We do submit builds for every release. If you want to have access to detail results (ie. doing security assessment on naxsi), get in touch with us! \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/legacy/olds-whitelists-bnf.md b/dependencies/naxsi/docs/old/legacy/olds-whitelists-bnf.md new file mode 100644 index 0000000..4652b9e --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-whitelists-bnf.md @@ -0,0 +1,103 @@ +### BasicRule +BasicRule(s) are present at the location's configuration level. It is (most of the time) used to create whitelists. BasicRule syntax is : + +![whitelist-diagram](Images/Whitelist.png) + +#### **wl:ID** (WhiteList) + +Which rule ID(s) are whitelisted. Possible syntax are: + +![wl-diagram](Images/wl.png) + +* `wl:0` : Whitelist all rules +* `wl:42` : Whitelist rule `#42` +* `wl:42,41,43` : Whitelist rules `42`, `41` and `43` +* `wl:-42` : Whitelist all user rules (`>= 1000`), excepting rule `42` + + + +#### **mz:** (MatchZones) + +![mz-diagram](Images/mz.png) + +Specify the zones (see below) in which the exception is allowed. Existing Zones are the following : + +- `ARGS`: GET args +- `$ARGS_VAR `: named GET argument +- `$ARGS_VAR_X`: regex matching the name of a GET argument +- `HEADERS `: HTTP Headers +- `$HEADERS_VAR ` : named HTTP header +- `$HEADERS_VAR_X`: regex matching a named HTTP header +- `BODY `: POST args (and RAW_BODY) +- `$BODY_VAR `: named POST argument +- `$BODY_VAR_X`: regex matching the name of a POST argument +- `URL`: The URL (before '?') +- `$URL`: The specified URL +- `$URL_X`: regex matching the URL (before '?') +- `FILE_EXT`: Filename (in a multipart POST containing a file) + +### Whitelist Example + +Totally disable rule #1000 for this location, matchzone is empty, so the whitelist always matches. + +``` +BasicRule wl:1000; +``` + +Disable rule #1000 on all url in GET argument named `foo`: + +``` +BasicRule wl:1000 "mz:$ARGS_VAR:foo"; +``` + +Disable rule `#1000` in GET argument named `foo` for url `/bar`: + +``` +BasicRule wl:1000 "mz:$ARGS_VAR:foo|$URL:/bar"; +``` + +Disable rule `#1000` in all GET arguments for url `/bar`: + +``` +BasicRule wl:1000 "mz:$URL:/bar|ARGS"; +``` + +Disable rule `#1000` in all GET argument NAMES (only name, not content): + +``` +BasicRule wl:1000 "mz:ARGS|NAME"; +``` + +### Notes + +- A zone can be suffixed with `|NAME`, meaning the rule matched in the name of the variable, but not its content. +- Both matchzone content and patterns (`rx:`/`str:`) must be in lower-case, as naxsi is case insensitive +- `RAW_BODY` whitelists are written just as any `BODY` whitelist, see [[rulessyntax]] +- A whitelist can't mix `_X` elements with `_VAR` or `$URL` items. ie: + +``` +$URL_X:/foo|$ARGS_VAR:bar : WRONG +$URL_X:^/foo$|$ARGS_VAR_X:^bar$ : GOOD +``` + +### Regex Whitelist Examples + +Available only in [naxsi 0.52]( https://github.com/nbs-system/naxsi/releases/tag/0.52 ) and later. + +Disable rule `#1000` in all GET arguments containing `meh`: + +``` +BasicRule wl:1000 "mz:$ARGS_VAR_X:meh"; +``` + +Disable rule `#1000` in GET argument named `meh`: + +``` +BasicRule wl:1000 "mz:$ARGS_VAR_X:^meh"; +``` + +Disable rule `#1000` in all GET arguments matching `meh_`: + +``` +BasicRule wl:1000 "mz:$ARGS_VAR_X:^meh_[0-9]+$" +``` \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/legacy/olds-whitelists.md b/dependencies/naxsi/docs/old/legacy/olds-whitelists.md new file mode 100644 index 0000000..abc76fe --- /dev/null +++ b/dependencies/naxsi/docs/old/legacy/olds-whitelists.md @@ -0,0 +1,99 @@ +### BasicRule +BasicRule(s) are present at the location's configuration level. It is (most of the time) used to create whitelists. BasicRule syntax is : + +``` +BasicRule wl:ID [mz:[$URL:target_url]|[match_zone]|[$ARGS_VAR:varname]|[$BODY_VAR:varname]|[$HEADERS_VAR:varname]|[NAME]] +``` + +#### **wl:ID** (WhiteList) + +Which rule ID(s) are whitelisted. Possible syntax are: + +* `wl:0` : Whitelist all rules +* `wl:42` : Whitelist rule `#42` +* `wl:42,41,43` : Whitelist rules `42`, `41` and `43` +* `wl:-42` : Whitelist all user rules (`>= 1000`), excepting rule `42` + +#### **mz:** (MatchZones) + +Specify the zones (see below) in which the exception is allowed. Existing Zones are the following : + +- `ARGS`: GET args +- `$ARGS_VAR `: named GET argument +- `$ARGS_VAR_X`: regex matching the name of a GET argument +- `HEADERS `: HTTP Headers +- `$HEADERS_VAR ` : named HTTP header +- `$HEADERS_VAR_X`: regex matching a named HTTP header +- `BODY `: POST args (and RAW_BODY) +- `$BODY_VAR `: named POST argument +- `$BODY_VAR_X`: regex matching the name of a POST argument +- `URL`: The URL (before '?') +- `$URL`: The specified URL +- `$URL_X`: regex matching the URL (before '?') +- `FILE_EXT`: Filename (in a multipart POST containing a file) + +### Whitelist Example + +Totally disable rule #1000 for this location, matchzone is empty, so the whitelist always matches. + +``` +BasicRule wl:1000; +``` + +Disable rule #1000 on all url in GET argument named `foo`: + +``` +BasicRule wl:1000 "mz:$ARGS_VAR:foo"; +``` + +Disable rule `#1000` in GET argument named `foo` for url `/bar`: + +``` +BasicRule wl:1000 "mz:$ARGS_VAR:foo|$URL:/bar"; +``` + +Disable rule `#1000` in all GET arguments for url `/bar`: + +``` +BasicRule wl:1000 "mz:$URL:/bar|ARGS"; +``` + +Disable rule `#1000` in all GET argument NAMES (only name, not content): + +``` +BasicRule wl:1000 "mz:ARGS|NAME"; +``` + +### Notes + +- A zone can be suffixed with `|NAME`, meaning the rule matched in the name of the variable, but not its content. +- Both matchzone content and patterns (`rx:`/`str:`) must be in lower-case, as naxsi is case insensitive +- `RAW_BODY` whitelists are written just as any `BODY` whitelist, see [[rulessyntax]] +- A whitelist can't mix `_X` elements with `_VAR` or `$URL` items. ie: + +``` +$URL_X:/foo|$ARGS_VAR:bar : WRONG +$URL_X:^/foo$|$ARGS_VAR_X:^bar$ : GOOD +``` + +### Regex Whitelist Examples + +Available only in [naxsi 0.52]( https://github.com/nbs-system/naxsi/releases/tag/0.52 ) and later. + +Disable rule `#1000` in all GET arguments containing `meh`: + +``` +BasicRule wl:1000 "mz:$ARGS_VAR_X:meh"; +``` + +Disable rule `#1000` in GET argument named `meh`: + +``` +BasicRule wl:1000 "mz:$ARGS_VAR_X:^meh"; +``` + +Disable rule `#1000` in all GET arguments matching `meh_`: + +``` +BasicRule wl:1000 "mz:$ARGS_VAR_X:^meh_[0-9]+$" +``` \ No newline at end of file diff --git a/dependencies/naxsi/docs/old/libinjection-integration.md b/dependencies/naxsi/docs/old/libinjection-integration.md new file mode 100644 index 0000000..1cc0a13 --- /dev/null +++ b/dependencies/naxsi/docs/old/libinjection-integration.md @@ -0,0 +1,79 @@ +# Libinjection integration + +[libinjection](https://github.com/client9/libinjection) is a 3rd party library (developped by client9) aiming at detecting SQL injections (sqli) and cross-site scripting (xss) by tokenization. This library is integrated within naxsi for two purposes : + - generic detection of xss/sqli + - virtual patching + +### Generic Detection + +libinjection generic detection *must* be explicitely enabled using specific directives : [LibInjectionXss](directives.md#libinjectionxss) or [LibInjectionSql](directives.md#libinjectionsql). It can as well be enabled at runtime using [runtime modifiers](runtime-modifiers.md) : `naxsi_flag_libinjection_xss` and `naxsi_flag_libinjection_sql`. + + * Generic libinjection_xss rule has internal id 18 and increases named score `$LIBINJECTION_XSS` of 8 per match. + + * Generic libinjection_sql rule has internal id 17 and increases named score `$LIBINJECTION_SQL` of 8 per match. + + +A generic setup to block any request triggering libinjection_xss looks like : + +``` +location / { + SecRulesEnabled; + LibInjectionXss; + CheckRule "$LIBINJECTION_XSS >= 8" BLOCK; +... +} +``` + +for libinjection_sql : +``` +location / { + SecRulesEnabled; + LibInjectionSql; + CheckRule "$LIBINJECTION_SQL >= 8" BLOCK; +... +} +``` + +When generic detection is enabled, false positives can be whitelisted using id 17 ([libinjection_xss](internal-rules.md#libinjection_xss)) or 18 ([libinjection_sql](internal-rules.md#libinjection_sql)). + + +Using runtime modifiers, it might look like : + + +``` +#/foobar as LOTS of sql injections +if ($request_uri ~ ^/foobar(.*)$ ) { + set $naxsi_flag_libinjection_sql 1; +} +... +location / { + ... + CheckRule "$LIBINJECTION_SQL >= 8" DROP; + ... +} +``` + + +### Virtual Patching + +(>= 0.55rc2) + +Widely enabling libinjection might not be possible depending on the application context. +However, libinjection can as well be used for virtual patching : + +``` +MainRule "d:libinj_xss" "s:DROP" "mz:$ARGS_VAR:ruuu" id:41231; +``` + + +_Pass the content of GET variable 'ruuu' to libinjection, and drop request if it's detected as xss_ + +``` +MainRule "d:libinj_sql" "s:DROP" "mz:$ARGS_VAR:ruuu" id:41231; +``` + +_DROP any request triggering libinjection_sql in GET variable 'ruuu'_ + + +Using virtual patching approach, user-created rules can be managed/whitelisted without specificities. + diff --git a/dependencies/naxsi/docs/old/matchzones-bnf.md b/dependencies/naxsi/docs/old/matchzones-bnf.md new file mode 100644 index 0000000..76d04aa --- /dev/null +++ b/dependencies/naxsi/docs/old/matchzones-bnf.md @@ -0,0 +1,89 @@ +## Match Zones + +Match Zones *mz* are present in rules and whitelists. It is used to specify where a pattern should be searched (rules) or where it should be allowed (whitelist). +Please note that matchzones behave a bit differently in rules and whitelists : In rules each condition is *OR* (ie. in `BODY` _or_ in `HEADERS`), +while in whitelist it's *AND* (ie. url must be `/foo` _and_ exception must happen in `ARGS`) + +### Global Zones + +4 main zones exist : URL, ARGS, HEADERS, BODY, and matchzone can be more or less restrictive. + +A mz can be wide : + +- `ARGS`: GET args +- `HEADERS `: HTTP Headers +- `BODY `: POST args (and RAW_BODY) +- `URL`: The URL itself (before '?') +- `ALL`: TODO DOCUMENTATION + +Or more specific : + +- `$ARGS_VAR:string`: named GET argument +- `$HEADERS_VAR:string` : named HTTP header +- `$BODY_VAR:string`: named POST argument + +Sometime, regular expressions are needed (ie. variable names can vary) : + +- `$HEADERS_VAR_X:regex`: regex matching a named HTTP header (>= 0.52) +- `$ARGS_VAR_X:regex`: regex matching the name of a GET argument (>= 0.52) +- `$BODY_VAR_X:regex`: regex matching the name of a POST argument (>= 0.52) + +A matchzone can be restricted to a specific URL : +(_but is not a zone on its own_) + +- `$URL:string`: restricted to this url +- `$URL_X:regex`: restricted to url matching regex (>= 0.52) + + +A matchzone that targets BODY,HEADERS,ARGS can add `|NAME` to *specify* the target is not +the content of a variable, but its name itself. + +It is useful in specific contexts (ie. whitelist `[ ]` in form var names on url /foo) + +`BasicRule id:1310,1311 "mz:$URL:/foo|BODY|NAME";` + + +more specific, match-zones : +- `FILE_EXT`: Filename (in a multipart POST containing a file) +- `RAW_BODY`: A raw, unparsed representation of the BODY of a http request (>= 0.55rc0) + + + +### Match Zone + +A matchzone is a combination of one or several zone with an optional url. + +In most situations, variable name and url can be predicted, and a static mz can be created : + +![StaticMatchZone](Images/mz_str.png) + +When regular expressions are needed : + +![StaticMatchZone](Images/mz_rx.png) + +*note:* You CANNOT mix regex (`$URL_X`) and static (`$ARGS_VAR`) in a rule. + +*$URL* and *$URL_X* are only used to restrict the scope of a matchzone, and are not specifying the zone. + +### Whitelists matchzones + +In whitelist context, *all* conditions must be satisfied : + +`BasicRule wl:X "mz:$ARGS_VAR:foo|$URL:/bar";` \ +_id X is whitelisted in GET variable 'foo' on URL '/bar'_ + +### Rules matchzones + +In rules context, `$URL` or `$URL_X` *must* be satisfied if present. Any other condition is treated as *OR* (opposite to whitelists). + +`BasicRule str:Y id:X "mz:ARGS|BODY";` +_pattern 'Y' will be matched against *any* GET and POST arguements_ + +`BasicRule str:Y id:X "mz:ARGS|BODY|$URL:/foo";` +_pattern 'Y' will be matched against *any* GET and POST arguements as long as URL is /foo_ + +### Regex vs String + +Matchzones composed of static (`$*_VAR:` `$URL:`) matchzones are stored in hashtables, and thus optimal. +Regex matchzones (`$*_VAR_X:` `$URL_X:`) require more runtime processing. +It is *not* possible to mix static and regex matchzone in a same rule/whitelist : `mz:$ARGS_VAR_X:^foo$|$URL:/x` or `mz:$URL_X:/foo|$ARGS_VAR:x` are wrong. diff --git a/dependencies/naxsi/docs/old/naxsi-compile.md b/dependencies/naxsi/docs/old/naxsi-compile.md new file mode 100644 index 0000000..06e5a1e --- /dev/null +++ b/dependencies/naxsi/docs/old/naxsi-compile.md @@ -0,0 +1,202 @@ +*Note: This process is intended to run on a fully up-to-date Debian Stretch, that follows [installation best practices](https://www.ssi.gouv.fr/guide/recommandations-de-securite-relatives-a-un-systeme-gnulinux/)* + +### Build dependencies + +- GCC +- make +- nginx :) +- libpcre3-dev + +### Get naxsi + +You can download naxsi from the releases page [here](https://github.com/wargio/naxsi/releases) +Get the latest release source code and the corresponding signature file : + +```shell +usr@008885ac189c:~$ export NAXSI_VER=1.3 +usr@008885ac189c:~$ wget https://github.com/wargio/naxsi/releases/download/$NAXSI_VER/naxsi-$NAXSI_VER-src-with-deps.tar.gz -O naxsi-$NAXSI_VER-src-with-deps.tar.gz +``` + +### Get Nginx + +Next, you need to get the source code for the nginx version you are running (in this example, we are using the nginx from the debian stretch repository) : + +```shell +usr@008885ac189c:~$ export NGINX_VER=X.YY.Z +usr@008885ac189c:~$ wget https://nginx.org/download/nginx-$NGINX_VER.tar.gz +usr@008885ac189c:~$ wget https://nginx.org/download/nginx-$NGINX_VER.tar.gz.asc +usr@008885ac189c:~$ gpg --recv-key 520A9993A1C052F8 +usr@008885ac189c:~$ gpg --verify nginx-$NGINX_VER.tar.gz.asc +usr@008885ac189c:~$ rm nginx-$NGINX_VER.tar.gz.asc +``` + +If the signature fails, check that both files have been correctly downloaded and are not corrupted. + +### Build naxsi as a dynamic extension + +First, extract the source code : +```shell +usr@008885ac189c:~$ mkdir -p naxsi-$NAXSI_VER +usr@008885ac189c:~$ tar -C naxsi-$NAXSI_VER -xzf naxsi-$NAXSI_VER-src-with-deps.tar.gz +usr@008885ac189c:~$ tar vxf nginx-$NGINX_VER.tar.gz +usr@008885ac189c:~$ cd nginx-$NGINX_VER +usr@008885ac189c:~/nginx-X.YY.Z$ ./configure --add-dynamic-module=../naxsi-$NAXSI_VER/naxsi_src/ +usr@008885ac189c:~/nginx-X.YY.Z$ make modules +``` +The resulting `ngx_http_naxsi_module.so` will be located in the `objs` directory. +Copy it to your nginx server, in `/etc/nginx/modules/`. +Also copy `naxsi_core.rules` to `/etc/nginx/`. + + +### Build naxsi as a dynamic extension for nginx from your distribution package (i.e Ubuntu) + +You need to build the module with the same flags as your NGINX server package was compiled for example via `apt-get source nginx` + +Execute this to list them: +```shell +usr@008885ac189c:~$ nginx -V +``` +Then pass them to `./configure`. + +```shell +usr@008885ac189c:~/nginx-X.YY.Z$ ./configure --add-dynamic-module=../naxsi-$NAXSI_VER/naxsi_src/ +usr@008885ac189c:~/nginx-X.YY.Z$ make modules +``` +This will ensure module will be compatible with your nginx and will load properly. + + +### Basic setup + +#### Main configuration + +You need to tell nginx to load the naxsi module and naxsi core rules (if you don't load them, naxsi will block every requests) : + +```shell +usr@008885ac189c:~$ cat /etc/nginx/nginx.conf +... +load_module /etc/nginx/modules/ngx_http_naxsi_module.so; # load naxsi + +http { + include /etc/nginx/naxsi_core.rules; # load naxsi core rules + ... +} +... + +``` + +Naxsi works on a per-location basis, meaning you can only enable it inside a location : +```python +server { +... + + location / { # naxsi is enabled, and in learning mode + + SecRulesEnabled; #enable naxsi + LearningMode; #enable learning mode + LibInjectionSql; #enable libinjection support for SQLI + LibInjectionXss; #enable libinjection support for XSS + + DeniedUrl "/RequestDenied"; #the location where naxsi will redirect the request when it is blocked + CheckRule "$SQL >= 8" BLOCK; #the action to take when the $SQL score is superior or equal to 8 + CheckRule "$RFI >= 8" BLOCK; + CheckRule "$TRAVERSAL >= 5" BLOCK; + CheckRule "$UPLOAD >= 5" BLOCK; + CheckRule "$XSS >= 8" BLOCK; + + + proxy_pass http://127.0.0.1; + .... + } + + location /admin { # naxsi is disabled + + SecRulesDisabled; #optional, naxsi is disabled by default + + allow 1.2.3.4; + deny all; + proxy_pass http://127.0.0.1; + .... + } + + location /vuln_page.php { # naxsi is enabled, and is *not* in learning mode + + SecRulesEnabled; + proxy_pass http://127.0.0.1; + } + + location /RequestDenied { + internal; + return 403; + } +... + +} +``` + +#### Whitelist + +As naxsi uses a whitelist approach, a lot of false positives may be generated, potentially dropping legitimate requests. +To prevent this, whitelists must be written (either manually or with [nx-tool](https://github.com/nbs-system/nxtool-ng)). +For example, if you have an e-commerce website that sells furniture, people will be likely to search for something like `table`. Unfortunately, `table` is also a SQL keyword, which will trigger naxsi. +To prevent this, you can write a whitelist telling naxsi to allow the `table` keyword in the search form (assuming the search form in on `/search`) : + +```python +server { + + location / { + SecRulesEnabled; #enable naxsi + LearningMode; #enable learning mode + LibInjectionSql; #enable libinjection support for SQLI + LibInjectionXss; #enable libinjection support for XSS + + DeniedUrl "/RequestDenied"; #the location where naxsi will redirect the request when it is blocked + CheckRule "$SQL >= 8" BLOCK; #the action to take when the $SQL score is superior or equal to 8 + CheckRule "$RFI >= 8" BLOCK; + CheckRule "$TRAVERSAL >= 5" BLOCK; + CheckRule "$UPLOAD >= 5" BLOCK; + CheckRule "$XSS >= 8" BLOCK; + + BasicRule wl:1000 "mz:$URL:/search|$ARGS_VAR:q"; + proxy_pass http://127.0.0.1; + .... + + } + +} +``` + +See [here](whitelists-bnf.md) and [here](whitelists-examples.md) for more informations about whitelists. + +#### Blacklist + +You can also create blacklist with naxsi, allowing you to drop requests even when in learning mode. +Let's imagine a PHP script (`/vuln_page.php`) vulnerable to an unquoted SQLI in the `id` parameter, a typical exploitation would look like this : +``` +GET /vuln_page.php?id=1'+or+1=1/* +``` +You can use naxsi to virtually patch this vulnerabilty by adding a blacklist denying every requests on `/vuln_page.php` where the `id` parameter contains anything other than a number (in this example, the blacklist will only apply to the `/` location, you can use `MainRule` and put it outside in the `http` block to make it global): + +```python +server { + + location / { + SecRulesEnabled; #enable naxsi + LearningMode; #enable learning mode + LibInjectionSql; #enable libinjection support for SQLI + LibInjectionXss; #enable libinjection support for XSS + + DeniedUrl "/RequestDenied"; #the location where naxsi will redirect the request when it is blocked + CheckRule "$SQL >= 8" BLOCK; #the action to take when the $SQL score is superior or equal to 8 + CheckRule "$RFI >= 8" BLOCK; + CheckRule "$TRAVERSAL >= 5" BLOCK; + CheckRule "$UPLOAD >= 5" BLOCK; + CheckRule "$XSS >= 8" BLOCK; + + BasicRule id:4242 "mz:$URL:/vuln_page.php|$ARGS_VAR:id" "rx:[^\d]+" "s:DROP" "msg:blacklist for SQLI in /vuln_page.php"; + proxy_pass http://127.0.0.1; + .... + + } + +} +``` diff --git a/dependencies/naxsi/docs/old/naxsi-setup.md b/dependencies/naxsi/docs/old/naxsi-setup.md new file mode 100644 index 0000000..befe876 --- /dev/null +++ b/dependencies/naxsi/docs/old/naxsi-setup.md @@ -0,0 +1,147 @@ +# Basic Setup + + +### Architecture of naxsi configuration + + * **http {}** level : `include naxsi_core.rules` + * **server {}** level : + * [Dynamic modifiers](runtime-modifiers.md) + * **location {}** level : + * [Enabled/Disabled directives](directives.md#secrulesenabled) + * [LearningMode-related directives](directives.md#learningmode) + * [Whitelists](whitelists-bnf.md) + * [CheckRules](checkrules-bnf.md) + * [RequestDenied](requestdenied-bnf.md) + * **location /RequestDenied** + * return HTTP error code, post-processing ... + + +### Example configuration + +``` +#Only for nginx's version with modular support +load_module /../modules/ngx_http_naxsi_module.so; +events { + ... +} +http { + include /tmp/naxsi_ut/naxsi_core.rules; + ... + server { + listen ...; + server_name ...; + location / { + #Enable naxsi + SecRulesEnabled; + #Enable learning mode + LearningMode; + #Define where blocked requests go + DeniedUrl "/50x.html"; + #CheckRules, determining when naxsi needs to take action + CheckRule "$SQL >= 8" BLOCK; + CheckRule "$RFI >= 8" BLOCK; + CheckRule "$TRAVERSAL >= 4" BLOCK; + CheckRule "$EVADE >= 4" BLOCK; + CheckRule "$XSS >= 8" BLOCK; + #naxsi logs goes there + error_log /.../foo.log; + ... + } + error_page 500 502 503 504 /50x.html; + #This is where the blocked requests are going + location = /50x.html { + return 418; #I'm a teapot \o/ + } + } +} +``` + +### Next steps + +The next step is learning; however, before jumping there, ensure that you have: + * A nginx as a webserver or reverse proxy + * Naxsi installed and running in learning mode + * If you perform a request such as `curl 'http://127.0.0.1:4242/?a=<>'`, you should see a [NAXSI_FMT](naxsilogs.md#naxsi_fmt) in your logs : + `2016/07/12 13:27:04 [error] 14492#0: *1 NAXSI_FMT: ip=127.0.0.1&server=127.0.0.1&uri=/&learning=1&vers=0.55rc2&total_processed=1&total_blocked=1&block=1&cscore0=$XSS&score0=16&zone0=ARGS&id0=1302&var_name0=a&zone1=ARGS&id1=1303&var_name1=a, client: 127.0.0.1, server: localhost, request: "GET /?a=<> HTTP/1.1", host: "127.0.0.1:4242"` + + +### Learning, log-injection, ElasticSearch, Kibana + +The ElasticSearch/Kibana part is optional but provides a great comfort and way to visualize "what's going on". + +![Global Workflow](Images/naxsi-workflow.png) + + +### Components + +Nxtool setup can be found here: +(_tl;dr: python setup.py install, or `./nxtool.py -c nxapi.json -x`_) + * [nxapi documentation](https://github.com/nbs-system/naxsi/tree/master/nxapi#prequisites) + +Kibana (v4 as of this writing) can be downloaded here: + * [kibana website](https://www.elastic.co/downloads/kibana) + +Once those two components are setup, you should be able to inject naxsi logs into ElasticSearch with NxTool. +Here is an example of what it might look like in production: + +![Kibana Dashboard](Images/kibana.png) + + + +### Configuration - NXTOOL + +As stated in dedicated documentation, nxtool comes with a `json` file specifying ES location, index etc. + +``` +"elastic" : { + "host" : "127.0.0.1:9200", + "index" : "nxapi", + "doctype" : "events", + "default_ttl" : "7200", + "max_size" : "1000", + "version" : "2" +}, +``` + +Once configured and running on the same host as nginx, you can start injecting logs into ES: + +`nxtool.py --fifo /tmp/naxsi_pipe --no-timeout` +_(here, nginx is being told to write logs to /tmp/naxsi_pipe which is a FIFO created by nxtool)_ + +### Configuration - Kibana + +Now, you should be able to configure Kibana to setup a dashboard to visualize your naxsi data. + +This step is left as an exercise for the reader, see +[Creating Kibana Dashboard](https://www.elastic.co/guide/en/kibana/current/dashboard.html). + + + +### Configuration - DataDog + +Golden Setup + +Blacklisting = mod_security + +WAF = naxsi + +https://gist.github.com/marcinguy/3a106991d3a84995efacc473f8db21a9 + +You can get logs to DataDog very easily using this Grok rule: + +Grok Parser rule +``` +​myParsingrule %{date("yyyy/MM/dd HH:mm:ss"):connect_date} \[%{word:status}\] %{number:id}\#%{number:id2}: \*%{number:value} %{data::json} +``` + +Then you will see a nice Dashboard of Attacks + +[[https://user-images.githubusercontent.com/20355405/90318948-4c52a700-df34-11ea-8521-259551b5322e.png]] + +You can also send alerts to Slack: + +[[https://user-images.githubusercontent.com/20355405/92943641-52fd0d00-f453-11ea-99ee-411d9ea33105.png]] + +You just built an Open Source WAF solution with Alerts and Dashboard. + + diff --git a/dependencies/naxsi/docs/old/naxsilogs.md b/dependencies/naxsi/docs/old/naxsilogs.md new file mode 100644 index 0000000..9fd2196 --- /dev/null +++ b/dependencies/naxsi/docs/old/naxsilogs.md @@ -0,0 +1,61 @@ +### NAXSI_FMT + +NAXSI_FMT are outputed by naxsi in your errorlog : + +``` +2013/11/10 07:36:19 [error] 8278#0: *5932 NAXSI_FMT: ip=X.X.X.X&server=Y.Y.Y.Y&uri=/phpMyAdmin-2.8.2/scripts/setup.php&learning=0&vers=0.52&total_processed=472&total_blocked=204&block=0&cscore0=$UWA&score0=8&zone0=HEADERS&id0=42000227&var_name0=user-agent, client: X.X.X.X, server: blog.memze.ro, request: "GET /phpMyAdmin-2.8.2/scripts/setup.php HTTP/1.1", host: "X.X.X.X" +``` + +Here, client `X.X.X.X` request to server `Y.Y.Y.Y` did trigger the rule `42000227` in the var named `user-agent` in the`HEADERS` zone. `id X` might seem obscure, but you can see the meaning in [naxsi_core.rules]( https://github.com/wargio/naxsi/blob/main/naxsi_rules/naxsi_core.rules ): + +``` +MainRule "str:<" "msg:html open tag" "mz:ARGS|URL|BODY|$HEADERS_VAR:Cookie" "s:$XSS:8" id:1302; +``` + +NAXSI_FMT is composed of different items : + +- `ip` : Client's ip +- `server` : Requested Hostname (as seen in http header `Host`) +- `uri`: Requested URI (without arguments, stops at `?`) +- `learning`: tells if naxsi was in learning mode (0/1) +- `vers` : Naxsi version, only since [0.51]( https://github.com/wargio/naxsi/tree/0.51 ) +- `total_processed`: Total number of requests processed by nginx's worker +- `total_blocked`: Total number of requests blocked by (naxsi) nginx's worker +- `zoneN`: Zone in which match happened (see "Zones" in the table below) +- `idN`: The rule id that matched +- `var_nameN`: Variable name in which match happened (optional) +- `cscoreN` : _named_ score tag +- `scoreN` : associated _named_ score value + +Several groups of zone, id, var_name, cscore and score can be present in a single line. + +### NAXSI_EXLOG + +NAXSI_EXLOG is a complement to [[naxsilogs.md]]. Along with exceptions, it contains actual content of the matched request. While NAXSI_FMT only contains IDs and location of exception, NAXSI_EXLOG provides actual content, allowing you to easily decide if it's a false positive or not. + +Learning tools uses this at his advantage. Extensive log is enabled by adding the following line in your server {} section but **out** of your location. + +```javascript +set $naxsi_extensive_log 1; +``` + +This feature is provided by [[runtime-modifiers]]. + +``` +2013/05/30 20:47:05 [debug] 10804#0:*1 NAXSI_EXLOG: ip=127.0.0.1&server=127.0.0.1&uri=/&id=1302&zone=ARGS&var_name=a&content=a<>bcd +2013/05/30 20:47:05 [error] 10804#0:*1 NAXSI_FMT: ip=127.0.0.1&server=127.0.0.1&uri=/&learning=0&vers=0.50&total_processed=1&total_blocked=1&zone0=ARGS&id0=1302&var_name0=a, client: 127.0.0.1, server: , request: "GET /?a=a<>bcd HTTP/1.0", host: "127.0.0.1" +``` + +### Naxsi Internal IDs + +"User defined" rules are supposed to have IDs > `1000`. + +IDs inferior `1000` are reserved for [naxsi internal rules](internal-rules.md), which are usually related to protocol sanity and things that cannot be expressed through regular expressions or string matches. + +Think twice before whitelisting one of those IDs, as it might partially/totally disable naxsi. + +### Naxsi JSON Logs + +TODO DOCUMENTATION + +[directives.md#naxsi_json_log](directives) diff --git a/dependencies/naxsi/docs/old/rawbody.md b/dependencies/naxsi/docs/old/rawbody.md new file mode 100644 index 0000000..1e8d163 --- /dev/null +++ b/dependencies/naxsi/docs/old/rawbody.md @@ -0,0 +1,39 @@ +# Raw body + +RAW_BODY (>= 0.55rc0) is a feature to allow naxsi to match patterns in content it doesn't know to parse. + +As stated in [internal rules](internal-rules.md), naxsi will bail out when it doesn't know content-type. If id:11 [bad content-type](internal-rules.md#uncommon_content_type) is whitelisted, then naxsi will go onto proceed all rules that are targeting `RAW_BODY`. + +ie. configuration : + +``` +http { +... +MainRule "id:4241" "s:DROP" "str:RANDOMTHINGS" "mz:RAW_BODY"; +... + +location / { + ... + BasicRule wl:11 "mz:$URL:/|BODY"; + ... +} +... +``` + +ie. request : +``` +POST / ... +Content-Type: RAFARAFA +... + + +RANDOMTHINGS + +``` + +Then rule 4241 will trigger. However, if `id:11` was not whitelisted, then rule 4241 wouldn't be proceed. + +### Specifics + +Before being passed on to raw_body parsing, all null bytes are replaced with actual 0's. + diff --git a/dependencies/naxsi/docs/old/requestdenied-bnf.md b/dependencies/naxsi/docs/old/requestdenied-bnf.md new file mode 100644 index 0000000..87a0216 --- /dev/null +++ b/dependencies/naxsi/docs/old/requestdenied-bnf.md @@ -0,0 +1,16 @@ +# DeniedUrl + +DeniedUrl is used to indicate a location where blocked requests will be redirected (internally). + +In version before 0.49, by default, naxsi forwards blocked request there while in learning mode. Upon "real" request termination, using nginx's post_action mechanism. + +This was due to usage of nx_intercept, which could intercept learning traffic in live. + +As the request might be modified during redirect (url & arguments), extra http headers orig_url (original url), orig_args (original GET args) and naxsi_sig (NAXSI_FMT) are added. + +If $naxsi_flag_post_action is set to "1", naxsi will perform post_action (while in learning) even in versions '''> 0.49'''. + +The headers that are forwarded to the location denied page are : + * Naxsi orig url : x-orig_url header + * Naxsi orig args : x-orig_args header + * Naxsi orig sig : x-naxsi_sig header diff --git a/dependencies/naxsi/docs/old/rules-bnf.md b/dependencies/naxsi/docs/old/rules-bnf.md new file mode 100644 index 0000000..39f1197 --- /dev/null +++ b/dependencies/naxsi/docs/old/rules-bnf.md @@ -0,0 +1,90 @@ +# Rules + +Rules are meant to search for patterns in parts of a request to detect attacks. + +ie. DROP any request containing the string 'zz' in *any* GET or POST argument : +`MainRule id:424242 "str:zz" "mz:ARGS|BODY" "s:DROP";` + +Rules can be present at `location` level (`BasicRule`) or at `http` level (`MainRule`). + +Rules have the following schema : + +![Rule](Images/rule.png) + +Everything must be quoted with double quotes, except the id part. + +### ID (id:...) + +`id:num` is the *unique* numerical ID of the rule, that will be used in `NAXSI_FMT` or whitelists. + +IDs inferior to `1000` are reserved for naxsi internal rules (protocol mismatch etc.) + +### Match Pattern + +![Sig-Digram](Images/pattern.png) + +Match pattern can be a regular expression, a string match, or a call to a lib (libinjection) : + +* `rx:foo|bar` : will match `foo` or `bar` +* `str:foo|bar` : will match `foo|bar` +* `d:libinj_xss` : will match if libinjection says it's XSS (**>= 0.55rc2**) +* `d:libinj_sql` : will match if libinjection says it's SQLi (**>= 0.55rc2**) + +Using plain string match when possible is recommended, as it's way faster. +All strings *must* be lowercase, since naxsi's matches are case insensitive. + +### Score (s:...) + +![Score-Diagram](Images/score.png) + +**s** is the score section. You can create "named" counters: `s:$FOOBAR:4` will increase counter `$FOOBAR` value by 4. One rule can increase several scores: `s:$FOO:4,$BAR:8` will increase both `$FOO` by 4 and `$BAR` by 8. +A rule can as well directly specifiy an action such a BLOCK (blocks the request in non-learning mode) or DROP (blocks the request **even** in learning mode) +Named scores are later handled by [CheckRules](checkrules-bnf.md). + +### MatchZone (mz:...) + +Please refer to [Match Zones](matchzones-bnf.md) for details. + +**mz** is the match zone, defining which part of the request will be inspected by the rule. + +In rules, all matchzones but `$URL*:` are treated as *OR* conditions : + +`MainRule id:4242 str:z "mz:$ARGS_VAR:X|BODY";` + +pattern 'z' will be searched in GET var 'X' and *all* BODY vars. + +`MainRule id:4242 str:z "mz:$ARGS_VAR:X|BODY|$URL_X:^/foo";` + +pattern 'z' will be searched in GET var 'X' and all BODY vars *as long as* URL starts with `/foo`. + +Starting from naxsi **0.55rc0**, for unknown content-types, you can use the `RAW_BODY` match-zone. `RAW_BODY` rules looks like that: + +``` +MainRule id:4241 s:DROP str:RANDOMTHINGS mz:RAW_BODY; +``` + +Rules in the `RAW_BODY` zone will only applied when: + - The *Content-type* is unknown (which means naxsi doesn't know how to properly parse the request) + - `id 11` (which is the internal blocking rule for 'unknown content-type') is whitelisted. + +Then, the full body (url decoded and with null-bytes replaced by '0') is passed to this set of rules. +The full body is matched again the regexes or string matches. + +Whitelists for `RAW_BODY` rules are actually written just like normal body rules, such as: + +``` +BasicRule wl:4241 "mz:$URL:/rata|BODY"; +``` + +### Human readable message (msg:...) + +**msg** is a string describing the pattern. This is mostly used for analyzing and to have some human-understandable text. + +### Negative Keyword (negative) + +**negative** is a keyword that can be used to make a negative rule. +Score is applied when the rule doesn't match : + +``` +MainRule negative "rx:multipart/form-data|application/x-www-form-urlencoded" "msg:Content is neither mulipart/x-www-form.." "mz:$HEADERS_VAR:Content-type" "s:$EVADE:4" id:1402; +``` diff --git a/dependencies/naxsi/docs/old/rules-examples.md b/dependencies/naxsi/docs/old/rules-examples.md new file mode 100644 index 0000000..7991d0a --- /dev/null +++ b/dependencies/naxsi/docs/old/rules-examples.md @@ -0,0 +1,124 @@ +Go to [Rules Explanation](rules-bnf.md) + + + * [generic rules](#generic-rules) + * [Blocking "bad" user agents](#blocking-bad-user-agents) + * [Blocking "bad" referers](#blocking-bad-referers) + * [Blocking dangerous directories](#blocking-dangerous-directories) + * [Virtual patching : Simple/Generic XSS](#simplegeneric-xss) + * [Virtual patching : Simple/Generic (wider) XSS](#simplegeneric-wider-xss) + * [Virtual patching : Simple/Generic File Upload](#simplegeneric-file-upload) + * [Raw Body rules](#raw-body) + * [LibInjection (XSS) Virtual Patching (>= 0.55rc1)](#libinjection-xss-virtual-patching) + * [LibInjection (SQL) Virtual Patching (>= 0.55rc1)](#libinjection-sql-virtual-patching) + * [Negative URL rule](#negative-rule) + + +## 'generic' rules + +Search for string `0x` in any POST/PUT arg, any part of the URL, any GET arg, or the HTTP header named `cookie` (extracted from naxsi_core.rules). If rule matches, `$SQL` score is increased by 2. Rule can be whitelisted via id `1002`. + +``` +MainRule "str:0x" "msg:0x, possible hex encoding" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:2" id:1002; +``` + +## Practices + +Sometime, you can write rules to enforce best practices or simply to deter automated attacks. + + +### Blocking "bad" user agents +``` +MainRule "str:w3af.sourceforge.net" "msg:DN SCAN w3af User Agent" "mz:$HEADERS_VAR:User-Agent" "s:$UWA:8" id:42000041 ; +``` + +Block w3af user-agent (http://w3af.org). + + +### Blocking "bad" referers + +``` +BasicRule "str:http://www.shadowysite.com/" "msg:Bad referer" "mz:$HEADERS_VAR:referer" "s:DROP" id:20001; +``` + + +### Blocking dangerous directories + +ie. following [CVE-2015-2067](http://cve.circl.lu/cve/CVE-2015-2067) on magento's plugin "magmi", you want to block access to the plugin : + +``` +MainRule "str:/magmi/" "msg:Access to magmi folder" "mz:URL" "s:$UWA:8" id:42000400; +MainRule "str:/magmi.php" "msg:Access to magmi.php" "mz:URL" "s:$UWA:8" id:42000401; +``` + +## Vpatching Examples + +Virtual patching usually aims at protecting a vulnerable software from exploitation. + +### Simple/Generic XSS + +There is a reflected XSS in GET variable "foo" on URL "/target" : + +``` +MainRule id:4242 "str:<" "msg:xss (angle bracket)" "mz:$ARGS_VAR:foo|$URL:/target" s:DROP; +``` + +This rule will stop any request containing the character '<' at the targeted location. + + +### Simple/Generic (wider) XSS + +There is a reflected XSS in GET variable "foo" on all product URLs : + +``` +MainRule id:4242 "str:<" "msg:xss (angle bracket)" "mz:$ARGS_VAR_X:^foo$|$URL_X:^/product/[0-9]+/product$" s:DROP; +``` + + +### Simple/Generic File Upload + +Blocking asp/php file upload (part of core rules). Increases `$UPLOAD` by 8 if the string uploaded file names contains `ph` (.php / .pht ...) `.asp` or `.ht` (.htaccess ...). + +``` +MainRule "rx:\.ph|\.asp|\.ht" "msg:asp/php file upload!" "mz:FILE_EXT" "s:$UPLOAD:8" id:1500; +``` + + +### Raw Body + +Raw Body zone is meant for the content-types that naxsi can't parse (XML, java serialized objects, unorthodox developments). +See [RAW_BODY](rawbody.md) for details on RAW_BODY behaviour. + +``` +MainRule "id:4241" "s:DROP" "str:RANDOMTHINGS" "mz:RAW_BODY"; +``` + +### LibInjection (XSS) Virtual Patching + +(>= 0.55rc1) + +Will drop any request for which libinjection detects content of GET var `foo` as an XSS. + +``` +MainRule "id:4241" "s:DROP" "d:libinj_xss" "mz:$ARGS_VAR:foo"; +``` + +### LibInjection (SQL) Virtual Patching + +(>= 0.55rc1) + +Will drop any request for which libinjection detects content of GET var `foo` as an SQLi. + +``` +MainRule "id:4241" "s:DROP" "d:libinj_sql" "mz:$ARGS_VAR:foo"; +``` + +### Negative rule + +Will drop any request for which the URL doesn't start with "/rest/" + +``` +MainRule "id:4241" negative "s:DROP" "rx:^/rest/" "mz:URL"; +``` + + diff --git a/dependencies/naxsi/docs/old/runtime-modifiers.md b/dependencies/naxsi/docs/old/runtime-modifiers.md new file mode 100644 index 0000000..b0a5842 --- /dev/null +++ b/dependencies/naxsi/docs/old/runtime-modifiers.md @@ -0,0 +1,135 @@ +# naxsi dynamic configuration (aka nginx vars) + +Since `0.49`, naxsi supports a limited set of variables that can override or modify its behavior. + + * `naxsi_flag_learning` : If present, this variable will override naxsi learning flag ("0" to disable learning, "1" to enable it). + * `naxsi_flag_post_action` : If present and set to "0" this variable may be used to disable post_action in learning mode. + * `naxsi_flag_enable` : If present, this variable will override naxsi's "SecRulesEnabled" ("0" to disable naxsi, "1" to enable). + * `naxsi_extensive_log` : If present (and set to "1"), this variable will force naxsi to log the CONTENT of variable matching rules (see notes at bottom). + +Since `0.54`, naxsi as well support libinjection enable/disable flags at runtime + * `naxsi_flag_libinjection_sql` + * `naxsi_flag_libinjection_xss` + +Since `0.56`, naxsi as well support JSON output from blocks/events with enable/disable flags at runtime + * `naxsi_json_log` + +### Gentle reminder +It is important to know that naxsi operates at the REWRITE phase of nginx. Thus, setting those variables directly in the location where naxsi is present is ineffective (as naxsi will be called before variable set is effective). + +This is correct: + +``` + set $naxsi_flag_enable 0; + location / { + ... + } +``` + +But this is *wrong*: +``` + location / { + set $naxsi_flag_learning 1; + ... + } +``` + +With that said, you can use the power of nginx, lua, etc. to change naxsi's behavior. The presence of these variables will enable/disable learning mode, naxsi itself or force extensive logging. +You can thus do things naxsi is usually not able to, like modifying its behavior according to (nginx) variables set at run-time : + +``` + # Disable naxsi if client ip is 127.0.0.1 + if ($remote_addr = "127.0.0.1") { + set $naxsi_flag_enable 0; + } +``` + + +Those variables can as well be set from lua scripts (see nginx's mod_lua). + +### naxsi_flag_learning + +If `naxsi_flag_learning` variable is present, this value will override naxsi's current static configuration regarding learning mode. + +``` + if ($remote_addr = "1.2.3.4") { + set $naxsi_flag_learning 1; + } + location / { + ... + } +``` + + +### naxsi_flag_post_action + +[post_action](http://wiki.nginx.org/HttpCoreModule#post_action) can be used by naxsi to literally forward a request to the [DeniedUrl](directives.md#deniedurl) location. It is on by default until naxsi 0.50 (a souvenir from ̀nx_intercept`) and is off by default since 0.51, because of the switch to [nxtool](https://github.com/nbs-system/naxsi/tree/master/nxapi). +Using this might lead to unpredictable behavior +Can be set to 0 or 1 + +### naxsi_flag_enable + +If `naxsi_flag_enable` variable is present and set to 0, naxsi will be disabled in this request. This allows you to partially disable naxsi in specific conditions. +To completely disable naxsi for "trusted" users : + +``` + set $naxsi_flag_enable 0; + location / { + ... + } +``` + +### naxsi_extensive_log + +If present (and set to “1”), this variable will force naxsi to log the CONTENT of variable matching rules. +Because of a potential impact on performance, use this with caution. Naxsi will log those to nginx’s `error_log`, ie: + +``` + NAXSI_EXLOG: ip=%V&server=%V&uri=%V&id=%d&zone=%s&var_name=%V&content=%V +``` + +See [naxsi logs](naxsilogs.md) for more details. + + +### naxsi_flag_libinjection_sql + +If set to "1", naxsi will pass every parsed content to [libinjection](libinjection-integration.md) and ask for SQL injection detection. +If the libinjection matches, internal rule [libinjection_sql is fired ](internal-rules.md#libinjection_sql). + +### naxsi_flag_libinjection_xss + +If set to "1", naxsi will pass every parsed content to [libinjection](libinjection-integration.md) and ask for XSS detection. +If the libinjection matches, internal rule [libinjection_xss is fired ](internal-rules.md#libinjection_xss). + + +### naxsi_json_log + +If present (and set to “1”), this variable will force naxsi to log in JSON format of events/blocks. +JSON output will be limited to 1948, if it will be more to log, second entry (multiline log) will be empty JSON. Makes no sense to connect big JSONs on multiline. + +So if a multiline event is made, I send an empty JSON. You cannot connect JSON across logs lines, this would be very difficult for JSON parsing. + +I think this will help in most of cases. + +Multiline log example: + +``` +2020/07/22 09:24:57 [error] 14714#0: *1 NAXSI_FMT: ip=127.0.0.1&server=localhost&uri=/&vers=0.56&total_processed=1&total_blocked=1&config=learning&cscore0=$SQL&score0=630&zone0=ARGS&id0=1998&var_name0=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1&zone1=ARGS&id1=1998&var_name1=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2&zone2=ARGS&id2=1998&var_name2=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa3&zone3=ARGS&id3=1998&var_name3=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4&zone4=ARGS&id4=1998&var_name4=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa5&zone5=ARGS&id5=1998&var_name5=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa6&zone6=ARGS&id6=1998&var_name6=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa7&zone7=ARGS&id7=1998&var_name7=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa8&zone8=ARGS&id8=1998&var_name8=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa9&zone9=ARGS&id9=1998&var_name9=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10&zone10=ARGS&id10=1998&var_name10=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa11&zone11=ARGS&id11=1998&var_name11=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa12&zone12=ARGS&id12=1998&var_name12=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa13&seed_start=185, client: 127.0.0.1, server: localhost, request: "GET /?AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +2020/07/22 09:24:57 [error] 14714#0: *1 NAXSI_FMT: seed_end=185&zone13=ARGS&id13=1998&var_name13=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa14&zone14=ARGS&id14=1998&var_name14=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa15, client: 127.0.0.1, server: localhost, request: "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 HTTP/1.1", host: "localhost" +As you can see they're connected by "seed_start" and "seed_end". +``` + +Naxsi will just return empty JSON: + +``` +2020/07/22 09:24:57 [error] 14714#0: *1 { }, client: 127.0.0.1, server: localhost, request: "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 HTTP/1.1", host: "localhost" +2020/07/22 09:24:57 [error] 14714#0: *1 { }, client: 127.0.0.1, server: localhost, request: "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 HTTP/1.1", host: "localhost" +``` + +My use case is DataDog (which parser cannot connect multiple JSON with "seed_start" and "seed_end" values, this would be also very complex to connect and parse in DataDog) + +The typical case should look like this (no Multiline log) + +``` +2020/07/22 09:25:01 [error] 14714#0: *2 { "ip":"127.0.0.1","server":"localhost","uri":"/","vers":"0.56","total_processed":"2","total_blocked":"2","config":"learning","cscore0":"$XSS","score0":"16","zone0":"ARGS","id0":"1302","var_name0":"","zone1":"ARGS","id1":"1303","var_name1":"" }, client: 127.0.0.1, server: localhost, request: "GET /? + +test 5 + +test 6 + +test 7 + +test 8 + +test 9 X + +test 10 + +test 11 + +test 12





...



+ +# opera only, only "DoS" +# test 13 01 + +# opera only, "DoS" +# test 14 + +test 15 + +test 16 X + +test 17 + +test 18 + +# obsolete firefox 3 +# test 19 ¼script ¾alert(1)//¼/script ¾ + +test 20 + +test 21 + +test 22 + +test 23
+ +test 24 1 + +test 25 ;1 + +# obsolete firefox 4 and under +# test 26 +ADw-html+AD4APA-body+AD4APA-div+AD4-top secret+ADw-/div+AD4APA-/body+AD4APA-/html+AD4-.toXMLString().match(/.*/m),alert(RegExp.input); + +test 27 + +test 28 1 + +test 29 @import "data:,*%7bx:expression(write(1))%7D"; + +test 31_1 + +test 31_2 + +test 32
+ +test 33 XXXXXX + +test 34 1 + +test 35 1 + +test 36 XXX + +test 37 + +test 38 + +# obsolete, FF 3.6 and Opera 11 +#test 39_1 + +test 39_2 ><image xlink:href=" + +test 40 + +test 41
  • + +test 42 XXX + +test 43 + +test 44 X + +test 45
    XXX
    + +test 46
    XXX
    + +test 47 + +test 48 + +test 49 + +test 50 + +test 51 + +test 52 + +test 53_1 + +test 53_2 + +test 54 +test 55_2