Punchwell Security — Audited, Self-Hosted WP HR

Punchwell exists because the plugin it continues was left unmaintained with unpatched security flaws. So security isn’t a footnote here — it’s the reason the project started.

This page is the honest version: what we fixed, how we work, how to report something, and where the original plugin’s known issues stand in the maintained fork. We reference public, already-disclosed information only — no exploit code, no payloads, no drama.

The short version. Punchwell is self-hosted, security-audited, and has had all of the original’s call-home and outbound network code removed and verified. Your team’s data stays in your own WordPress database — the free version makes no outbound calls at all, and the only outbound call Pro makes is validating your license key against our own billing server, never your data. The endpoints behind the original plugin’s publicly disclosed flaws are capability-gated in this fork — and the arbitrary-user-deletion flaw is fixed and verified in source.


Our security posture, in plain English

Four things define how Punchwell treats your data and your site. None are marketing abstractions — each maps to a concrete decision in the code.

1. Audited

The five add-ons went through a multi-agent security audit (2026-06-08) that surfaced 128 findings — 5 critical, 35 high, 51 medium, 37 low. Every critical and high finding was resolved and adversarially verified. The five criticals were the serious kind: a local-file-include leading to remote code execution, privilege escalation on role/capability handlers, a PHP 8 create_function fatal, an unauthenticated file-upload path to RCE, and PHP object injection. A separate pre-launch adversarial audit ran across the base plugin and payroll engine; its actionable findings were fixed too — including an employee being able to set their own pay rate, and a shift-cap default that silently truncated hours.

2. No data call-home

Your employee and attendance data never leaves your server. The free version makes no outbound network calls at all — verified down to zero network primitives in the plugin code and bundled libraries — and the only outbound call Pro makes is validating your license key against our own billing server, never your data. We removed the original’s license-server phone-home, stripped the EDD license handlers from the add-ons, deleted the defunct mishubd.com updaters, and removed a sponsor fetch in a bundled date library. The only external content that ever loads is standard WordPress fare: optional YouTube tutorial embeds and Gravatar avatars. Your timesheets, your roster, your leave records — none of it syncs to anyone’s cloud, because there’s nowhere for it to go.

3. Hardened for the current stack

The original was written for PHP 5.6 and breaks on PHP 8 — white screens after an update, the “add employee” form hanging on the spinner, punch-out failing, profile and department saves stalling. Punchwell is PHP 8 / WordPress 7 / MySQL 8 clean. The data layer was modernized off end-of-life libraries onto a maintained ORM and date stack, and the unsafe legacy database defaults that fatal under MySQL 8 strict mode were removed.

4. You own the data

Self-hosted by design. Employees are just WordPress users; attendance is rows in your own database. There’s no vendor cloud holding your staff records, no account to be locked out of, and — because it’s GPL — no way to be held hostage by a vendor that disappears. Which is exactly what happened to the plugin Punchwell replaces.

This is the same ethos behind the flagship office-IP clock-in lock: it refuses an off-site punch server-side rather than merely logging a location. Enforcement that actually enforces, data that actually stays put. See how the IP lock works.


Security advisory index

The plugin Punchwell continues — the original “WP Human Resource Management” plugin (slug hrm, by wpspear) — was removed from the WordPress.org directory on 2025-07-01 for a “Security Issue.” Its last release was version 2.2.17, around 2019. The vendor is gone and the old update host is defunct.

Below is where each publicly disclosed vulnerability stands in the maintained fork. Each was confirmed on the NVD as of 2026-06-17. We describe these nominatively — to help people still running the abandoned version understand their exposure, not to imply any affiliation.

CVE-2025-5956 — Arbitrary user deletion · CVSS 8.1 (High)

The flaw (original plugin, 2.0.0–2.2.17, unpatched): the employee-delete AJAX action passed client-supplied IDs straight to wp_delete_user() with no capability check. Any logged-in user could delete any account — including administrators.

In Punchwell: specifically fixed and verified in source. The delete handler now requires the delete_users capability, and performs a per-ID delete_user check before anything is removed.

CVE-2025-5953 — Privilege escalation · CVSS 8.8 (High)

The flaw (original plugin, 2.0.0–2.2.17, unpatched): missing authorization on a role-assignment AJAX action let a logged-in employee promote their own account to WordPress administrator.

In Punchwell: the class of flaw is addressed by the project’s hard rule — every privileged AJAX action is gated with current_user_can(), not a nonce alone. We frame this at the class level: we capability-gate the endpoints behind this disclosure. We don’t claim to have individually traced and patched this one specific role handler.

CVE-2019-9574 — Broken access control on leave records · CVSS 7.5 (High)

The flaw (original plugin, before 2.2.6, unpatched): a low-privilege user could modify leave records outside their own authority.

In Punchwell: the leave handlers are capability-gated. Privileged leave actions check the acting user’s capability before changing any record.

The honest framing we hold ourselves to: these CVEs are real, public, and serious — and they affect the original abandoned plugin, not Punchwell. We cite only already-disclosed information, never exploit code. We say “capability-gates the endpoints” and “addresses the class of flaw,” and we never say “unhackable,” “100% secure,” or “guaranteed.” Audited and gated is a strong, true claim. Magic isn’t.

Still running the original on a live site? Don’t guess at your exposure — read the 5-minute security check to see whether you’re affected, then follow the migration path. Your data carries over.


How we actually write the code

The posture above comes from a small set of rules applied everywhere. These are the load-bearing practices, not aspirations.

  • Capability gating on every privileged action. A valid nonce proves the request came from your site — it does not prove the user is allowed to do the thing. So privileged AJAX handlers verify the nonce and call current_user_can() with the right capability. The CVEs above were, at root, nonce-without-capability mistakes. We don’t repeat them.
  • Sanitize on the way in, escape on the way out. Input is cleaned before it’s used; all output is escaped (esc_html, esc_attr, esc_url, wp_kses_post). No raw user data reaches a page or a query.
  • No data call-home. Zero network primitives in the free plugin or its bundled libraries — verified. Nothing transmits your roster or any employee data; the only outbound call Pro makes is validating its license key against our own billing server.
  • CSV-injection guards on every export. Payroll and report exports neutralize spreadsheet-formula injection (the classic =, +, -, @ lead-character trick), so a malicious cell can’t execute when someone opens your CSV.
  • Header-injection guards on email. From-name, Reply-to and CC fields strip carriage returns and line feeds, so notification settings can’t be turned into a mail-header-injection vector.
  • Strict-mode-safe schema. The unsafe 0000-00-00 date defaults that fatal under MySQL 8 were removed; date/time columns default to real NULLs. Schema changes apply through an idempotent reconcile that adds, never deletes data.
  • Clean uninstall. Deactivation clears scheduled tasks; uninstall removes plugin data deliberately, not as a surprise.

Because Punchwell is GPL and self-hosted, you can verify all of this yourself — read the source, audit the network behavior, confirm nothing leaves your server. That’s the point of owning your tools.


Responsible disclosure

If you believe you’ve found a security issue in Punchwell or any of its add-ons, we want to hear from you — and we’ll work with you, not against you.

How to report. Email security@sturdyhaus.com with:

  • A clear description of the issue, the affected component (base plugin or which add-on), and version.
  • Steps to reproduce, and the impact you believe it has.
  • Your environment if relevant (PHP / WordPress / MySQL versions).

Please report privately first and give us a reasonable window to investigate and ship a fix before any public disclosure. We’ll acknowledge your report, keep you updated on remediation, and credit you in the changelog if you’d like the credit.

In scope: the Punchwell base plugin and the bundled add-ons (front-end, recruitment, loan, attendance-report, permission, and the payroll-export engine and its connectors) — issues such as missing authorization, injection, broken access control, insecure file handling, or anything that lets a user act beyond their capability.

Out of scope: your own WordPress core, server, theme, or unrelated third-party plugins; social-engineering or physical attacks; findings that require an already-compromised admin account; and reports consisting only of automated-scanner output with no demonstrated impact. We also can’t speak for the original abandoned plugin — if you’re running that, the fix is to migrate, not to report it to us.

Our commitment back to you. We don’t pursue good-faith researchers who follow this policy. No exploit code is required in your initial report — a description and reproduction steps are enough. This is an independent project, so please don’t expect an enterprise bug-bounty payout — but you will get a real human who maintains the actual code, prompt acknowledgement, and a credit.


Where to track security fixes

Every security-relevant change ships in a version bump with a changelog entry — that’s a release discipline, not a one-off. The current base plugin is version 2.14.1 (database schema 3.3). You can see what changed, and when, on the changelog, and read the broader story of the audit, the call-home removal, and the library modernization on the about page.

When you evaluate any self-hosted plugin’s security, the changelog is the evidence. A maintained project leaves a trail; an abandoned one stops in 2019.


Security FAQ

Were the original plugin’s CVEs actually fixed, or just “addressed”? Both, depending on which one. CVE-2025-5956 (arbitrary user deletion) is specifically fixed and verified in source — the delete handler now requires the delete_users capability and a per-ID check. For CVE-2025-5953 (privilege escalation) we use class-level language honestly: the project’s hard rule capability-gates every privileged endpoint, which addresses the class of flaw, but we don’t claim we individually traced that one specific role handler. CVE-2019-9574’s leave handlers are capability-gated. We’d rather under-claim and be right than over-claim and be caught.

Is Punchwell affiliated with the original plugin or its author? No. Punchwell is an independent, third-party maintained GPL fork. Sturdyhaus is not affiliated with, endorsed by, or sponsored by wpspear, the original author, or weDevs. We reference “WP Human Resource Management” only descriptively — to help people running the abandoned version find a maintained alternative.

You say “no data call-home” — what about the YouTube videos and avatars? The free plugin itself makes zero outbound network calls; we removed and verified that. The only outbound call Pro makes is validating your license key against our own billing server — never your data. The only external content that loads is standard WordPress: optional YouTube tutorial embeds (only if you open them) and Gravatar avatars. No timesheet, roster, or attendance data ever leaves your server, because there’s no code to send it.

Can you guarantee Punchwell is unhackable? No, and you should be suspicious of anyone who claims that about any software. What we can say is true and specific: it’s been audited, the privileged endpoints are capability-gated, all of the original’s outbound network code is removed and verified (Pro’s only outbound call is license validation to our own billing server — never your data), and the office-IP clock-in lock refuses an off-site punch server-side. Self-hosted also means the security perimeter is yours to control. “Audited and gated,” not “magic.”

I’m still on the old plugin and worried — what should I do right now? Start with the 5-minute security check to understand your exposure, then follow the migration guide. It’s a migration, not a rebuild — your employees, attendance, and leave records carry over via a documented script, and it’s reversible if you back up first.

Does the security story have anything to do with the flagship feature? Directly. The same principle — enforce server-side, keep data local — is why the office-IP clock-in lock blocks an off-site punch instead of just recording it, and why none of that location data is ever transmitted off your server. Security and the differentiator are the same idea applied twice.


Run HR on a plugin that’s actually maintained

The original plugin was delisted in 2025 with the flaws above still open. Punchwell is the hardened, PHP 8–ready continuation — audited, capability-gated, no data call-home, your data on your own server.

If you’re on the old version, the responsible next step is simple and low-risk:

Read the 5-minute security check → /punchwell/migrate/ Your employees, attendance, and leave records carry over. It’s a migration, not a rebuild — and reversible if you back up first.

Prefer to evaluate first? Download the free version on WordPress.org or see how the IP lock works.


Independent GPL fork. Punchwell is an independent, third-party maintained fork of the GPL-licensed “WP Human Resource Management” plugin. Sturdyhaus is not affiliated with, endorsed by, or sponsored by wpspear, weDevs, or the original author. Product names are referenced descriptively (nominative fair use) only, to identify the software lineage. All third-party names and trademarks belong to their respective owners.

Punchwell, by Sturdyhaus.