chore: bump validators to 0.2.* and fix security vulnerabilities#219
chore: bump validators to 0.2.* and fix security vulnerabilities#219
Conversation
|
Caution Review failedThe pull request is closed. ℹ️ Recent review infoConfiguration used: Organization UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
WalkthroughThe pull request updates the version constraint for the Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Update utopia-php/validators from 0.1.* to 0.2.* and resolve security advisories in dev dependencies by upgrading phpunit (9.6.31 → 9.6.34) and symfony/process (8.0.3 → 8.0.5). Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
048db7f to
a7aa2e6
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
tests/ModelTest.php (1)
139-145: Prefer restoring$_SERVERby unsetting missing keys.If
REQUEST_METHOD/REQUEST_URIwere absent before the test, Lines 141-142 currently reintroduce them withnull. Unsetting preserves original global state more accurately.Suggested patch
protected function restoreRequest(): void { - $_SERVER['REQUEST_METHOD'] = $this->method; - $_SERVER['REQUEST_URI'] = $this->uri; + if ($this->method === null) { + unset($_SERVER['REQUEST_METHOD']); + } else { + $_SERVER['REQUEST_METHOD'] = $this->method; + } + + if ($this->uri === null) { + unset($_SERVER['REQUEST_URI']); + } else { + $_SERVER['REQUEST_URI'] = $this->uri; + } $_GET = []; $_POST = []; }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@tests/ModelTest.php` around lines 139 - 145, The restoreRequest method should avoid reintroducing REQUEST_METHOD/REQUEST_URI when they were originally absent: instead of unconditionally assigning $_SERVER['REQUEST_METHOD'] = $this->method and $_SERVER['REQUEST_URI'] = $this->uri, check $this->method and $this->uri and unset the corresponding $_SERVER keys when those properties are null (otherwise restore their values); keep clearing $_GET and $_POST as-is. Update the restoreRequest function to use conditional unset/assign logic referencing restoreRequest, $_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI'], $this->method and $this->uri.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@composer.json`:
- Line 31: Update the phpunit version constraint in composer.json to prevent
resolving vulnerable releases: replace the existing "phpunit/phpunit" constraint
(currently allowing 9.5.x or ^9.5.25) with "^9.6.33" so Composer will only allow
PHPUnit versions >=9.6.33; edit the "phpunit/phpunit" entry in composer.json
accordingly and run composer update or regenerate the lockfile to ensure the
lockfile reflects the new safe minimum.
In `@src/App.php`:
- Around line 720-722: The code checks $validator instanceof
\Utopia\Validator\ArrayList before resolving callable validators, so when
$param['validator'] is a callable (used by Hook::param) the instanceof test
fails; update the logic to first detect if $validator is callable and, if so,
invoke it to obtain the actual validator object (e.g. $validator = $validator()
or call_user_func($validator)), then perform the $validator instanceof
\Utopia\Validator\ArrayList check (affecting the isArrayList variable) so
model-list inputs are correctly recognized; ensure you reference and modify the
$validator variable before the isArrayList assignment in the same block.
In `@src/Request.php`:
- Around line 196-216: The code currently assigns $remoteAddr =
$this->getServer('REMOTE_ADDR') and returns it unvalidated; update the fallback
so $remoteAddr is validated with filter_var(..., FILTER_VALIDATE_IP) (supporting
IPv4/IPv6) and if invalid set it to '0.0.0.0' before returning; specifically,
after retrieving $remoteAddr from $this->getServer('REMOTE_ADDR') in the method
that iterates $this->trustedIpHeaders and uses $this->getHeader($header),
validate $remoteAddr the same way you validate $ip (use filter_var) and return
the validated value or '0.0.0.0'.
---
Nitpick comments:
In `@tests/ModelTest.php`:
- Around line 139-145: The restoreRequest method should avoid reintroducing
REQUEST_METHOD/REQUEST_URI when they were originally absent: instead of
unconditionally assigning $_SERVER['REQUEST_METHOD'] = $this->method and
$_SERVER['REQUEST_URI'] = $this->uri, check $this->method and $this->uri and
unset the corresponding $_SERVER keys when those properties are null (otherwise
restore their values); keep clearing $_GET and $_POST as-is. Update the
restoreRequest function to use conditional unset/assign logic referencing
restoreRequest, $_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI'],
$this->method and $this->uri.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
composer.lockis excluded by!**/*.lock
📒 Files selected for processing (49)
Dockerfilecomposer.jsondocker-compose.ymlsrc/App.phpsrc/Hook.phpsrc/Model.phpsrc/Request.phpsrc/Validator.phpsrc/Validator/AnyOf.phpsrc/Validator/ArrayList.phpsrc/Validator/Assoc.phpsrc/Validator/Boolean.phpsrc/Validator/Domain.phpsrc/Validator/FloatValidator.phpsrc/Validator/HexColor.phpsrc/Validator/Host.phpsrc/Validator/Hostname.phpsrc/Validator/IP.phpsrc/Validator/Integer.phpsrc/Validator/JSON.phpsrc/Validator/Multiple.phpsrc/Validator/Nullable.phpsrc/Validator/Numeric.phpsrc/Validator/Range.phpsrc/Validator/Text.phpsrc/Validator/URL.phpsrc/Validator/WhiteList.phpsrc/Validator/Wildcard.phptests/ModelTest.phptests/Validator/ArrayListTest.phptests/Validator/AssocTest.phptests/Validator/BooleanTest.phptests/Validator/DomainTest.phptests/Validator/FloatValidatorTest.phptests/Validator/HexColorTest.phptests/Validator/HostTest.phptests/Validator/HostnameTest.phptests/Validator/IPTest.phptests/Validator/IntegerTest.phptests/Validator/JSONTest.phptests/Validator/MultipleOfTest.phptests/Validator/MultipleTest.phptests/Validator/NullableTest.phptests/Validator/NumericTest.phptests/Validator/RangeTest.phptests/Validator/TextTest.phptests/Validator/URLTest.phptests/Validator/WhiteListTest.phptests/Validator/WildcardTest.php
💤 Files with no reviewable changes (43)
- src/Validator/Nullable.php
- tests/Validator/WildcardTest.php
- src/Validator/IP.php
- tests/Validator/MultipleOfTest.php
- src/Validator/ArrayList.php
- tests/Validator/DomainTest.php
- src/Validator/Range.php
- src/Validator/WhiteList.php
- tests/Validator/IntegerTest.php
- src/Validator/URL.php
- src/Validator/HexColor.php
- tests/Validator/NumericTest.php
- src/Validator/Integer.php
- Dockerfile
- src/Validator/Text.php
- tests/Validator/FloatValidatorTest.php
- tests/Validator/AssocTest.php
- tests/Validator/HexColorTest.php
- src/Validator.php
- src/Validator/AnyOf.php
- tests/Validator/TextTest.php
- tests/Validator/WhiteListTest.php
- tests/Validator/ArrayListTest.php
- tests/Validator/URLTest.php
- tests/Validator/HostnameTest.php
- src/Validator/Boolean.php
- tests/Validator/HostTest.php
- src/Validator/JSON.php
- tests/Validator/NullableTest.php
- src/Validator/Wildcard.php
- tests/Validator/MultipleTest.php
- tests/Validator/JSONTest.php
- src/Validator/Domain.php
- tests/Validator/BooleanTest.php
- src/Validator/FloatValidator.php
- src/Validator/Numeric.php
- tests/Validator/RangeTest.php
- docker-compose.yml
- src/Validator/Host.php
- src/Validator/Assoc.php
- src/Validator/Hostname.php
- tests/Validator/IPTest.php
- src/Validator/Multiple.php
composer.json
Outdated
| "phpunit/phpunit": "^9.5.25", | ||
| "swoole/ide-helper": "4.8.3", | ||
| "laravel/pint": "^1.2", | ||
| "phpunit/phpunit": "9.*", |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n composer.jsonRepository: utopia-php/http
Length of output: 1801
🏁 Script executed:
if [ -f composer.lock ]; then
head -50 composer.lock
echo "=== Checking for phpunit/phpunit ==="
jq '.["packages-dev"][] | select(.name=="phpunit/phpunit") | {name, version, dist}' composer.lock 2>/dev/null || echo "PHPUnit not found in packages-dev or jq error"
else
echo "composer.lock not found"
fiRepository: utopia-php/http
Length of output: 2157
🌐 Web query:
PHPUnit 9.6.34 CVE security fix vulnerability
💡 Result:
PHPUnit 9.6.34 is relevant to CVE-2026-24765 (unsafe deserialization of PHPT code-coverage “.coverage” files that can lead to code execution if an attacker can pre-place a crafted file—commonly discussed as a CI/CD “poisoned pipeline” scenario). The upstream security fix landed in PHPUnit 9.6.33 (patched version), and 9.6.34 is a follow-up that fixes a regression introduced in 9.6.33—so 9.6.34 also contains the security fix. [1] [2] [3]
What to do
- Upgrade to at least 9.6.33; 9.6.34 is the safer target for the 9.6.x line because it includes the regression fix. [1] [3]
- If you can’t upgrade immediately, reduce risk by ensuring CI jobs don’t run with pre-existing/cached
*.coveragefiles in the workspace (clean checkout / ephemeral runners). [1] [2]
Affected / patched (per advisory)
- Affected:
>= 9.0.0, < 9.6.33; Patched:9.6.33(and later, including9.6.34). [1]
Sources:
[1] GitHub Advisory (GHSA-vvj3-c3rp-c85p / CVE-2026-24765) (github.com)
[2] NVD CVE-2026-24765 entry (nvd.nist.gov)
[3] PHPUnit 9.6.34 release notes (regression fix after 9.6.33) (github.com)
Citations:
- 1: GHSA-vvj3-c3rp-c85p
- 2: https://nvd.nist.gov/vuln/detail/CVE-2026-24765
- 3: https://github.com/sebastianbergmann/phpunit/releases/tag/9.6.34
Update PHPUnit constraint to ^9.6.33 to exclude vulnerable versions.
Line 40 declares "phpunit/phpunit": "^9.5.25", which allows versions down to 9.5.25 when dependencies are resolved. This includes vulnerable versions before 9.6.33 (affected by CVE-2026-24765 - unsafe deserialization in .coverage files). Although the lock file currently pins 9.6.34, the loose constraint risks resolution to vulnerable versions in fresh or lowest-constraint scenarios. Use ^9.6.33 instead.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@composer.json` at line 31, Update the phpunit version constraint in
composer.json to prevent resolving vulnerable releases: replace the existing
"phpunit/phpunit" constraint (currently allowing 9.5.x or ^9.5.25) with
"^9.6.33" so Composer will only allow PHPUnit versions >=9.6.33; edit the
"phpunit/phpunit" entry in composer.json accordingly and run composer update or
regenerate the lockfile to ensure the lockfile reflects the new safe minimum.
src/App.php
Outdated
| $validator = $param['validator']; | ||
| $isArrayList = $validator instanceof \Utopia\Validator\ArrayList; | ||
|
|
There was a problem hiding this comment.
Resolve callable validators before ArrayList detection.
Line 721 checks instanceof ArrayList on the raw validator field. When the validator is provided as a callable (supported by Hook::param), this is always false, and model-list inputs can be treated as a single model payload.
Suggested patch
- $validator = $param['validator'];
- $isArrayList = $validator instanceof \Utopia\Validator\ArrayList;
+ $validator = $param['validator'];
+ if (!\is_string($validator) && \is_callable($validator)) {
+ $validator = \call_user_func_array($validator, $this->getResources($param['injections']));
+ }
+ $isArrayList = $validator instanceof \Utopia\Validator\ArrayList;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| $validator = $param['validator']; | |
| $isArrayList = $validator instanceof \Utopia\Validator\ArrayList; | |
| $validator = $param['validator']; | |
| if (!\is_string($validator) && \is_callable($validator)) { | |
| $validator = \call_user_func_array($validator, $this->getResources($param['injections'])); | |
| } | |
| $isArrayList = $validator instanceof \Utopia\Validator\ArrayList; | |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/App.php` around lines 720 - 722, The code checks $validator instanceof
\Utopia\Validator\ArrayList before resolving callable validators, so when
$param['validator'] is a callable (used by Hook::param) the instanceof test
fails; update the logic to first detect if $validator is callable and, if so,
invoke it to obtain the actual validator object (e.g. $validator = $validator()
or call_user_func($validator)), then perform the $validator instanceof
\Utopia\Validator\ArrayList check (affecting the isArrayList variable) so
model-list inputs are correctly recognized; ensure you reference and modify the
$validator variable before the isArrayList assignment in the same block.
src/Request.php
Outdated
| $remoteAddr = $this->getServer('REMOTE_ADDR') ?? '0.0.0.0'; | ||
|
|
||
| foreach ($this->trustedIpHeaders as $header) { | ||
| $headerValue = $this->getHeader($header); | ||
|
|
||
| if (empty($headerValue)) { | ||
| continue; | ||
| } | ||
|
|
||
| // Leftmost IP address is the address of the originating client | ||
| $ips = explode(',', $headerValue); | ||
| $ip = trim($ips[0]); | ||
|
|
||
| // Validate IP format (supports both IPv4 and IPv6) | ||
| if (filter_var($ip, FILTER_VALIDATE_IP)) { | ||
| return $ip; | ||
| } | ||
| } | ||
|
|
||
| return $remoteAddr; | ||
| } |
There was a problem hiding this comment.
Validate REMOTE_ADDR before fallback return.
Line 196 assigns REMOTE_ADDR directly, and Line 215 returns it without validation. That contradicts the method contract (“validated client IP or 0.0.0.0”) and can leak invalid values downstream.
Suggested patch
- $remoteAddr = $this->getServer('REMOTE_ADDR') ?? '0.0.0.0';
+ $remoteAddr = $this->getServer('REMOTE_ADDR');
+ $remoteAddr = (\is_string($remoteAddr) && \filter_var($remoteAddr, FILTER_VALIDATE_IP))
+ ? $remoteAddr
+ : '0.0.0.0';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| $remoteAddr = $this->getServer('REMOTE_ADDR') ?? '0.0.0.0'; | |
| foreach ($this->trustedIpHeaders as $header) { | |
| $headerValue = $this->getHeader($header); | |
| if (empty($headerValue)) { | |
| continue; | |
| } | |
| // Leftmost IP address is the address of the originating client | |
| $ips = explode(',', $headerValue); | |
| $ip = trim($ips[0]); | |
| // Validate IP format (supports both IPv4 and IPv6) | |
| if (filter_var($ip, FILTER_VALIDATE_IP)) { | |
| return $ip; | |
| } | |
| } | |
| return $remoteAddr; | |
| } | |
| $remoteAddr = $this->getServer('REMOTE_ADDR'); | |
| $remoteAddr = (\is_string($remoteAddr) && \filter_var($remoteAddr, FILTER_VALIDATE_IP)) | |
| ? $remoteAddr | |
| : '0.0.0.0'; | |
| foreach ($this->trustedIpHeaders as $header) { | |
| $headerValue = $this->getHeader($header); | |
| if (empty($headerValue)) { | |
| continue; | |
| } | |
| // Leftmost IP address is the address of the originating client | |
| $ips = explode(',', $headerValue); | |
| $ip = trim($ips[0]); | |
| // Validate IP format (supports both IPv4 and IPv6) | |
| if (filter_var($ip, FILTER_VALIDATE_IP)) { | |
| return $ip; | |
| } | |
| } | |
| return $remoteAddr; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/Request.php` around lines 196 - 216, The code currently assigns
$remoteAddr = $this->getServer('REMOTE_ADDR') and returns it unvalidated; update
the fallback so $remoteAddr is validated with filter_var(...,
FILTER_VALIDATE_IP) (supporting IPv4/IPv6) and if invalid set it to '0.0.0.0'
before returning; specifically, after retrieving $remoteAddr from
$this->getServer('REMOTE_ADDR') in the method that iterates
$this->trustedIpHeaders and uses $this->getHeader($header), validate $remoteAddr
the same way you validate $ip (use filter_var) and return the validated value or
'0.0.0.0'.
Summary
utopia-php/validatorsfrom 0.1.* to 0.2.*phpunit/phpunitfrom 9.6.29 to 9.6.34 (fixes CVE-2026-24765)symfony/processfrom 8.0.0 to 8.0.5 (fixes CVE-2026-24739)Test plan
composer audit🤖 Generated with Claude Code
Summary by CodeRabbit