Bref vulnerable to Body Parsing Inconsistency in Event-Driven Functions
Impacted Resources
bref/src/Event/Http/Psr7Bridge.php:130-168
Description
When Bref is used with the Event-Driven Function runtime and the handler is a RequestHandlerInterface, then the Lambda event is converted to a PSR7 object.
During the conversion process, if the request is a MultiPart, each part is parsed and its content added in the $files or $parsedBody arrays.
To do that, the following method is called with as first argument the result array ($files or $parsedBody), as second argument the part name, and as third argument the part content:
/**
* Parse a string key like "files[id_cards][jpg][]" and do $array['files']['id_cards']['jpg'][] = $value
*/
private static function parseKeyAndInsertValueInArray(array &$array, string $key, mixed $value): void
{
if (! str_contains($key, '[')) {
$array[$key] = $value;
return;
}
$parts = explode('[', $key); // files[id_cards][jpg][] => [ 'files', 'id_cards]', 'jpg]', ']' ]
$pointer = &$array;
foreach ($parts as $k => $part) {
if ($k === 0) {
$pointer = &$pointer[$part];
continue;
}
// Skip two special cases:
// [[ in the key produces empty string
// [test : starts with [ but does not end with ]
if ($part === '' || ! str_ends_with($part, ']')) {
// Malformed key, we use it "as is"
$array[$key] = $value;
return;
}
$part = substr($part, 0, -1); // The last char is a ] => remove it to have the real key
if ($part === '') { // [] case
$pointer = &$pointer[];
} else {
$pointer = &$pointer[$part];
}
}
$pointer = $value;
}
The conversion process produces a different output compared to the one of plain PHP when keys ending with and open square bracket ([) are used.
Let's take for example the following part:
------WebKitFormBoundary
Content-Disposition: form-data; name="key0[key1][key2]["
value
------WebKitFormBoundary--
In plain PHP it would be converted to Array( [key0] => Array ( [key1] => Array ( [key2] => value) ) ), while in Bref it would be converted to Array( [key0] => Array ( [key1] => Array ( [key2] => ) ) [key0[key1][key2][] => value ).
Impact
Based on the application logic the difference in the body parsing might lead to vulnerabilities and/or undefined behaviors.
PoC
- Create a new Bref project.
- Create an
index.phpfile with the following content:
<?php
namespace App;
require __DIR__ . '/vendor/autoload.php';
use Nyholm\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class MyHttpHandler implements RequestHandlerInterface
{
public function handle(ServerRequestInterface $request): ResponseInterface
{
return new Response(200, [], var_export($request->getParsedBody(),true));
}
}
return new MyHttpHandler();
- Use the following
serverless.ymlto deploy the Lambda:
service: app
provider:
name: aws
region: eu-central-1
plugins:
- ./vendor/bref/bref
# Exclude files from deployment
package:
patterns:
- '!node_modules/**'
- '!tests/**'
functions:
api:
handler: index.php
runtime: php-83
events:
- httpApi: 'ANY /upload'
- Replay the following request after having replaced the
<HOST>placeholder with the deployed Lambda domain:
POST /upload HTTP/2
Host: <HOST>
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryQqDeSZSSvmn2rfjb
Content-Length: 180
------WebKitFormBoundaryQqDeSZSSvmn2rfjb
Content-Disposition: form-data; name="key0[key1][key2]["
value
------WebKitFormBoundaryQqDeSZSSvmn2rfjb--
- Notice how the body has been parsed.
- Create a
plain.phpfile with the following content:
<?php
var_dump($_POST);
- Start a PHP server inside the project directory (e.g.
php -S 127.0.0.1:8090). - Replay the following request after having replaced the
<HOST>placeholder with the PHP server address:
POST /plain.php HTTP/1.1
Host: <HOST>
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryQqDeSZSSvmn2rfjb
Content-Length: 180
------WebKitFormBoundaryQqDeSZSSvmn2rfjb
Content-Disposition: form-data; name="key0[key1][key2]["
value
------WebKitFormBoundaryQqDeSZSSvmn2rfjb--
- Notice the differences in the parsing compared to what observed at step 5.
Suggested Remediation
Use the PHP function parse_str to parse the body parameters to mimic the plain PHP behavior.
Czego dotyczy
Kliknij technologię, aby zobaczyć wszystkie dotyczące jej podatności.
| Platforma | Paczka | Podatne wersje | Poprawka w wersji |
|---|---|---|---|
| Paczka Composer | bref/bref | < 2.1.13 | 2.1.13 |
Odnośniki
- https://github.com/brefphp/bref/security/advisories/GHSA-82vx-mm6r-gg8w
- https://nvd.nist.gov/vuln/detail/CVE-2024-24754
- https://github.com/brefphp/bref/commit/c77d9f5abf021f29fa96b5720b7b84adbd199092
- https://github.com/brefphp/bref
- https://github.com/brefphp/bref/blob/2.1.12/src/Event/Http/Psr7Bridge.php#L130-L168
- Wektor CVSS
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N- Słabość (CWE)
CWE-436- Platforma
- Composer
- Paczka
bref/bref- Ujawniono
- 01.02.2024
- Aktualizacja
- 11.10.2026 10:22
Źródła i licencje
OSV / GitHub Advisory Database - GHSA-82vx-mm6r-gg8w - CC BY 4.0
Historia podatności: bref/bref
Wszystkie opisane podatności tej paczki (Paczka Composer), od najnowszej. Widać, czy to jednorazowa wpadka, czy paczka, której trzeba pilnować.
- Wszystkich wpisów
- 4
- Pierwsza → ostatnia
- 02.2024 03.2024
- Bez poprawki
- 0
- Wykorzystywana w atakach
- 0
Rozkład istotności
- Średnia 3
- Niska 1
Ujawnienia w latach
- 2024: 4
- 2025: 0
- 2026: 0
-
Bref vulnerable to Body Parsing Inconsistency in Event-Driven Functions ten wpis
Dowiedz się, które podatności dotyczą Twojej aplikacji
Po podłączeniu integracji DockRay i włączeniu raportowania oprogramowania DockRay porównuje zgłoszone wersje komponentów ze znanymi podatnościami i powiadamia o potwierdzonych dopasowaniach. Zakres zależy od obsługiwanej technologii i dostępnych biuletynów.