GHSA-2jx3-65f3-xr8r
GHSA-2jx3-65f3-xr8r · spomky-labs/otphp: Mass-assignment in Factory::loadFromProvisioningUri lets a hostile provisioning URI corrupt OTP state or leak an uncaught TypeError
Diese Seite enthält Fakten aus öffentlichen Sicherheitsquellen. Lesen Sie vor dem Aktualisieren die Originalmeldung.
## Summary `OTPHP\Factory::loadFromProvisioningUri()` parses an attacker-supplied `otpauth://` URI and forwards **every** query key to `OTP::setParameter($key, $value)`. `setParameter()` resolves the name with `property_exists($this, $parameter)` and performs a dynamic write `$this->{$parameter} = $value` (`src/OTP.php:196-197`). Because the query keys are entirely controlled by whoever produced the URI, a URI can target the internal properties of the OTP object that are not meant to be set from a URI: `parameters`, `issuer`, `label`, `issuer_included_as_parameter`, and (on TOTP) the readonly `clock`. This is an instance of object property mass-assignment (CWE-915). ## Impact The `Factory` is documented as the entry point for third-party provisioning URIs (e.g. QR codes from Microsoft 365 / Google Authenticator). An application that loads such a URI is exposed to: - **State corruption.** A URI such as `otpauth://totp/Alice?secret=JBSWY3DPEHPK3PXP¶meters[foo]=bar` overwrites the whole internal `$parameters` array that `createFromSecret()` primed (`period`, `algorithm`, `digits`, `epoch`). The resulting object is silently unusable: `getProvisioningUri()`, `getDigits()`, `at()`, `verify()` then throw `ParameterNotFoundException`. - **Uncaught TypeError escaping the documented exception type.** A URI such as `otpauth://totp/Alice?secret=JBSWY3DPEHPK3PXP&issuer_included_as_parameter=notabool` assigns a string to a typed `bool` property and raises a `TypeError`. The `try/catch` in `loadFromProvisioningUri()` only wraps `Url::fromString()`; `createOTP()` and `populateOTP()` run outside it, so the `TypeError` (and `Error` on the readonly `clock`) escapes past the documented `InvalidProvisioningUriException`, breaking callers that catch only the documented type. - **Label/issuer validation bypass.** `parameters[label]=hijacked` stores a label into the parameters array without running the `label` validation callback (keyed on `label`, not `parameters`). `getLabel()` and `getParameter('label')` then disagree — a confused-deputy risk. ## Affected component - `src/OTP.php:187-201` — `setParameter()` dynamic property write - `src/Factory.php:50-55` — `populateParameters()` forwarding all query keys ## Proof of concept ```php use OTPHP\Factory; // State corruption $otp = Factory::loadFromProvisioningUri( 'otpauth://totp/Alice?secret=JBSWY3DPEHPK3PXP¶meters[foo]=bar', $clock ); $otp->getProvisioningUri(); // ParameterNotFoundException: Parameter "period" does not exist // Uncaught TypeError Factory::loadFromProvisioningUri( 'otpauth://totp/Alice?secret=JBSWY3DPEHPK3PXP&issuer_included_as_parameter=notabool', $clock ); // TypeError escapes InvalidProvisioningUriException ``` ## Remediation Restrict the keys accepted from a provisioning URI to a known allow-list of public OTP parameters, and never let a URI key resolve to an internal object property via `property_exists`. Route all URI-sourced values through the validated parameter map only.
CVSS 6.9 · Mittel · Korrektur verfügbar
- Veröffentlicht
- Aktualisiert
Technologie-Stack: php
Betroffene Produkte und Versionen
spomky-labs/otphp Packagist
- Softwareversionen
- 1.0.1-stable
- 11.0.3
- 11.1.0
- 11.1.1
- 11.2.0
- 11.2.1
- 11.2.2
- 11.3.0
- 11.4.0
- 11.4.1
- 11.4.2
- 5.0.0
- v1.0.0-stable
- v10.0.0
- v10.0.1
- v10.0.2
- v10.0.3
- v11.0.0
- v11.0.1
- v11.0.2
- v2.0.0-stable
- v2.0.1-stable
- v2.0.2-stable
- v3.0.0-stable
- v3.0.1-stable
- v3.1.0
- v3.1.1
- v4.0.0
- v4.0.1
- v4.0.2
- v4.0.3
- v4.0.4
- v5.0.1
- v6.0.0
- v6.0.1
- v6.0.2
- v6.0.3
- v6.0.4
- v7.0.0
- v7.0.1
- v7.0.2
- v7.0.3
- v7.0.4
- v8.0.0
- v8.1.0
- v8.2.0
- v8.3.0
- v8.3.1
- v8.3.2
- v8.3.3
- v9.0.0
- v9.0.0-alpha1
- v9.0.1
- v9.0.2
- v9.0.3
- v9.1.0
- v9.1.1
- v9.1.2
- v9.1.3
- v9.1.4
- Betroffene Versionsbereiche
- ECOSYSTEM: < 11.4.3
Auf 11.4.3 aktualisieren