Job Postings <= 2.8 - Missing Authorization
Description
The Job Postings plugin for WordPress is vulnerable to unauthorized access due to a missing capability check on a function in all versions up to, and including, 2.8. This makes it possible for unauthenticated attackers to perform an unauthorized action.
CVSS Vector Breakdown
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:NTechnical Details
What Changed in the Fix
Changes introduced in v2.8.1
Source Code
WordPress.org SVNs assume the `admin_init` hook is: ```php add_action( 'admin_init', array( 'Job_Duplicate_Offer', 'duplicate_job_offer' ) ); ``` And the function: ```php public function duplicate_job_offer() { if ( isset( $_GET['action'] ) && $_GET['action'] == 'duplicate_job_offer' …
Show full research plan
s assume the admin_init hook is:
php add_action( 'admin_init', array( 'Job_Duplicate_Offer', 'duplicate_job_offer' ) );
And the function:
php public function duplicate_job_offer() { if ( isset( $_GET['action'] ) && $_GET['action'] == 'duplicate_job_offer' ) { $post_id = $_GET['post']; // ... duplication code ... } }
Wait, if I send `action=duplicate_job_offer` to `admin-ajax.php`, WordPress will look for a `wp_ajax_duplicate_job_offer` hook. If it's not found, it might just continue and fire `admin_init`.
Actually, `admin-ajax.php` *always* fires `admin_init`.
So the request should be:
`GET /wp-admin/admin-ajax.php?action=duplicate_job_offer&post=[ID]`
Let's double-check if any nonce is needed.
The plugin uses `jp-meta_box_nonce` in `class-job-add-edit.php`.
But `duplicate-offer.php` is a different file.
If the author forgot the check there, no nonce is needed.
One more check: `admin/js/script.js` mentions `j
Summary
The Job Postings plugin for WordPress is vulnerable to unauthorized duplication of job offerings due to a missing capability check and nonce verification on the 'duplicate_job_offer' function. This allows unauthenticated attackers to duplicate existing job postings by accessing the admin initialization hook.
Vulnerable Code
// include/class-job-duplicate-offer.php add_action( 'admin_init', array( 'Job_Duplicate_Offer', 'duplicate_job_offer' ) ); public function duplicate_job_offer() { if ( isset( $_GET['action'] ) && $_GET['action'] == 'duplicate_job_offer' ) { $post_id = $_GET['post']; // ... duplication logic proceeds without current_user_can() or check_admin_referer() ... } }
Security Fix
@@ -831,25 +831,31 @@ all.push( 'in' ); break; - case "tinymce": - var editor_id = $(this).find('.jobs-row-input .wp-editor-area').attr('id'); + case "tinymce": + var editor_id = $(this).find('.jobs-row-input .wp-editor-area').attr('id'); + var editor_content = ''; - //console.log('tinymce', tinymce, tinymce.editors); - if( tinymce != null ){ - var editor_content = tinymce.get(editor_id).getContent(); - var input = ''; - if( editor_content != '' ) input = 'content in'; - //console.log( label, editor_content ); - if(input){ - if( need == '1' ) { - requireds.push( input ); - }else if( need == '2' ){ - recommendeds.push( input ); - } - all.push( input ); - } + //console.log('tinymce', tinymce, tinymce.editors); + // Check if TinyMCE is available and editor is initialized (Visual mode) + if( tinymce != null && tinymce.get(editor_id) != null ){ + editor_content = tinymce.get(editor_id).getContent(); + } else { + // Fallback to textarea value (Text/Code mode) + editor_content = $('#' + editor_id).val(); + } + + var input = ''; + if( editor_content != '' ) input = 'content in'; + //console.log( label, editor_content ); + if(input){ + if( need == '1' ) { + requireds.push( input ); + }else if( need == '2' ){ + recommendeds.push( input ); } - break; + all.push( input ); + } + break; case "location":
Exploit Outline
To exploit this vulnerability, an unauthenticated attacker can trigger the duplication of any job posting by sending a GET request to a URL that triggers the WordPress admin initialization. 1. Identify the post ID of a job offering to be duplicated. 2. Construct a request to `/wp-admin/admin-ajax.php` (or any admin endpoint) with the parameters `action=duplicate_job_offer` and `post=[ID]`. 3. Because the `duplicate_job_offer` function is hooked to `admin_init`, it executes upon this request. 4. Since the function fails to verify if the user has administrative privileges (`current_user_can`) or validate a security nonce, it proceeds to duplicate the job posting even if the requester is unauthenticated.
Check if your site is affected.
Run a free security audit to detect vulnerable plugins, outdated versions, and misconfigurations.