ActionScheduler_ScheduleDeserializer::reject
Handle a blob that references a class outside the vetted set.
Always surfaces the event for observability. Under enforcement (the default) the blob is rejected by returning false, which callers already handle like a corrupt schedule.
Shadow mode ("report only") relaxes this, but only for a $shadow_eligible rejection — one where the outermost object is a valid schedule and merely a nested class was unexpected. That is the sole case where a mis-tuned allow-list could disrupt an otherwise-legitimate action, so it is the only case shadow mode lets through. Structural rejections ($shadow_eligible false) — a top-level non-schedule (the issue #1318 PoC) or an unwalkable object graph — have no legitimate form and are always rejected, even in shadow mode, so report-only can never be downgraded into reviving the vulnerability.
Метод класса: ActionScheduler_ScheduleDeserializer{}
Хуки из метода
Возвращает
ActionScheduler_Schedule|false. False when rejected. A shadow-mode passthrough is only reached for a nested rejection, i.e. after the top-level schedule gate passed, so any object returned is a schedule.
Использование
// protected - в коде основоного (родительского) или дочернего класса $result = $this->reject( $offending_class, $shadow_eligible );
- $offending_class(строка) (обязательный)
- The class that triggered the rejection.
- $shadow_eligible(true|false) (обязательный)
- Whether shadow mode may let this particular rejection through.
Код ActionScheduler_ScheduleDeserializer::reject() ActionScheduler ScheduleDeserializer::reject WC 11.2.2
protected function reject( $offending_class, $shadow_eligible ) {
// A rejection stands unless we are in shadow mode AND this rejection is eligible for report-only
// passthrough. Resolve it once so the reported outcome and the branch taken cannot disagree, and
// the action_scheduler_enforce_schedule_allowed_classes filter runs a single time.
$rejected = self::is_enforced() || ! $shadow_eligible;
/**
* Fires when a stored schedule blob references a class Action Scheduler did not expect.
*
* @since 4.1.0
*
* @param string $offending_class The class that triggered the rejection.
* @param string $outer_class The outermost class in the blob.
* @param string[] $unexpected_classes Every class the blob names that is outside the safe set.
* @param bool $rejected Whether the blob was rejected (true) or allowed through in
* shadow mode (false). Always true for a structural rejection
* (top-level non-schedule or unwalkable graph), which shadow
* mode cannot relax.
*/
do_action( 'action_scheduler_unexpected_schedule_class', $offending_class, $this->outer_class, $this->potential_offenders, $rejected );
if ( $rejected ) {
return false;
}
// Shadow mode, nested-only rejection: behave as Action Scheduler did before this change. This is
// reached only when the top-level object is a valid schedule, so the unrestricted parse can no
// longer instantiate a bare top-level gadget.
return @unserialize( $this->source_data ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.serialize_unserialize, WordPress.PHP.NoSilencedErrors.Discouraged
}