Skip to content

The UTC/site-local timestamp split still exists in the checkout_attempts and detections tables #55

Description

@cport1

#51 fixed this class of bug in wp_webdecoy_blocked_ips. The same defect remains in two other
tables, found while reviewing the 2.3.2 diff (PR #54) and deliberately left out of a safety release.

Both are unverified — the verification agents that would have confirmed them died mid-review.
Treat the line references as leads, not findings.

1. wp_webdecoy_checkout_attempts.created_at

Written with current_time('mysql') (site-local) at includes/class-webdecoy-woocommerce.php:217,
read against a gmdate()-generated threshold in get_recent_attempts() (:290).

Consequence: on a site east of UTC the window is wider than configured, and west of UTC it is
narrower — so checkout velocity and card-testing detection operate over the wrong window. The
direction of the error depends on the sign of gmt_offset, which is why it has never looked broken.

2. detections.created_at vs the Detections page date filters

Written site-local at includes/class-webdecoy-detector.php:245, webdecoy.php:1744, :1851,
:2558, and includes/class-webdecoy-woocommerce.php:350. The Today / 7d / 30d quick filters build
their bounds with gmdate('Y-m-d') in admin/partials/detections-page.php.

Consequence: "Today" is the wrong day for part of every day on any non-UTC site.

Work

  • Verify both, with the actual line numbers, before changing anything
  • Pick one convention — UTC in the database, converted at the display boundary via
    get_date_from_gmt() — and apply it to both tables
  • Decide what happens to existing rows written under the old mixed semantics. A migration that
    shifts them all by the current offset is wrong for any site that has changed timezone.
  • Add a test that fails when a write and its matching read disagree on timezone

Why not in 2.3.2

A safety release should reduce blast radius, not rewrite timestamp semantics across three tables.
The block table was in scope because a wrong comparison there meant blocking silently did nothing.
These two only skew a reporting window.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal prioritybugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions