Repository navigation
v3.0.1
Security
-
Validator/TransactionValidator
- Reject CRLF, percent-encoded CRLF and NULL bytes in URI; fix the
previously broken backslash regex (/\\\/) that matched nothing
relevant. Mitigates HTTP Response Splitting / smuggling (A03). - Reject protocol-relative URIs (
//host,/\host) which Symfony's
Request::create()interprets as havinghostas authority.
Mitigates SSRF / Open Redirect (A10). - New
validateHeaders(): enforce RFC 7230 §3.2.6 tchar header names
and forbid CR/LF/NULL in header values (A03).
- Reject CRLF, percent-encoded CRLF and NULL bytes in URI; fix the
-
Validator/BatchRequestValidator
- Drop the "skip per-transaction validation for batches >1000" path.
Security must not depend on batch size; the maxBatchSize cap is the
only correct performance lever (A04 Insecure Design).
- Drop the "skip per-transaction validation for batches >1000" path.
-
Parser/JsonBatchRequestParser
json_decodenow usesdepth=32andJSON_THROW_ON_ERROR, plus a
configurablemaxContentLength(default 5 MiB) checked before
decoding. Mitigates billion-laughs / memory-exhaustion DoS (A04).- Add a denylist of sensitive context headers that must not be
propagated from the parent request to sub-requests:Host,
X-Forwarded-*,X-Real-IP,Forwarded, and RFC 7230 §6.1
hop-by-hop headers (A01 BAC + A03 spoofing).
-
Bridge facades and executors
- SymfonyBatchRequestFacade / LaravelBatchRequestFacade: replace raw
$e->getMessage()in 500 responses with a generic
"Internal server error" message; full context is still logged
(A09 Information Disclosure). - SymfonyTransactionExecutor: keep informative error type/message for
HttpExceptionInterface(NotFound, etc.) but return a generic
payload for all otherThrowable(A09). - LaravelTransactionExecutor: stop returning
get_class($e)and the
raw exception message in the per-transaction response (A09).
- SymfonyBatchRequestFacade / LaravelBatchRequestFacade: replace raw
Bugs
-
Parser/JsonBatchRequestParser::extractParameters
parse_stris no longer applied to JSON-looking bodies. Previously
a body like{"a":1}was silently mangled into
['{"a":1}' => '']. The raw body still flows through
prepareContent.
-
Bridge/Symfony/SymfonyBatchRequestFacade
- Remove the redundant "isLargeBatch" branch in
extractContextthat
decoded the entire payload a second time, and remove the rate-limit
decode that ran without depth/throw flags. Rate-limit decode is now
safe and tolerant of invalid input (count=1 fallback). - Remove the unused
getErrorType()method (dead code). logErrorno longer allocates a freshNullLoggeron each call.
- Remove the redundant "isLargeBatch" branch in
-
Handler/BatchRequestHandler
- Stop disabling the logger for batches >1000. Silently dropping
validation-error logs hid both bugs and DoS attempts.
- Stop disabling the logger for batches >1000. Silently dropping
-
Bridge/Laravel/LaravelServiceProvider
- Actually load
config/batch-request.phpviamergeConfigFrom,
publish it under thebatch-request-configtag, and read
batch-request.max_batch_size(with a safe fallback to 50 when the
configrepository is not bound, so test containers keep working).
The config file existed and was documented but had no effect. - Mark the provider as
final.
- Actually load
Tests
- Update Symfony/LaravelTransactionExecutor tests to assert the new
generic error contract. - Replace the PHPUnit-12
$this->isType('callable')(removed in
PHPUnit 13) with acallbackconstraint in
LaravelServiceProviderTest.