gggeek / yet-another-waf-core
A php library for building web api firewalls
Requires
- php: ^8.2
- ext-ctype: *
- ext-json: *
- ext-zlib: *
- nyholm/psr7: ^1.8.2
- psr/http-client: ^1.0.3
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0.2
- psr/http-server-middleware: ^1.0.2
- psr/log: ^3.0.2
- symfony/json-path: ^7.4.12
Requires (Dev)
- ext-curl: *
- ext-mbstring: *
- guzzlehttp/guzzle: ^7.13.2
- laminas/laminas-httphandlerrunner: ^2.13.0
- phpunit/phpunit: ^11.5.55|^12.5.29|^13.2.1
- symfony/dotenv: ^v7.4.11|^8.0.11
- symfony/http-client: ^7.4.9
- symfony/psr-http-message-bridge: ^v7.4.8|^8.0.8|^8.10
- yoast/phpunit-polyfills: ^4.0
Suggests
- ext-brotli: Necessary to be able to inspect received brotli-compressed message bodies
- ext-curl: Required (atm at least) for connecting to unix-socket based upstreams and some other nice http features
- ext-zstd: Necessary to be able to inspect received zstd-compressed message bodies
- guzzlehttp/guzzle: Either this or symfony/http-client are required
- symfony/http-client: Either this or guzzlehttp/guzzle are required
Conflicts
- guzzlehttp/guzzle: <7.13.2
- psr/http-factory: <1.1.0
- symfony/http-client: <7.0
This package is auto-updated.
Last update: 2026-07-14 22:47:31 UTC
README
A php library for building Web API Firewalls - and other assorted http proxies.
Primary finished-product targets are forward proxies for filtering the requests and responses of calls to HTTP APIs to only let through what you want to expose.
Example use-cases:
- reducing the surface of an API, eg. only allowing READ requests or access to specific URLs
- removing sensitive data from an API responses
- adding/modifying/removing http headers
- tracing of requests and responses
- rate limiting (not implemented, but should be implementable with existing components from other packages)
- caching (not implemented, but should be implementable with existing components from other packages)
Work In Progress
Working
- Support for Listening on http and on unix sockets
- Matching requests and responses based on htp headers, request/response body and most other HTTP fields
- End-to-end testing of all implemented features using Apache, FrankenPHP, Nginx: locally via a container-based test environment and Continuous Integration on every push to GitHub
In scope (to be implemented)
Main missing features:
- Matching request/response bodies using jsonpath/css/xpath expressions
- Filtering (modification of requests/responses)
- "restart the processing chain" as possible action for matching rules
- HTTPS support
- Documentation
See the Roadmap for a detailed list of features not yet implemented.
Out of scope
Not in scope (yet?):
- a GUI
- dispatching requests to different upstream backends based on conditions
- filtering request/response bodies other than Json
- feature parity with Varnish or performance parity with HAProxy
- using async requests to connect to upstream servers
- implementing rate-limiting, caching with own code (we should allow usage of PSR compliant external code for that)
Requirements:
PHP 8.2 and up, with extension: ctype, curl, json and zlib.
A webserver to run it.
If you want to have the proxy listening on a unix socket instead of an http port, choose an http server which can do that: as of June 2026 Nginx and frankenPHP can, while Apache can't.
Either the symfony/http-client or guzzlehttp/guzzle php package.
The php curl extension is recommended, as it is required for most of the complex http stuff when making requests to
the upstream server.
Installation
Via Composer: composer require gggeek/yet-another-waf-core:dev-main
Then install either symfony/http-client or guzzlehttp/guzzle.
Usage
More examples will come...
For the moment, see projects https://github.com/gggeek/yet-another-docker-socket-proxy and https://github.com/gggeek/yet-another-waf as examples.
Or take a look at the Proxy used for the unit testing suite in ./tests/public
Design principles
- Security first. No requests are allowed by default, everything has to be whitelisted.
- Ease of use. Error messages should be clear and rather verbose than cryptic. Logging facilities should be extensive. Ambiguous configuration should be rejected.
- Flexibility. The proxies should be easy to configure for common scenarios and extend to achieve uncommon ones. A Docker image shall be provided to get started running a "whitelabel" Firewall with no fuss.
- Stability. No API breackage allowed after version 1.0 is released. Strict adherence to semantic versioning.
- Performance. Maximum speed of execution and minimum cpu usage / memory usage are important. But not the main concern: safety, robustness and flexibility come first.
- Versatility. Proxies and Firewalls built on this library should work the same regardless of the webserver used to run PHP, be it Apache, Nginx, FrankenPHP or something else. The library should interoperate seamlessly with 3rd-party components readily available in the php ecosystem.
Which translates into:
- PHP 8.2 and up
- strict typing everywhere
- using DI patterns as much as possible
- using the PSR-7, PSR-15, PSR-18 interfaces means it should be easy to extend/embed the Proxy classes in other middlewares
- avoid relying on too many, big dependencies - f.e. no Monolog, Symfony ConfigTreeBuilder
- delegate all possible processing to a 'bootstrap' phase, so that the processing loop can be as efficient as possible
when used in eg.
workermode with FrankenPHP - taking care about memory leaks
- prefer end-to-end testing to unit testing, as the specific webserver used to run php does have an impact on the processing by the YAWAF code of http requests, esp. the ones which are not conforming to the http standard
Testing
Given the non-trivial set of configuration required to carry out end-to-end tests, the recommended setup is to use the provided docker-based stack to run the test suite
./tests/env/container.sh build ./tests/env/container.sh start ./tests/env/container.sh runtests ./tests/env/container.sh stop
The testsuite can be run using FrankenPHP or Apache as webserver with the following commands:
TEST_WEBSERVER=frankenphp ./tests/env/container.sh runtests
TEST_WEBSERVER=apache ./tests/env/container.sh runtests
FAQ
...
License
Use of this software is subject to the terms in the LICENSE file