Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/career-section/include/dashboard_widget.php
+++ b/career-section/include/dashboard_widget.php
@@ -26,14 +26,24 @@
</thead>
<tbody>
<?php
- global $wpdb;
- $table_name = $wpdb->prefix . "cs_applicant_submissions";
+ global $wpdb;
-
- $user = $wpdb->get_results( $wpdb->prepare(
- "SELECT * FROM " . $wpdb->prefix . "cs_applicant_submissions ORDER BY ID DESC LIMIT %d",
- 5
- ) );
+ $cache_key = 'cs_applicant_latest_5';
+ $cache_group = 'cs_applicant';
+
+ // try to get from cache
+ $user = wp_cache_get( $cache_key, $cache_group );
+
+ if ( false === $user ) {
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
+ $user = $wpdb->get_results(
+ $wpdb->prepare(
+ "SELECT * FROM {$wpdb->prefix}cs_applicant_submissions ORDER BY ID DESC LIMIT %d",5
+ )
+ );
+ // save to cache (10 minutes)
+ wp_cache_set( $cache_key, $user, $cache_group, 600 );
+ }
// $user = $wpdb->get_results( "SELECT * FROM {$table_name} ORDER BY ID DESC LIMIT 5" );
$i = 0;
--- a/career-section/include/enqueue.php
+++ b/career-section/include/enqueue.php
@@ -14,7 +14,7 @@
}add_action('wp_enqueue_scripts','csaf_add_css_js');
function csaf_admin_enqueue($hook) {
- if ( 'csection_page_appform' == $hook ) {
+ if ( 'csection_page_csaf_appform' == $hook ) {
wp_enqueue_style('af-admin-css', plugin_dir_url( __FILE__ ). '../css/admin.css', array(), '1.0.0', 'all');
wp_enqueue_script('af_custom_js', plugin_dir_url(__FILE__) . '../js/custom.js' , array('jquery'),'1.0.0',true);
}
--- a/career-section/include/posttype.php
+++ b/career-section/include/posttype.php
@@ -3,8 +3,8 @@
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
-add_action( 'init', 'career_section_posttype' );
-function career_section_posttype() {
+add_action( 'init', 'csaf_posttype' );
+function csaf_posttype() {
$labels = array(
'name' => _x( 'Career Section', 'post type general name', 'career-section' ),
'singular_name' => _x( 'Career Section', 'post type singular name', 'career-section' ),
@@ -40,8 +40,8 @@
register_post_type( 'csection', $args );
}
//gallery Taxonomy
-add_action( 'init', 'csection_taxonomy', 0 );
-function csection_taxonomy() {
+add_action( 'init', 'csaf_taxonomy', 0 );
+function csaf_taxonomy() {
// Add new taxonomy, make it hierarchical (like categories)
$labels = array(
'name' => _x( 'CS Category', 'taxonomy general name', 'career-section' ),
--- a/career-section/include/top_level_menu.php
+++ b/career-section/include/top_level_menu.php
@@ -12,8 +12,8 @@
'View Entries',
'View Entries',
'manage_options',
- 'appform',
- 'appform_options_page_html'
+ 'csaf_appform',
+ 'csaf_appform_options_page_html'
);
}
/**
@@ -23,7 +23,7 @@
/**
* Top level menu callback function
*/
-function appform_options_page_html() {
+function csaf_appform_options_page_html() {
// check user capabilities
if ( ! current_user_can( 'manage_options' ) ) {
return;
@@ -46,6 +46,7 @@
//delete db raw
global $wpdb;
$table_name = $wpdb->prefix . "cs_applicant_submissions";
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->delete( $table_name, array( 'id' => sanitize_text_field($delete_id)) );
//delete files
global $wp_filesystem;
@@ -127,6 +128,7 @@
<?php
global $wpdb;
// $table_name = $wpdb->prefix . "cs_applicant_submissions";
+ // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$user = $wpdb->get_results( "SELECT * FROM ". $wpdb->prefix . "cs_applicant_submissions" );
$i = 0;
foreach ($user as $row){
--- a/career-section/index.php
+++ b/career-section/index.php
@@ -5,7 +5,7 @@
* Description: Install and send your CV.
* Author: Md. Shahinur Islam
* Author URI: https://profiles.wordpress.org/shahinurislam
- * Version: 1.7
+ * Version: 1.8
* Text Domain: career-section
* Network: True
* License: GPLv2
@@ -25,14 +25,14 @@
require_once CSAF_PLUGIN_DIR . '/include/dashboard_widget.php';
require_once CSAF_PLUGIN_DIR . '/include/top_level_menu.php';
//-------------- Load Custom post type Single page --------------------//
-function csection_single_template( $template ) {
+function csaf_single_template( $template ) {
global $post;
if ( 'csection' === $post->post_type) {
return plugin_dir_path( __FILE__ ) . 'templates/single-csection.php';
}
return $template;
}
-add_filter( 'single_template', 'csection_single_template' );
+add_filter( 'single_template', 'csaf_single_template' );
//db create------------------------------------
global $csaf_jal_db_version;
@@ -41,10 +41,10 @@
global $wpdb;
global $csaf_jal_db_version;
- $table_name = $wpdb->prefix . 'cs_applicant_submissions';
+ $csaf_table_name = $wpdb->prefix . 'cs_applicant_submissions';
$charset_collate = $wpdb->get_charset_collate();
- $sql = "CREATE TABLE $table_name (
+ $csaf_sql = "CREATE TABLE $csaf_table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
first_name tinytext NOT NULL,
last_name tinytext NOT NULL,
@@ -58,18 +58,18 @@
) $charset_collate;";
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
- dbDelta( $sql );
+ dbDelta( $csaf_sql );
add_option( 'csaf_jal_db_version', $csaf_jal_db_version );
}
register_activation_hook( __FILE__, 'csaf_jal_install' );
global $wpdb;
-$installed_ver = get_option( "csaf_jal_db_version" );
-if ( $installed_ver != $csaf_jal_db_version ) {
+$csaf_installed_ver = get_option( "csaf_jal_db_version" );
+if ( $csaf_installed_ver != $csaf_jal_db_version ) {
- $table_name = $wpdb->prefix . 'cs_applicant_submissions';
+ $csaf_table_name = $wpdb->prefix . 'cs_applicant_submissions';
- $sql = "CREATE TABLE $table_name (
+ $csaf_sql = "CREATE TABLE $csaf_table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
first_name tinytext NOT NULL,
last_name tinytext NOT NULL,
@@ -83,7 +83,7 @@
);";
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
- dbDelta( $sql );
+ dbDelta( $csaf_sql );
update_option( "csaf_jal_db_version", $csaf_jal_db_version );
}
@@ -183,7 +183,7 @@
$cs_qualification = get_post_meta($post->ID,'cs_qualification',true);
$cs_gender = get_post_meta($post->ID,'cs_gender',true);
$cs_deadline = get_post_meta($post->ID,'cs_deadline',true);
- wp_nonce_field('save_csaf_meta','name_nonce');
+ wp_nonce_field('csaf_save_csaf_meta','name_nonce');
?>
<p><label>Company Logo URL </label><input type="text" name="cs_logo" value="<?php echo esc_html($cs_logo);?>" placeholder="link" /></p>
@@ -197,13 +197,13 @@
<?php
}
- function save_csaf_meta($post_id){
+ function csaf_save_csaf_meta($post_id){
//Check if our nonce is set
if(! isset($_POST['name_nonce'])){
return;
}
//Check if our nonce is valid
- if(! wp_verify_nonce( sanitize_text_field(wp_unslash($_POST['name_nonce'])),'save_csaf_meta')){
+ if(! wp_verify_nonce( sanitize_text_field(wp_unslash($_POST['name_nonce'])),'csaf_save_csaf_meta')){
return;
}
// Make sure that it(input) is set.
@@ -253,5 +253,47 @@
update_post_meta($post_id,'cs_deadline',$my_cs_deadline);
}
- add_action('save_post','save_csaf_meta');
+ add_action('save_post','csaf_save_csaf_meta');
+
+ function csaf_download_cv() {
+
+ // 1. Capability check
+ if ( ! current_user_can( 'manage_options' ) ) {
+ wp_die( 'Unauthorized' );
+ }
+
+ // 2. NONCE CHECK (IMPORTANT FIX)
+ if (
+ ! isset( $_GET['cs_nonce'] ) ||
+ ! wp_verify_nonce( sanitize_text_field(wp_unslash( $_GET['cs_nonce'] )), 'csaf_download_cv' )
+ ) {
+ wp_die( 'Invalid request' );
+ }
+
+ // 3. Validate input existence
+ if ( ! isset( $_GET['file'] ) ) {
+ wp_die( 'File not specified' );
+ }
+
+ // 4. Unsplash + sanitize
+ $file = sanitize_file_name( wp_unslash( $_GET['file'] ) );
+
+ $upload_dir = wp_upload_dir();
+ $path = $upload_dir['basedir'] . '/cs_applicant_submission_files/' . $file;
+
+ if ( file_exists( $path ) ) {
+
+ header( 'Content-Type: application/octet-stream' );
+ header( 'Content-Disposition: attachment; filename="' . basename( $path ) . '"' );
+
+ // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile
+ readfile( $path );
+ exit;
+ }
+
+ wp_die( 'File not found' );
+ }
+
+add_action( 'admin_post_csaf_download_cv', 'csaf_download_cv' );
+add_action( 'admin_post_nopriv_csaf_download_cv', 'csaf_download_cv' ); // 🔥 مهم
?>
--- a/career-section/templates/single-csection.php
+++ b/career-section/templates/single-csection.php
@@ -138,6 +138,7 @@
<!-- insert data -->
<?php
+
if ( isset( $_POST['first_name'], $_POST['csaf_form_nonce'] ) ){
require_once( ABSPATH . 'wp-admin/includes/file.php' );
@@ -145,10 +146,10 @@
require_once( ABSPATH . 'wp-admin/includes/media.php' );
// Unsanitize POST data
- $nonce = sanitize_text_field(wp_unslash( $_POST['csaf_form_nonce'] ));
- $first_name = sanitize_text_field( wp_unslash( $_POST['first_name'] ) );
+ $csaf_nonce = sanitize_text_field(wp_unslash( $_POST['csaf_form_nonce'] ));
+ $csaf_first_name = sanitize_text_field( wp_unslash( $_POST['first_name'] ) );
// Verify nonce
- if ( ! wp_verify_nonce( $nonce, 'csaf_form_submission' ) ) {
+ if ( ! wp_verify_nonce( $csaf_nonce, 'csaf_form_submission' ) ) {
wp_die( esc_html__( 'Nonce verification failed', 'career-section' ) );
}
@@ -157,67 +158,116 @@
WP_Filesystem();
// Define custom folder inside uploads
- $upload_dir = wp_upload_dir();
- $cs_dir = $upload_dir['basedir'] . '/cs_applicant_submission_files';
+ $csaf_upload_dir = wp_upload_dir();
+ $csaf_dir = $csaf_upload_dir['basedir'] . '/cs_applicant_submission_files';
+
+ if ( ! file_exists( $csaf_dir ) ) {
+ wp_mkdir_p( $csaf_dir ); // WordPress-approved directory creation
+ }
- if ( ! file_exists( $cs_dir ) ) {
- wp_mkdir_p( $cs_dir ); // WordPress-approved directory creation
+ //create htaccess
+ $csaf_htaccess = $csaf_dir . '/.htaccess';
+ if ( ! file_exists( $csaf_htaccess ) ) {
+ file_put_contents( $csaf_htaccess, "php_flag engine offn<FilesMatch "\.php$">nDeny from alln</FilesMatch>");
}
- $cvfiles = "without your cv.";
- $uploaded_file_url = '';
+ $csaf_cvfiles = "without your cv.";
+ $csaf_uploaded_file_url = '';
if ( ! empty( $_FILES['cv']['name'] ) && ! empty( $_FILES['cv']['tmp_name'] ) ) {
+ $csaf_allowed_types = array(
+ 'pdf' => 'application/pdf',
+ 'doc' => 'application/msword',
+ 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+ );
+ // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
+ $csaf_file = $_FILES['cv'];
+ // Validate file type
+ $csaf_filetype = wp_check_filetype_and_ext( $csaf_file['tmp_name'], $csaf_file['name'], $csaf_allowed_types );
+
+ if ( ! $csaf_filetype['ext'] || ! $csaf_filetype['type'] ) {
+ wp_die( 'Invalid file type. Only PDF/DOC/DOCX allowed.' );
+ }
+ // Rename file (IMPORTANT)
+ $csaf_name_file = wp_generate_password( 32, false ) . '.' . $csaf_filetype['ext'];
+
// Sanitize filename
- $original_name = sanitize_file_name( $_FILES['cv']['name'] );
- $name_file = time() . '_' . $original_name;
- $destination = $cs_dir . '/' . $name_file;
-
- // Use WP_Filesystem to move the file instead of move_uploaded_file()
- if ( $wp_filesystem->move( $_FILES['cv']['tmp_name'], $destination, true ) ) {
- $cvfiles = "with your cv.";
- $uploaded_file_url = $upload_dir['baseurl'] . '/cs_applicant_submission_files/' . $name_file;
- }
- }
+ // $csaf_original_name = sanitize_file_name( $_FILES['cv']['name'] );
+ // $csaf_name_file = time() . '_' . $csaf_original_name;
+ $csaf_destination = $csaf_dir . '/' . $csaf_name_file;
+
+ $csaf_file['name'] = $csaf_name_file;
+
+ function csaf_custom_upload_dir( $dirs ) {
+ $dirs['subdir'] = '/cs_applicant_submission_files';
+ $dirs['path'] = $dirs['basedir'] . '/cs_applicant_submission_files';
+ $dirs['url'] = $dirs['baseurl'] . '/cs_applicant_submission_files';
+
+ return $dirs;
+ }
+
+ // set custom upload dir
+ add_filter( 'upload_dir', 'csaf_custom_upload_dir' );
+
+ $csaf_upload = wp_handle_upload( $csaf_file, array(
+ 'test_form' => false,
+ 'mimes' => $csaf_allowed_types,
+ ));
+
+ remove_filter( 'upload_dir', 'csaf_custom_upload_dir' );
+
+ if ( isset( $csaf_upload['error'] ) ) {
+ wp_die( esc_html( $csaf_upload['error'] ));
+ } else{
+ $csaf_cvfiles = "with your cv.";
+ $csaf_uploaded_file_url = $csaf_upload['url'];
+ $csaf_name_file = basename($csaf_upload['file']);
+ // $download_link = admin_url('admin-post.php?action=cs_download_cv&file=' . $csaf_name_file);
+ $csaf_download_link = wp_nonce_url(
+ admin_url( 'admin-post.php?action=csaf_download_cv&file='.rawurlencode( $csaf_name_file ) ),
+ 'csaf_download_cv', 'cs_nonce'
+ );
+ }
+ }
// for email reciepnt
-$email_reciepnt_message = '<p>Attachments: <b><a href="'.wp_upload_dir()['baseurl'].'/cs_applicant_submission_files/'.sanitize_text_field($name_file).'">Download</a><b></p>';
+$csaf_email_reciepnt_message = '<p>Attachments: <b><a href="'.esc_url($csaf_download_link).'">Download</a><b></p>';
// if files not found
if($_FILES['cv']['name'] == '' || $_FILES['cv']['name'] == null){
- $name_file = '';
+ $csaf_name_file = '';
// for email reciepnt
- $email_reciepnt_message = '<p>Attachments: No File Attached.</p>';
+ $csaf_email_reciepnt_message = '<p>Attachments: No File Attached.</p>';
}
global $wpdb;
// $table_name = $wpdb->prefix."cs_applicant_submissions";
// Unsanitize and sanitize all POST fields safely
-$first_name = isset($_POST['first_name']) ? sanitize_text_field(wp_unslash($_POST['first_name'])) : '';
-$last_name = isset($_POST['last_name']) ? sanitize_text_field(wp_unslash($_POST['last_name'])) : '';
-$present_address = isset($_POST['present_address']) ? sanitize_text_field(wp_unslash($_POST['present_address'])) : '';
-$email_address = isset($_POST['email_address']) ? sanitize_text_field(wp_unslash($_POST['email_address'])) : '';
-$mobile_no = isset($_POST['mobile_no']) ? sanitize_text_field(wp_unslash($_POST['mobile_no'])) : '';
-$post_name = isset($_POST['post_name']) ? sanitize_text_field(wp_unslash($_POST['post_name'])) : '';
-$cv_file = isset($name_file) ? sanitize_text_field($name_file) : ''; // uploaded file name
-
+$csaf_first_name = isset($_POST['first_name']) ? sanitize_text_field(wp_unslash($_POST['first_name'])) : '';
+$csaf_last_name = isset($_POST['last_name']) ? sanitize_text_field(wp_unslash($_POST['last_name'])) : '';
+$csaf_present_address = isset($_POST['present_address']) ? sanitize_text_field(wp_unslash($_POST['present_address'])) : '';
+$csaf_email_address = isset($_POST['email_address']) ? sanitize_email(wp_unslash($_POST['email_address'])) : '';
+$csaf_mobile_no = isset($_POST['mobile_no']) ? sanitize_text_field(wp_unslash($_POST['mobile_no'])) : '';
+$csaf_post_name = isset($_POST['post_name']) ? sanitize_text_field(wp_unslash($_POST['post_name'])) : '';
+$csaf_cv_file = isset($csaf_name_file) ? sanitize_text_field($csaf_name_file) : ''; // uploaded file name
+// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
$wpdb->query( $wpdb->prepare( "INSERT INTO ".$wpdb->prefix."cs_applicant_submissions (first_name, last_name, present_address, email_address, mobile_no, post_name, cv ) VALUES ( %s, %s, %s, %s, %s, %s, %s )",
- $first_name,
- $last_name,
- $present_address,
- $email_address,
- $mobile_no,
- $post_name,
- $cv_file));
+ $csaf_first_name,
+ $csaf_last_name,
+ $csaf_present_address,
+ $csaf_email_address,
+ $csaf_mobile_no,
+ $csaf_post_name,
+ $csaf_cv_file));
// get the inserted record id.
$id = $wpdb->insert_id;
if($id>0){
?>
- <div id="snackbar" class="rounded">Application has been sent <?php echo esc_html($cvfiles);?></div>
+ <div id="snackbar" class="rounded">Application has been sent <?php echo esc_html($csaf_cvfiles);?></div>
<script>
var x = document.getElementById("snackbar");
x.className = "show";
@@ -230,34 +280,34 @@
}
add_filter( 'wp_mail_from_name', 'csaf_sender_name' );
//user notification
- $to = sanitize_email($_POST['email_address']);
- $subject = 'Thanks for application';
- $body = 'Dear, Thanks for application. We will contact soon.';
- $headers = array('Content-Type: text/html; charset=UTF-8');
- wp_mail( $to, $subject, $body, $headers );
+ $csaf_to = sanitize_email(wp_unslash($_POST['email_address']));
+ $csaf_subject = 'Thanks for application';
+ $csaf_body = 'Dear, Thanks for application. We will contact soon.';
+ $csaf_headers = array('Content-Type: text/html; charset=UTF-8');
+ wp_mail( $csaf_to, $csaf_subject, $csaf_body, $csaf_headers );
if(!empty(esc_html(get_option('email_recipint'))) || esc_html(get_option('email_recipint')) !== null){
//Email Receipint notification
- $to = esc_html(get_option('email_recipint'));
- $subject = 'Application For '.sanitize_text_field($_POST['post_name']);
- $message = '<html><body>';
- $message .= '<h1>'.esc_html(get_bloginfo("name")).' Career Application</h1>';
- $message .= '<p>First Name: <b>'.sanitize_text_field($_POST['first_name']).'<b></p>';
- $message .= '<p>Last Name: <b>'.sanitize_text_field($_POST['last_name']).'<b></p>';
- $message .= '<p>Present Address: <b>'.sanitize_text_field($_POST['present_address']).'<b></p>';
- $message .= '<p>Email: <b>'.sanitize_text_field($_POST['email_address']).'<b></p>';
- $message .= '<p>Mobile: <b>'.sanitize_text_field($_POST['mobile_no']).'<b></p>';
- $message .= '<p>Post Name: <b>'.sanitize_text_field($_POST['post_name']).'<b></p>';
- $message .= $email_reciepnt_message;
- $message .= '</body></html>';
- $body = $message;
- $headers = array('Content-Type: text/html; charset=UTF-8');
- wp_mail( $to, $subject, $body, $headers );
+ $csaf_to = esc_html(get_option('email_recipint'));
+ $csaf_subject = 'Application For '.sanitize_text_field(wp_unslash($_POST['post_name']));
+ $csaf_message = '<html><body>';
+ $csaf_message .= '<h1>'.esc_html(get_bloginfo("name")).' Career Application</h1>';
+ $csaf_message .= '<p>First Name: <b>'.sanitize_text_field(wp_unslash($_POST['first_name'])).'<b></p>';
+ $csaf_message .= '<p>Last Name: <b>'.sanitize_text_field(wp_unslash($_POST['last_name'])).'<b></p>';
+ $csaf_message .= '<p>Present Address: <b>'.sanitize_text_field(wp_unslash($_POST['present_address'])).'<b></p>';
+ $csaf_message .= '<p>Email: <b>'.sanitize_email(wp_unslash($_POST['email_address'])).'<b></p>';
+ $csaf_message .= '<p>Mobile: <b>'.sanitize_text_field(wp_unslash($_POST['mobile_no'])).'<b></p>';
+ $csaf_message .= '<p>Post Name: <b>'.sanitize_text_field(wp_unslash($_POST['post_name'])).'<b></p>';
+ $csaf_message .= $csaf_email_reciepnt_message;
+ $csaf_message .= '</body></html>';
+ $csaf_body = $csaf_message;
+ $csaf_headers = array('Content-Type: text/html; charset=UTF-8');
+ wp_mail( $csaf_to, $csaf_subject, $csaf_body, $csaf_headers );
}
}else{
?>
- <div id="snackbar" class="rounded">Application not sent <?php echo esc_html($cvfiles);?></div>
+ <div id="snackbar" class="rounded">Application not sent <?php echo esc_html($csaf_cvfiles);?></div>
<script>
var x = document.getElementById("snackbar");
x.className = "show";
@@ -310,7 +360,7 @@
<input type="text" name="post_name" value="<?php the_title();?>" class="form-control-af" id="exampleInputPostname" aria-describedby="Post" required>
</div>
<div class="afmb-3">
- <label for="exampleInputPostname" class="form-label-af">Upload CV (PDF,DOCS,JPG ETC)</label>
+ <label for="exampleInputPostname" class="form-label-af">Upload CV (PDF,DOC)</label>
<input type="file" name="cv" class="form-control-af" id="exampleInputPostname" aria-describedby="cv_upload" multiple="false">
</div>
<?php wp_nonce_field( 'csaf_form_submission', 'csaf_form_nonce' ); ?>