| @@ -541,17 +541,17 @@ | ||
| 541 | 541 | } |
| 542 | 542 | |
| 543 | 543 | $value = $this->$key ?? $this->fillable[ $key ]; |
| 544 | 544 | |
| 545 | - // Unserialize if necessary | |
| 545 | + // Unserialize if necessary (object instantiation disallowed — see helper). | |
| 546 | 546 | if ( is_string( $value ) && $this->is_serialized( $value ) ) { |
| 547 | - $value = maybe_unserialize( $value ); | |
| 547 | + $value = \booktics_safe_maybe_unserialize( $value ); | |
| 548 | 548 | } |
| 549 | 549 | |
| 550 | 550 | // Normalize value to default type |
| 551 | 551 | if ( gettype( $value ) !== gettype( $default ) ) { |
| 552 | 552 | if ( gettype( $default ) === 'array' && is_string( $value ) && $this->is_serialized( $value ) ) { |
| 553 | - $value = maybe_unserialize( $value ); | |
| 553 | + $value = \booktics_safe_maybe_unserialize( $value ); | |
| 554 | 554 | } elseif ( gettype( $default ) === 'array' ) { |
| 555 | 555 | $value = $default; |
| 556 | 556 | } |
| 557 | 557 | } |
| @@ -556,9 +556,9 @@ | ||
| 556 | 556 | } |
| 557 | 557 | } |
| 558 | 558 | |
| 559 | 559 | // Cast specific keys to objects |
| 560 | - if ( $key == 'schedule' ) { | |
| 560 | + if ( 'schedule' == $key ) { | |
| 561 | 561 | $value = (object) $value; |
| 562 | 562 | } |
| 563 | 563 | |
| 564 | 564 | // Cast specific keys to boolean |
| @@ -569,9 +569,9 @@ | ||
| 569 | 569 | ] ) ) { |
| 570 | 570 | $value = filter_var( $value, FILTER_VALIDATE_BOOLEAN ); |
| 571 | 571 | } |
| 572 | 572 | |
| 573 | - if ( $key == 'user_registered' ) { | |
| 573 | + if ( 'user_registered' == $key ) { | |
| 574 | 574 | $value = $default; |
| 575 | 575 | } |
| 576 | 576 | |
| 577 | 577 | $data[ $key ] = $value ?? $default; |
| @@ -589,9 +589,11 @@ | ||
| 589 | 589 | * |
| 590 | 590 | * @return bool True if data is serialized, false otherwise |
| 591 | 591 | */ |
| 592 | 592 | function is_serialized( $data ) { |
| 593 | - return is_string( $data ) && @unserialize( $data ) !== false; | |
| 593 | + // Structural check only (WordPress core) — never calls unserialize(), so it | |
| 594 | + // cannot trigger PHP Object Injection on attacker-controlled user meta. | |
| 595 | + return is_string( $data ) && \is_serialized( $data ); | |
| 594 | 596 | } |
| 595 | 597 | |
| 596 | 598 | /** |
| 597 | 599 | * Specify data which should be serialized to JSON. |