CVE-2024-24754: Bref/bref Bref Vulnerable To Body Parsing Vulnerability

LOW
Advisory Identifier: GHSA-82vx-mm6r-gg8w
CVSS 3.7
CWE-436
Published
Advisory Summary

CVE-2024-24754 is a LOW (CVSS 3.7) bref vulnerable to body parsing vulnerability (CWE-436: Interpretation Conflict) affecting Bref/bref libraries in the Packagist ecosystem. The issue involves bref vulnerable to body parsing inconsistency in event-driven functions. Remediation is available by upgrading affected packages to version 2.1.13.

CVE-2024-24754 at a Glance

CVE Identifier CVE-2024-24754
GHSA Identifier GHSA-82vx-mm6r-gg8w
Severity LOW
CVSS v3.1 Base Score 3.7
CWE Classification CWE-436: Interpretation Conflict
Affected Product Bref/bref
Package Ecosystem Packagist
Published Date
Last Updated

Security Impact

CVSS: 3.7

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N).

Attack Vector Network (AV:N)
Attack Complexity High (AC:H)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality None (C:N)
Integrity Low (I:L)
Availability None (A:N)

How to Fix CVE-2024-24754

To remediate this vulnerability, upgrade all affected Bref/bref dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

bref/bref fixed: 2.1.13
Upgrade bref/bref to 2.1.13
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

inspect dependencies for bref/bref

How to Check if You Are Affected

To determine whether your application is affected by CVE-2024-24754, inspect your project dependencies for Bref/bref:

inspect dependencies for bref/bref

Analyze the terminal output to locate any version of Bref/bref in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 2.1.13), your application is affected.

Note: Verify declared build manifests and deployed runtime container environments.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-436: Interpretation Conflict, where product a handles inputs or steps differently than product b, which causes a to perform incorrect actions based on its perception of b's state. In Bref/bref, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## 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: ```php /** * 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 1. Create a new Bref project. 2. Create an `index.php` file with the following content: ```php <?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(); ``` 3. Use the following `serverless.yml` to deploy the Lambda: ```yaml 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' ``` 4. 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-- ``` 5. Notice how the body has been parsed. 6. Create a `plain.php` file with the following content: ```php <?php var_dump($_POST); ``` 7. Start a PHP server inside the project directory (e.g. `php -S 127.0.0.1:8090`). 8. 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-- ``` 9. Notice the differences in the parsing compared to what observed at step 5. ## Suggested Remediation Use the PHP function [`parse_str`](https://www.php.net/manual/en/function.parse-str.php) to parse the body parameters to mimic the plain PHP behavior.

CVE-2024-24754 Affected Bref/bref Versions

1 component(s)
Fixed Versions:
2.1.13
Product / Package Ecosystem Affected Versions Fixed Version
bref/bref
Packagist
< 2.1.13
2.1.13

References

Frequently Asked Questions

What is CVE-2024-24754?
CVE-2024-24754 is a security vulnerability in Bref/bref involving Bref vulnerable to Body Parsing Inconsistency in Event-Driven Functions under CWE-436: Interpretation Conflict.
Which Bref/bref versions are affected?
Affected versions include releases prior to 2.1.13 across affected packages: bref/bref.
What version fixes CVE-2024-24754?
Upgrading to 2.1.13 (or the latest patched release for your respective branch) resolves the vulnerability.
Is bref/bref affected?
Yes, bref/bref is affected in releases prior to 2.1.13. Upgrade your dependency to 2.1.13 or later.
What is the CVSS score of CVE-2024-24754?
CVE-2024-24754 has a CVSS v3.1 base score of 3.7 (LOW) with vector string CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N.
What CWE is associated with CVE-2024-24754?
CVE-2024-24754 is classified under CWE-436: Interpretation Conflict (Product A handles inputs or steps differently than Product B, which causes A to perform incorrect actions based on its perception of B's state.).
How can I check Packagist dependencies for CVE-2024-24754?
Run the dependency tree command: 'inspect dependencies for bref/bref'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-82vx-mm6r-gg8w",
  "modified" : "2024-02-01T22:47:29Z",
  "published" : "2024-02-01T22:47:29Z",
  "aliases" : [ "CVE-2024-24754" ],
  "summary" : "Bref vulnerable to Body Parsing Inconsistency in Event-Driven Functions",
  "details" : "## Impacted Resources\n\nbref/src/Event/Http/Psr7Bridge.php:130-168\n\n## Description\n\nWhen 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.\nDuring the conversion process, if the request is a MultiPart, each part is parsed and its content added in the `$files` or `$parsedBody` arrays.\nTo 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:\n\n```php\n/**\n * Parse a string key like \"files[id_cards][jpg][]\" and do $array['files']['id_cards']['jpg'][] = $value\n */\nprivate static function parseKeyAndInsertValueInArray(array &$array, string $key, mixed $value): void\n{\n    if (! str_contains($key, '[')) {\n        $array[$key] = $value;\n\n        return;\n    }\n\n    $parts = explode('[', $key); // files[id_cards][jpg][] => [ 'files',  'id_cards]', 'jpg]', ']' ]\n    $pointer = &$array;\n\n    foreach ($parts as $k => $part) {\n        if ($k === 0) {\n            $pointer = &$pointer[$part];\n\n            continue;\n        }\n\n        // Skip two special cases:\n        // [[ in the key produces empty string\n        // [test : starts with [ but does not end with ]\n        if ($part === '' || ! str_ends_with($part, ']')) {\n            // Malformed key, we use it \"as is\"\n            $array[$key] = $value;\n\n            return;\n        }\n\n        $part = substr($part, 0, -1); // The last char is a ] => remove it to have the real key\n\n        if ($part === '') { // [] case\n            $pointer = &$pointer[];\n        } else {\n            $pointer = &$pointer[$part];\n        }\n    }\n\n    $pointer = $value;\n}\n```\n\nThe conversion process produces a different output compared to the one of plain PHP when keys ending with and open square bracket (`[`) are used.\n\nLet's take for example the following part:\n```\n------WebKitFormBoundary\nContent-Disposition: form-data; name=\"key0[key1][key2][\"\n\nvalue\n------WebKitFormBoundary--\n```\n\nIn 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 )`.\n\n## Impact\n\nBased on the application logic the difference in the body parsing might lead to vulnerabilities and/or undefined behaviors.\n\n## PoC\n\n1. Create a new Bref project.\n2. Create an `index.php` file with the following content:\n```php\n<?php\n\nnamespace App;\n\nrequire __DIR__ . '/vendor/autoload.php';\n\nuse Nyholm\\Psr7\\Response;\nuse Psr\\Http\\Message\\ResponseInterface;\nuse Psr\\Http\\Message\\ServerRequestInterface;\nuse Psr\\Http\\Server\\RequestHandlerInterface;\n\nclass MyHttpHandler implements RequestHandlerInterface\n{\n    public function handle(ServerRequestInterface $request): ResponseInterface\n    {\n\n        return new Response(200, [], var_export($request->getParsedBody(),true));\n    }\n}\n\nreturn new MyHttpHandler();\n\n```\n3. Use the following `serverless.yml` to deploy the Lambda:\n```yaml\nservice: app\n\nprovider:\n    name: aws\n    region: eu-central-1\n\nplugins:\n    - ./vendor/bref/bref\n\n# Exclude files from deployment\npackage:\n    patterns:\n        - '!node_modules/**'\n        - '!tests/**'\n\nfunctions:\n    api:\n        handler: index.php\n        runtime: php-83\n        events:\n            - httpApi: 'ANY /upload'\n```\n4. Replay the following request after having replaced the `<HOST>` placeholder with the deployed Lambda domain:\n```\nPOST /upload HTTP/2\nHost: <HOST>\nContent-Type: multipart/form-data; boundary=----WebKitFormBoundaryQqDeSZSSvmn2rfjb\nContent-Length: 180\n\n------WebKitFormBoundaryQqDeSZSSvmn2rfjb\nContent-Disposition: form-data; name=\"key0[key1][key2][\"\n\nvalue\n------WebKitFormBoundaryQqDeSZSSvmn2rfjb--\n```\n5. Notice how the body has been parsed.\n6. Create a `plain.php` file with the following content:\n```php\n<?php\n\nvar_dump($_POST);\n```\n7. Start a PHP server inside the project directory (e.g. `php -S 127.0.0.1:8090`).\n8. Replay the following request after having replaced the `<HOST>` placeholder with the PHP server address:\n```\nPOST /plain.php HTTP/1.1\nHost: <HOST>\nContent-Type: multipart/form-data; boundary=----WebKitFormBoundaryQqDeSZSSvmn2rfjb\nContent-Length: 180\n\n------WebKitFormBoundaryQqDeSZSSvmn2rfjb\nContent-Disposition: form-data; name=\"key0[key1][key2][\"\n\nvalue\n------WebKitFormBoundaryQqDeSZSSvmn2rfjb--\n```\n9. Notice the differences in the parsing compared to what observed at step 5.\n\n## Suggested Remediation\n\nUse the PHP function [`parse_str`](https://www.php.net/manual/en/function.parse-str.php) to parse the body parameters to mimic the plain PHP behavior.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "Packagist",
      "name" : "bref/bref"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "2.1.13"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/brefphp/bref/security/advisories/GHSA-82vx-mm6r-gg8w"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2024-24754"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/brefphp/bref/commit/c77d9f5abf021f29fa96b5720b7b84adbd199092"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/brefphp/bref"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/brefphp/bref/blob/2.1.12/src/Event/Http/Psr7Bridge.php#L130-L168"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-436" ],
    "severity" : "LOW",
    "github_reviewed" : true,
    "github_reviewed_at" : "2024-02-01T22:47:29Z",
    "nvd_published_at" : "2024-02-01T16:17:14Z"
  }
}