Submit Feedback feature doesn’t filter submitted Text. So, Attacker can submit malicious script. For example, the malicious script can be use to steal cookie or other information with Cross Site Scripting (XSS) Attack.
public function save_survey_response(WP_REST_Request $request)
{ if (!wp_verify_nonce($request->get_param('nonce'), "userfeedback_survey_submission-{$request['id']}")) {
return new WP_REST_Response(null, 403);
}
$survey_id = $request['id'];
$id_address = UserFeedback_Device_Detect::ip();
$os = UserFeedback_Device_Detect::os();
$browser = UserFeedback_Device_Detect::browser();
$device = UserFeedback_Device_Detect::deviceType();
// Validate Answers
$validation = $this->validate_response_answers($request->get_json_params()['answers'], $survey_id);
if (!$validation['success']) {
$status = isset($validation['status']) ? $validation['status'] : 400;
return new WP_REST_Response(
array(
'success' => false,
'errors' => $validation['errors'],
),
$status
);
}
$response_id = UserFeedback_Response::create(
array_merge(
$request->get_json_params(),
array(
'survey_id' => sanitize_text_field($survey_id),
'user_ip' => $id_address,
'user_browser' => $browser,
'user_os' => $os,
'user_device' => $device,
)
)
);
do_action('userfeedback_survey_response', $survey_id, $response_id, $request->get_json_params());
return new WP_REST_Response(
array(
'success' => true,
'response_id' => $response_id,
)
);
}
When a user or visitor submits their feedback, the code will run the function save_survey_response() and capture the submission from the visitor/user with the function $request->get_json_params(). After that, the code will call the create() function from the class UserFeedback_Response. See the code below..
public static function create( $args, $new_timestamps = true ) {
global $wpdb; $instance = new static();// self::get_instance();
$table = $instance->get_table();
foreach ( $args as $key => $value ) {
if ( ! in_array( $key, $instance->get_columns() ) ) {
unset( $args[ $key ] );
}
}
$params = $args;
if ( $new_timestamps ) {
$params = array_merge(
$params,
array(
$instance->timestamp_column => current_time( 'mysql' ),
)
);
}
$params = $instance->encode_entity_attributes( $params );
$wpdb->insert( $table, $params );
return $wpdb->insert_id;
}
If we look at the code above, the create() function will process the input from the visitor to the database with the $wpdb->insert(). However during this process, the input from the visitor is not filtered, so the visitor can send malicious code/scripts.
This vulnerability has been patched on version 1.0.8, before the submitted text from users/visitor is saved to database, it will be sanitized using sanitize_text_field()
1. Install wordpress and run on your local server. Then install UserFeedback <= 1.0.7 Plugin
2. Setup New Surveys with Long Answer question type.
3. Logout from admin account.
4. Open home page and click a Post.
5. Fill the feedback form with XSS payload and click submit. We can submit survey as Visitor/Guest.
<img src=x onerror=”alert(document.cookie)” />
6. Login with admin account and check the results page -> click surveys -> individual response.
7. Alert popup will be shown