Skip to content

Instantly share code, notes, and snippets.

@matb33
Last active October 20, 2016 08:28
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matb33/5092416 to your computer and use it in GitHub Desktop.
Save matb33/5092416 to your computer and use it in GitHub Desktop.
WordPress plugin that protects resume uploads for the Job Manager plugin (http://pento.net/projects/wordpress-job-manager-plugin/)
Create this folder:
/wp-content/plugins/job-manager-private-uploads/
Put the two PHP files in there, then activate this plugin via the WordPress admin.
NOTE: your WordPress installation should be configured to allow WP_Rewrite to make modifications to the .htaccess file.
<?php
require_once "../../../wp-config.php";
require_once "job-manager-private-uploads.php";
if (current_user_can("upload_files")) {
$filename = $_GET["f"];
$fullFilename = ABSPATH . $filename;
$fileExtension = strtolower(substr(strrchr($filename, "."), 1));
$attachmentFilename = str_replace(JobManagerPrivateUploads::$privacyPrefix, "", $filename);
switch ($fileExtension) {
case "pdf": $contentType = "application/pdf"; break;
case "exe": $contentType = "application/octet-stream"; break;
case "zip": $contentType = "application/zip"; break;
case "doc": $contentType = "application/msword"; break;
case "xls": $contentType = "application/vnd.ms-excel"; break;
case "ppt": $contentType = "application/vnd.ms-powerpoint"; break;
case "gif": $contentType = "image/gif"; break;
case "png": $contentType = "image/png"; break;
case "jpeg":
case "jpg": $contentType = "image/jpg"; break;
default: $contentType = "application/force-download";
}
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: private", false);
header("Content-Type: " . $contentType);
header("Content-Disposition: attachment; filename=\"" . basename($attachmentFilename) . "\";");
header("Content-Transfer-Encoding: binary");
header("Content-Length: " . filesize($fullFilename));
readfile($fullFilename);
} else {
header("HTTP/1.1 403 Forbidden");
echo "<h1>Forbidden</h1>";
}
<?php
/*
Plugin Name: Job Manager Private Uploads
Plugin URI: https://gist.github.com/matb33/5092416
Description: Prevents direct access to files uploaded using the Job Manager plugin (http://pento.net/projects/wordpress-job-manager-plugin/)
Version: 1.0
Author: Mathieu Bouchard
Author URI: http://www.matb33.me/
License: MIT
*/
class JobManagerPrivateUploads {
public static $privacyPrefix = "PRIVATE__";
private static $ruleMatch;
private static $ruleRedirect;
private static $deactivated = false;
public static function init() {
$uploadDir = wp_upload_dir();
$siteURL1 = site_url("", "http") . "/";
$siteURL2 = site_url("", "https") . "/";
$uploadPath = str_replace($siteURL2, "", str_replace($siteURL1, "", $uploadDir["baseurl"]));
$downloadPath = str_replace($siteURL2, "", str_replace($siteURL1, "", plugins_url("download.php", __FILE__)));
self::$ruleMatch = $uploadPath . ".*/" . self::$privacyPrefix . ".+$";
self::$ruleRedirect = $downloadPath . "?f=$0";
}
private static function add_rewrite_rule() {
global $wp_rewrite;
$wp_rewrite->non_wp_rules[self::$ruleMatch] = self::$ruleRedirect;
}
private static function del_rewrite_rule() {
global $wp_rewrite;
if (array_key_exists(self::$ruleMatch, $wp_rewrite->non_wp_rules)) {
unset($wp_rewrite->non_wp_rules[self::$ruleMatch]);
}
}
public static function activate() {
global $wp_rewrite;
self::add_rewrite_rule();
$wp_rewrite->flush_rules();
}
public static function deactivate() {
global $wp_rewrite;
self::$deactivated = true;
self::del_rewrite_rule();
$wp_rewrite->flush_rules();
}
public static function wp_handle_upload_prefilter($file) {
$options = get_option("jobman_options");
$fields = $options["fields"];
if (count($fields) > 0) {
foreach ($fields as $fid => $field) {
$key = "jobman-field-" . $fid;
if (isset($_FILES[$key])) {
if ($_FILES[$key] === $file) {
$file["name"] = self::$privacyPrefix . $file["name"];
return $file;
}
}
}
}
return $file;
}
public static function generate_rewrite_rules($wp_rewrite) {
if (!self::$deactivated) {
self::add_rewrite_rule();
}
}
}
JobManagerPrivateUploads::init();
add_filter("wp_handle_upload_prefilter", "JobManagerPrivateUploads::wp_handle_upload_prefilter");
add_filter("generate_rewrite_rules", "JobManagerPrivateUploads::generate_rewrite_rules");
register_activation_hook(__FILE__, "JobManagerPrivateUploads::activate");
register_deactivation_hook(__FILE__, "JobManagerPrivateUploads::deactivate");
@supermodo
Copy link

Hi Mathieu, thanks alot for the plugin, maybe the Job Manager can be useful, for me until now it is too vulnerabile for a personal info management. Actually is the basic request for this kind of works.

Anyway... I've tried your plugin but i get an error.
The resume and the application are working like before but i get this message at the end of the application process:
"There was an error uploading your application. Please contact us directly, and quote the information below:
Sorry, this file type is not permitted for security reasons."

I'm a beguiner and i don't understand what you mean with "Wordpress installation should be configured to allow WP_Rewrite"...
What i have to do or to check? Is WP_Rewrite the solution for the error message?
Thanks in advance for the advice
Regards

@matb33
Copy link
Author

matb33 commented Mar 9, 2013

Out of curiosity, are you getting the same error when my plugin is disabled?

As for WP_Rewrite, it's a matter of making sure the .htaccess file is writeable by the web server. I realize this isn't much to go on, but there should be lots of info on this out there. There's likely an article on the Wordpress site itself about it

If after enabling my plugin, you can take a look at the contents of .htaccess and can spot a line that contains PRIVATE__, you're OK with regards to WP_Rewrite

@coxy17
Copy link

coxy17 commented Jun 10, 2013

Hi Mathieu, The plugin worked great for me! I just wondered is it possible to include this straight into the plugin rather than a separate one based on your work? I'm just using it for a personal project.

@matb33
Copy link
Author

matb33 commented Jun 19, 2013

It's a separate plugin because the original plugin isn't mine, and I'd rather not duplicate the original author's entire codebase, patch it, then try to maintain a fork... Are you having issues with this current approach?

@a-irvine
Copy link

Howdy, I installed/tested and it seems it's only renaming the file to add the prefix? I can still download without logging in.

What is the expected behavior of this plugin? My .htaccess file in the root of my WP install doesn't contain anything about PRIVATE__ as mentioned above, so I'm wondering if perhaps my WP_Rewrite isn't configured correctly?

Anyone provide some insight into this? Thanks all

@matb33
Copy link
Author

matb33 commented Aug 28, 2013

@a-irvine, it's definitely related to the .htaccess file. I don't have much for you to go on... this is a WordPress configuration issue. If you can get rewriting to work from WP, then my plugin will be able to add rewrite rules and prevent downloading of files that start with PRIVATE__

@rianbarus
Copy link

Hi Mathieu, can you tell me how to limit the upload file size/upload cv without affect any others upload (only work for job manager). thanks

Rian Barus

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment