WP Manifestindependent plugin directory
manifest / content / crewhrm

Crew HRM WP Registry grade D+. High-severity findings · 3 findingsWP RegistryHigh-severity findings · 3 findingsOpen the reportD+

WordPress Job Board Plugin for Online Recruitment

★ 7stars
67release downloads
≈10active sites
1.1.6latest · 2 years ago

Install

Download hr-management-1.0.9.zip From the 1.0.9 release on GitHub, Mar 15, 2024

Upload it under Plugins → Add New Plugin → Upload Plugin, then activate.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/crewhrm/crewhrm/releases/download/1.0.9/hr-management-1.0.9.zip
No built-in updater. New versions won't appear under Dashboard → Updates. Install new releases yourself, or let Git Updater track the repository.

Crew HRM

WordPress Plugin for human resource management system. This is the free version repository where you can report bugs, vote on feature ideas, etc.

Please send pull requests if you find security issues or want to help us fix bugs.

To discuss ideas with us in private, please use the contact form on our website https://getcrewhrm.com/contact/

Production Deployment

Download production build from WordPress Plugin Directory or Github Releases.

Development environment setup

  • Open terminal at ~/wp-content/plugins/ directory
  • Run git clone https://github.com/CrewHRM/CrewHRM.git
  • Run cd CrewHRM
  • Run npm install
  • Run npm run build to compile scirpts in production mode and create releasable zip file.
  • Or, Run npm run watch if you'd like the codes to be compiled in development mode and need continuous compilation on code changes.

If it is cloned already, and need to pull updated codebase then

  • open terminal at ~wp-content/plugins/CrewHRM/
  • run git pull
  • and then npm run build or npm run watch

Whenever you pull updates to local repository, don't forget to run npm install and npm run build or watch again.

Releases

10 releases. Each count is every asset in that release; expand a row for the breakdown.

Tag
Published
Assets
Downloads
1.1.6 latest
Sep 22, 2024 2 years ago
tag only
—
Sep 22, 2024 2 years ago
tag only
—
May 18, 2024 2 years ago
tag only
—
Mar 15, 2024 2 years ago
hr-management-1.0.9.zip
7
Feb 22, 2024 2 years ago
hr-management-1.0.8.zip
8
Feb 10, 2024 2 years ago
crewhrm-1.0.7.zip
8
Jan 29, 2024 2 years ago
crewhrm-1.0.6.zip
11
Dec 9, 2023 2 years ago
crewhrm-1.0.5.zip
12
Nov 30, 2023 2 years ago
crewhrm-1.0.4.zip
13
Nov 19, 2023 2 years ago
crewhrm-1.0.3.zip
8

Active-site estimate ≈10 comes from the median of recent superseded releases. Method.

D+ grade

Security

Crew HRM 1.0.9 · audited by WP Registry

High-severity findings.

2 high 1 medium
Audited release
1.0.9
Findings
3
Worst severity
high
Content hash
aca17d7ffd1a09b31e83e595…

Findings

  • high Unauthenticated PHP object injection via maybe_unserialize on all AJAX input (CVE-2024-43252)

    unsafe_unserialize

    Every CrewHRM AJAX request is funneled through Dispatcher::dispatch, which wp_unslashes chosen POST/GET keys and then runs _Array::sanitizeRecursive. For each string, that helper calls sanitize_text_field and then _String::castValue, whose else-branch is maybe_unserialize($value) with no allowed_classes restriction. Type-checking only looks at the top-level parameter (array vs string vs int), so a serialized object placed in a nested key of an array argument still instantiates. Two handlers are wp_ajax_nopriv (applyToJob, getCareersListing) and a date-based nonce is localized on every frontend page for uid 0, so an unauthenticated visitor can trigger object instantiation. This plugin contains no POP gadgets of its own; if another component provides a chain, the result is file delete, option/user tampering, or RCE. Wordfence/Patchstack published this as CVE-2024-43252 (Crew HRM <= 1.1.1, patched in 1.1.2). Version 1.0.9 is in the affected range.

    classes/Helpers/_String.php:127-157

    Recommendation

    Do not unserialize request data. Cast only scalars (bool/int/float/null) and leave remaining strings as strings. If unserialize is required for stored meta, use unserialize($data, ['allowed_classes' => false]) and reject payloads matching /^O:\d+:/. Upgrade to 1.1.2+ which added _String::maybe_unserialize with an object block.

  • high Any logged-in user can list, archive, duplicate, or delete jobs (empty AJAX role)

    missing_capability

    JobManagement::PREREQUISITES sets getJobsDashboard and singleJobAction to an empty array (no role, no nopriv). Dispatcher treats missing/empty role as $required_roles = [] and User::validateRole() returns true whenever $role is empty, so the only gate is WordPress's logged-in wp_ajax_ hook plus a nonce. Scripts::loadVariables prints that nonce (action _crewhrm_Y_m_d) on every frontend page, including for Subscriber and the plugin's own crewhrm-employee role (capability: read). A Subscriber can POST action=crewhrm_getJobsDashboard with filters[page]=1 and receive every job (draft/archive/publish), descriptions, application forms, and per-stage candidate counts. The same user can POST action=crewhrm_singleJobAction with job_action=delete|archive|unarchive|duplicate. delete calls Job::deleteJob which removes the job row, stages, address, and Application::deleteApplicationByJobId (applicant PII and resumes). Other job endpoints (updateJob, getSingleJobEdit, getJobViewDashboard) correctly require administrator; these two were left unrestricted.

    classes/Controllers/JobManagement.php:21-27,100-148

    Recommendation

    Set 'role' => array( 'administrator' ) (and any intentional HR roles via crewhrm_hr_roles) on getJobsDashboard and singleJobAction. Change validateRole so an empty role list is deny-by-default, not allow. Do not localize dashboard nonces on unauthenticated/frontend pages.

  • medium Unauthenticated IDOR: upload or replace files on any incomplete application

    missing_auth

    uploadApplicationFile is registered with nopriv => true. After nonce check it only verifies that application_id exists and is_complete=0, then FileManager::uploadFile() runs wp_handle_upload (test_form false, no extra MIME allow-list) and, for field_name=resume, writes resume_file_id on that row. Application IDs are autoincrement integers returned by applyToJob and remain incomplete until finalize or the twicedaily cleaner (up to ~12 hours). An unauthenticated caller who guesses or observes a recent ID can attach an arbitrary WordPress-allowed file as that candidate's resume or mark the application complete via finalize=true, substituting attacker content into the hiring pipeline. Frontend claims resume accept=.pdf but the server does not enforce it.

    classes/Controllers/ApplicationHandler.php:26-31,109-131

    Recommendation

    Bind uploads to the application with an unguessable token created at applyToJob (store a random capability hash, require it on upload/finalize). Enforce an allow-list of MIME/extensions server-side (PDF for resume). Reject uploads whose application_id was not created in the same session.

WP Registry hashes the installable build and reports on that exact bytes-for-bytes copy. Embargoed findings are withheld until they are disclosed, so a clean verdict means nothing public is outstanding. WP Manifest does not audit code itself.