Title: Media Vault
Author: Max GJ Panas
Published: <strong>October 18, 2013</strong>
Last modified: February 18, 2014

---

Search plugins

![](https://ps.w.org/media-vault/assets/banner-772x250.jpg?rev=813330)

This plugin **hasn’t been tested with the latest 3 major releases of WordPress**.
It may no longer be maintained or supported and may have compatibility issues when
used with more recent versions of WordPress.

![](https://s.w.org/plugins/geopattern-icon/media-vault_e6e2db.svg)

# Media Vault

 By [Max GJ Panas](https://profiles.wordpress.org/max-gjp/)

[Download](https://downloads.wordpress.org/plugin/media-vault.0.8.12.zip)

 * [Details](https://ory.wordpress.org/plugins/media-vault/#description)
 * [Reviews](https://ory.wordpress.org/plugins/media-vault/#reviews)
 *  [Installation](https://ory.wordpress.org/plugins/media-vault/#installation)
 * [Development](https://ory.wordpress.org/plugins/media-vault/#developers)

 [Support](https://wordpress.org/support/plugin/media-vault/)

## Description

#### Protected Attachment Files

Media Vault cordons off a section of your WordPress uploads folder and secures it,
protecting all files within by passing requests for them through a _powerful, flexible
and completely customizable_ set of permission checks.

After activating the plugin, to protect attachment files with Media Vault you can:

 * use the _Media Uploader admin page_ to upload new protected attachments,
 * use the _Media Vault metabox_ to toggle file protection on the ‘Edit Media’ admin
   page,
 * use the the _Media Vault Protection Settings_ fields in the new Media Modal, 
   or,
 * using _bulk actions_ in your Media Library page, you can change file protection
   on multiple pre-existing attachments at once.

By default the only permission check that the plugin does on media files is that
the user requesting them be logged in. You can change this _default_ behavior from
the ‘Media Settings’ page in the ‘Settings’ menu of the WordPress Admin. You can
also change the restrictions set on attachments on an individual basis by means 
of either the Media Vault metabox on the ‘Edit Media’ page or the Media Vault Protection
Settings fields in the new Media Modal.

You can also write your own custom restrictions using the `mgjp_mv_add_permission()`
function. See [this support question](https://wordpress.org/support/topic/restrict-only-for-subscribers?replies=5)
for more details.

#### Safe Download Links

Creating a cross-browser compatible download link for a file is a harder task than
might be expected. Media Vault handles this for you, and it does so while preserving
all the file security features discussed earlier like blocking downloads to people
who should not have access to the file.

The download links are available through a simple shortcode that you can use in 
your post/page editor screen:

    ```
    [mv_dl_links ids="1,2,3"]
    ```

where ‘ids’ are the comma separated list of attachment ids you would like to make
available for download in the list.

_Note:_ Plugin comes with styles ready for WordPress 3.8+!

_Note:_ **Now supports WordPress MultiSite!**

## Screenshots

 * [[
 * The WordPress Media Upload page with Media Vault file protection activated.
 * [[
 * An example of the access denied prompt produced by a custom file access restriction
   implemented very simply using Media Vault.
 * [[
 * The WordPress Media Upload page with Media Vault file protection activated (in
   WP mp6 & WP 3.8+)

## Installation

#### Install Through your Blog’s Admin

_This sometimes does not to work on `localhost`, so if you’re running your site 
off your own computer it’s simpler to use the second method._

 1. Go to the ‘Plugins’ menu in WordPress and select ‘Add New’.
 2. Type ‘Media Vault’ in the Search Box and press the ‘Search’ button.
 3. When you find ‘Media Vault’, click ‘Install Now’ and after reading it, click ‘ok’
    on the little alert that pops up.
 4. When the plugin finishes installing, simply click ‘Activate Now’.

#### Downloading from WordPress.org

 1. Clicking the big ‘Download’ button on the right on this page (wordpress.org/plugins/
    media-vault/) will download the plugin’s `zip` folder (`mediavault.zip`).
 2. Upload this `zip` folder to your server; to the `/wp-content/plugins/` directory
    of the site you wish to install the plugin on.
 3. Extract the contents of the `zip`. Once it is done you can delete the `mediavault.
    zip` file if you wish.
 4. Activate the plugin through the ‘Plugins’ menu in WordPress.

Once you have Media Vault activated and fully enabled don’t forget to go and check
out the plugin’s settings on the ‘Media Settings’ page under the admin ‘Settings’
menu.

## FAQ

  How do I toggle File Protection on an existing Attachment?

You have two options. If you only want to toggle File Protection on **a single attachment**,
you can do it directly from the attachment’s Edit page. In the ‘Media Vault Settings’
metabox in the right column, you can toggle protection by clicking the button that
will either say ‘Add to Protected’ or ‘Remove from Protected’. Remember to click‘
Update’ to save the changes you have made.

If you want to toggle File Protection on **multiple attachments**, the plugin comes
with two bulk actions that can be performed in the Media Library page in the WordPress
Admin. On the Media Library page select the attachment or attachments you would 
like to manipulate by ticking the box next to their title. Then from the ‘bulk options’
dropdown select either the ‘Add to Protected’ or ‘Remove from Protected’ option 
and click the ‘Apply’ button next to the dropdown.

You can verify that the action took effect by looking at the Media Vault column 
in the Media Library list table. It will display when an attachment’s files are 
protected as well as the permissions set on the particular attachment.

  Can files uploaded from the front-end be automatically protected?

Yes they can, see [this support question](https://wordpress.org/support/topic/default-upload-protection-from-front-end?replies=5)
for more details!

  How are unprotected files handled? How does this plugin work?

This question was recently asked and answered in [this support thread](https://wordpress.org/support/topic/how-the-unprotected-files-are-handeled?replies=3),
check it out!

## Reviews

![](https://secure.gravatar.com/avatar/e166e3988b491877bc152f27d4ffccd5e5abd7a1e9bb0b63667282242bc021be?
s=60&d=retro&r=g)

### 󠀁[It’s almost perfect](https://wordpress.org/support/topic/finally-this-plugin-is-amazing/)󠁿

 [maxeyle](https://profiles.wordpress.org/maxeyle/) January 20, 2020

I spent untold hours trying to solve the seemingly simple task of restricting access
to certain media uploads to logged in users. All I needed was a way to check a box
that would keep people from using a direct url to view private documents, and this
finally gave me that function. However, my celebration was short-lived because I
realized it was blocking the media url for everyone – including logged in users.
So close…

![](https://secure.gravatar.com/avatar/55a59270cd5b02008382983dc5bb3af8392fa4e52133ba7ff4eaad9da27f0cbb?
s=60&d=retro&r=g)

### 󠀁[Would be amazing if it worked](https://wordpress.org/support/topic/would-be-amazing-if-it-worked/)󠁿

 [fatheroftime](https://profiles.wordpress.org/fatheroftime/) October 17, 2019

This plugin no longer works, but it WOULD do everything I need it to do. Broken 
things: Doesn’t protect PDFs Doesn’t protect media files by default Can still access
files through a direct link

![](https://secure.gravatar.com/avatar/7b0bfaf4b1767dd3e5333ecf31f229f90c24de82f962d5c63fd854326a7dca7d?
s=60&d=retro&r=g)

### 󠀁[Great Work](https://wordpress.org/support/topic/great-work-418/)󠁿

 [jtvie](https://profiles.wordpress.org/jtvie/) September 3, 2016

Use it to secure some of my contents on a mid sized Page. Did some additional stuff
to it: Woocommerce membership (checks if a user already payed for chosen content
or is subscriber) Add options to the Divi theme&Builder to restrict access to sections/
blocks the same way as the media vault would do rewritten file serve code to handle
ranged/streamed video and or other big data packages action added to use an s3 as
primary file delivery as private links and the media vault as fallback (fileOnS3?
header location s3:serve file) If requested i’ll assist on similar topics. If anybody
is interested in the rewritten file serving php thing: the following code is a part
of the “mv-file-handler.php” file – there where no actions to overrule so i had 
to modify the original source: function mgjp_mv_get_file($rel_file, $action = ''){//
$rel_file = path to the file to view/download, // relative to the WP uploads folder//(
eg:'/media-vault/2013/10/media-vault-150×150.jpg') $upload_dir = wp_upload_dir();//
only files in the WP uploads directory are allowed to be accessed: $file = rtrim(
$upload_dir['basedir'], '/').str_replace('..', '', isset($rel_file)?$rel_file:'');//—
Basic Checks—————————————————-// if(!$upload_dir['basedir'] || !is_file($file)){
status_header(404); wp_die('404. File not found.'); } $mime = wp_check_filetype(
$file); // Check filetype against allowed filetypes if(isset($mime['type']) && $
mime['type']){ $mimetype = $mime['type']; }else{ status_header(403); wp_die(__('
403. Forbidden.<br/>You cannot directly access files of this type in this directory
on this server. Please contact the website administrator.')); } //—Permission Checks———————————————–//
$file_info = pathinfo($rel_file); // check if file is protected by checking // if
it is in the protected folder before // doing any permission checks if(0 === stripos(
$file_info['dirname'].'/', mgjp_mv_upload_dir('/', true))){ // disable caching of
this page by caching plugins ——// if(!defined('DONOTCACHEPAGE')) define('DONOTCACHEPAGE',
1); if(!defined('DONOTCACHEOBJECT')) define('DONOTCACHEOBJECT', 1); if(!defined('
DONOTMINIFY')) define('DONOTMINIFY', 1); //——————————————————-// // try and get 
attachment id from url ——————-// global $wpdb; $attachments = $wpdb->get_results(
$wpdb->prepare( " SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key
= %s AND meta_value LIKE %s ", '_wp_attachment_metadata', '%'.$file_info['basename'].'%'),
ARRAY_A ); $attachment_id = false; foreach($attachments as $attachment){ $meta_value
= unserialize($attachment['meta_value']); if(ltrim(dirname($meta_value['file']),'/')
== ltrim($file_info['dirname'], '/')){ $attachment_id = $attachment['post_id']; 
break; } } // ——————————————————// if(!$permission = mgjp_mv_get_the_permission(
$attachment_id)) $permission = get_option('mgjp_mv_default_permission', 'logged-
in'); $permissions = mgjp_mv_get_the_permissions(); // permission set up error detection
$standard_error_txt = ' '.esc_html__('Therefore for safety and privacy reasons this
file is unavailable. Please contact the website administrator.', 'media-vault').'
<p><a href="'.home_url().'">&larr;'.esc_html__('Return to homepage', 'media-vault').'
</a></p>'; if(!isset($permissions[$permission])) wp_die(__('The permissions set 
for this file are not recognized.', 'media-vault').$standard_error_txt); if(!isset(
$permissions[$permission]['logged_in'])) $errors[] = 'logged_in'; if(!isset($permissions[
$permission]['cb'])) $errors[] = 'cb'; if(isset($errors)){ $error_txt = __('The 
permissions set for this file have left the following important parameters undefined:','
media-vault') .'<ul><li>\''.implode('\'</li><li>\'', $errors).'\'</li></ul>' .'<
p>'.$standard_error_txt.'</p>'; wp_die($error_txt); } if($permissions[$permission]['
logged_in']) is_user_logged_in() || auth_redirect(); // using is_user_logged_in 
is lighter than using just auth_redirect if(false !== $permissions[$permission]['
cb']){ if(!is_callable($permissions[$permission]['cb'])) wp_die(__('The permission
checking function set in this file\'s permissions is not callable.', 'media-vault').
$standard_error_txt); $permission_check = call_user_func_array($permissions[$permission]['
cb'], array($attachment_id, $rel_file, $file)); if(is_wp_error($permission_check))
wp_die($permission_check->get_error_message().$standard_error_txt); if(true !== 
$permission_check) wp_die(__('You do not have sufficient permissions to view this
file.', 'media-vault').$standard_error_txt); } if(function_exists('attachment_get_remote_url')&&
$remote_url = attachment_get_remote_url($attachment_id)){ header("Location: ".$remote_url,
TRUE,307); } } // end of permission checks //——————————————————————-// $filesize
= filesize($file); header('Content-Type: '.$mimetype); // always send this if(false
=== strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS')) header('Content-Length:'.
$filesize); if('safeforce' !== $action){ //–OPEN FILE IN BROWSER functions————-//
$last_modified = gmdate('D, d M Y H:i:s', filemtime($file)); $etag = '"'.md5($last_modified).'"';
header("Last-Modified: $last_modified GMT"); header('ETag: '.$etag); header('Cache-
Control: no-store, no-cache, must-revalidate'); // HTTP 1.1. header('Pragma: no-
cache'); // HTTP 1.0. header('Expires: Thu, 01 Dec 1994 16:00:00 GMT'); // Proxies//
Support for Conditional GET $client_etag = isset($_SERVER['HTTP_IF_NONE_MATCH'])?
stripslashes($_SERVER['HTTP_IF_NONE_MATCH']):false; if(!isset($_SERVER['HTTP_IF_MODIFIED_SINCE']))
$_SERVER['HTTP_IF_MODIFIED_SINCE'] = false; $client_last_modified = trim($_SERVER['
HTTP_IF_MODIFIED_SINCE']); // If string is empty, return 0. If not, attempt to parse
into a timestamp $client_modified_timestamp = $client_last_modified?strtotime($client_last_modified):
0; // Make a timestamp for our most recent modification… $modified_timestamp = strtotime(
$last_modified); if(($client_last_modified && $client_etag) ?(($client_modified_timestamp
>= $modified_timestamp) && ($client_etag == $etag)) :(($client_modified_timestamp
>= $modified_timestamp) || ($client_etag == $etag)) ){ status_header(304); exit;}}
else{ //–FORCE DOWNLOAD Functions———————–// // required for IE, otherwise Content-
disposition is ignored if(ini_get('zlib.output_compression')) ini_set('zlib.output_compression','
Off'); header('Pragma: public'); // required header('Expires: 0'); header('Cache-
Control: must-revalidate, post-check=0, pre-check=0'); header('Cache-Control: private',
false); // required for certain browsers header('Content-Disposition: attachment;
filename="'.$file_info['basename'].'";'); header('Content-Transfer-Encoding: binary');}//
If we made it this far, just serve the file if(ob_get_length()) ob_clean(); $filesize
= filesize($file); //Handel partial request header("Accept-Ranges: 0-$filesize");
$buffer_size = 1024 * 1024; //1MB #bigger = more ram usage but less cpu if(isset(
$_SERVER['HTTP_RANGE'])){ preg_match('/bytes=(\d+)-(\d+)?/', $_SERVER['HTTP_RANGE'],
$matches); $offset = intval($matches[1]); $length = intval(isset($matches[2])?intval(
$matches[2]) – $offset:$filesize – $offset); if($length < 1) $length = $filesize–
$offset; if($length > $buffer_size*10) $length = $buffer_size*10;//limit max partial*
will trigger a ERR_CONTENT_LENGTH_MISMATCH on client but will perform better… header('
HTTP/1.1 206 Partial Content'); header('Content-Range: bytes '.$offset.'-'.($offset
+ $length).'/'.$filesize); $file = fopen($file, 'r'); // seek to the requested offset,
this is 0 if it's not a partial content request fseek($file, $offset); //split the
file so we could <code>stream</code> just the range we need while($length > 0 &&!
feof($file)){ if($length > $buffer_size) $bytes_to_read = $buffer_size; else $bytes_to_read
= $length; $length -= $bytes_to_read; echo fread($file, $bytes_to_read); flush();}
fclose($file); exit; } flush(); readfile($file); exit; }

![](https://secure.gravatar.com/avatar/91c9fae332c2a618be04da516c21dbb908c2bcccdc94d1d1878cbdbafbb62972?
s=60&d=retro&r=g)

### 󠀁[Very useful](https://wordpress.org/support/topic/very-useful-874/)󠁿

 [dimgord](https://profiles.wordpress.org/dimgord/) September 3, 2016

Found it while looking for restriction view access – it’s just what I needed, thanks
a lot!

![](https://secure.gravatar.com/avatar/91ffeff68d714f3c4c8b34133ae3911f58427bab9b76f07ebf4793c6cdaaf1bb?
s=60&d=retro&r=g)

### 󠀁[Great, but the future?](https://wordpress.org/support/topic/great-but-the-future/)󠁿

 [mojamba](https://profiles.wordpress.org/mojamba/) September 3, 2016

Recently installed and started using this plugin and it works wonderfully. But, 
seeing how long it has been since last being updated, I do worry if it will break
in some future WP update. For now, all good. Let’s hope someone keeps this plugin
active as I didn’t see any other plugin trying to solve this problem (which, itself,
was a huge surprise).

![](https://secure.gravatar.com/avatar/a38d72ed9120a26b196cb104400d71e613b88841c01e9d7e1b62098b50da55f1?
s=60&d=retro&r=g)

### 󠀁[Perfect plugin for member areas](https://wordpress.org/support/topic/perfect-plugin-for-member-areas/)󠁿

 [wyzyncom](https://profiles.wordpress.org/wyzyncom/) September 3, 2016 1 reply

Good plugin for securing / hiding media files (PDF’s and images) that are only to
be seen in the member area by logged-in users. Member management plugins like Ultimate
Member don’t offer this option. Result is that files which are imported into a member
page are still publicly visible and accessable. Not good, because the member area
and all its components should be visible by logged on members only. A big flaw in
WordPress, as far as I’m concerned. But this plugin solves the problem easy and 
in an intuitive way. Why not a 5 star rating? Because I think it’s a pitty that 
this plugin hasn’t been updated for a long time. Really hope the developer will 
restart his project. I would wanna pay for this plugin.

 [ Read all 27 reviews ](https://wordpress.org/support/plugin/media-vault/reviews/)

## Contributors & Developers

“Media Vault” is open source software. The following people have contributed to 
this plugin.

Contributors

 *   [ Max GJ Panas ](https://profiles.wordpress.org/max-gjp/)

[Translate “Media Vault” into your language.](https://translate.wordpress.org/projects/wp-plugins/media-vault)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/media-vault/), check
out the [SVN repository](https://plugins.svn.wordpress.org/media-vault/), or subscribe
to the [development log](https://plugins.trac.wordpress.org/log/media-vault/) by
[RSS](https://plugins.trac.wordpress.org/log/media-vault/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 0.8.12

fixed bug in `mv-file-handler.php` causing php Notice and corrupted files. Big thanks
to user [ikivanov](https://profiles.wordpress.org/ikivanov) for pointing it out 
and providing the solution!

#### 0.8.11

 * fixed bug in `mv-metaboxes.php` causing php Notice. Thank you user [ikivanov](https://profiles.wordpress.org/ikivanov)
   for pointing it out!
 * fixed bug in `mv-metaboxes.php` causing metabox stylesheet not to be served

#### 0.8.10

Fixed typo causing php error in `mv-extra-activation-steps.php`. Thank you user 
[wwn2013](https://profiles.wordpress.org/wwn2013) for pointing it out!

#### 0.8.9

 * Added Attachment Edit fields to the new Media Modal to make it easier to manage
   which files are protected with Media Vault and what permissions are set on each
   protected file.
 * Fixed visual bug with IE8 and the general sibling selector not showing permissions
   in the Media Vault Metabox on the attachment edit admin page.
 * Organized minified js code into seperate folder

#### 0.8.8

fixed bug in `mv-file-handler.php` that allowed files to be viewed in the protected
folder when ‘Save uploads in year/month folders’ was _not_ selected. Thanks to [WayneHarris](https://profiles.wordpress.org/wayneharris)
for pointing the issue out.

#### 0.8.7

added a body class to the WP admin to let Media Vault know to use the new 3.8+ styles

#### 0.8.6

fixed code that required php 5.4 and above, to be compatible with older versions
of php

#### 0.8.5

 * Now the plugin is not fully enabled if the rewrite rules are detected to not 
   be fully functioning as required
 * Added flag to indicate Media Vault can **only** be network activated on WordPress
   Multisite installs
 * Added return to homepage link in standard access denied message on protected 
   media
 * Added Media Vault Activation/Deactivation Helper (MVADH) to support setups where
   Media Vault cannot automatically configure all components it needs to function,
   particularly the rewrite rules. Currently, MVADH supports single & multisite 
   WordPress installs on Apache + mod_rewrite. Support for more server technologies
   coming soon. _MVADH not supporting a particular server technology **does not**
   mean Media Vault cannot work with that technology_, just that you may need to
   figure some of how to make the rewrite rules work by yourself.
 * Added **much** better support for WP multisite: better activation support, better
   deactivation support, better uninstallation support, better rewrite rule support,
   better file-handling support, better plugin update support.
 * Added MVADH rewrite rule support for ugly permalink setups
 * Made some performance tweaks & minor bugfixing

#### 0.8

 * added functionality to allow a place-holder image to replace a requested protected
   image.
 * refactored permission resolving functions to be more thorough and efficient.
 * modified `mgjp_mv_admin_check_user_permitted()` function to handle non admin 
   checking and renamed it to `mgjp_mv_check_user_permitted()` to reflect this.
 * added plugin update handling class to manage per update required changes fluidly.
 * created an `uninstall.php` file and moved all settings removal actions there 
   so that settings are now saved when a user only deactivates and does not remove
   the plugin.
 * added a link to the Media Vault settings to the Plugins page.
 * fixed bug with the Media Vault metabox not being able to set the default permission
   on the attachment.
 * fixed bug with the `mgjp_mv_get_the_permission()` function returning the wrong
   permission.

#### 0.7.1

The Metabox – added a Media Vault metabox to the attachment editor screen to manage
protection meta + bugfixing on the bulk actions script

#### 0.7

_Minor remastering of permission checking code to address protected attachment access
from within the WordPress backend. Highly recommended to immediately update._

 * Rewrote default permissions to return rather than using `wp_die` directly. They
   now MUST either return `true` upon determining the current user is permitted 
   to access a particular attachment; or if access is denied: `false` or a [`WP_Error`](https://codex.wordpress.org/Class_Reference/WP_Error)
   object with an error message included.
 * Added `mgjp_mv_admin_check_user_permitted()` function to use permission functions
   to change access to attachments while within the WP Admin.
 * Hooked into the ‘user_has_cap’ and ‘media_row_actions’ filters to restrict what
   users could see and manipulate in the backend for the specific attachments they
   did not have the permission to access.
 * Rewrote the custom permission checking function handling section of the file-
   handling script `mv-file-handler.php` to accommodate the changes to the way custom
   permission functions now return values.

#### 0.6

Initial Release.

## Meta

 *  Version **0.8.12**
 *  Last updated **12 years ago**
 *  Active installations **800+**
 *  WordPress version ** 3.5.0 or higher **
 *  Tested up to **3.7.41**
 *  Language
 * [English (US)](https://wordpress.org/plugins/media-vault/)
 * Tags
 * [attachments](https://ory.wordpress.org/plugins/tags/attachments/)[downloads](https://ory.wordpress.org/plugins/tags/downloads/)
   [media](https://ory.wordpress.org/plugins/tags/media/)[protection](https://ory.wordpress.org/plugins/tags/protection/)
   [security](https://ory.wordpress.org/plugins/tags/security/)
 *  [Advanced View](https://ory.wordpress.org/plugins/media-vault/advanced/)

## Ratings

 4.4 out of 5 stars.

 *  [  21 5-star reviews     ](https://wordpress.org/support/plugin/media-vault/reviews/?filter=5)
 *  [  3 4-star reviews     ](https://wordpress.org/support/plugin/media-vault/reviews/?filter=4)
 *  [  0 3-star reviews     ](https://wordpress.org/support/plugin/media-vault/reviews/?filter=3)
 *  [  0 2-star reviews     ](https://wordpress.org/support/plugin/media-vault/reviews/?filter=2)
 *  [  3 1-star reviews     ](https://wordpress.org/support/plugin/media-vault/reviews/?filter=1)

[Your review](https://wordpress.org/support/plugin/media-vault/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/media-vault/reviews/)

## Contributors

 *   [ Max GJ Panas ](https://profiles.wordpress.org/max-gjp/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/media-vault/)

## Donate

Would you like to support the advancement of this plugin?

 [ Donate to this plugin ](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6KFT65LQXEHFQ)