Blocking a video from being accessed via url?

When I play a video (that is blocked from being downloaded as a file from a php web script player that I’m using) I can see the url address of the file from my PC in dev tools > networking > media, Is there a way to block or scramble the video’s url from being available to be copied? If not, is there a way to keep that url from being available unless the potential viewer is logged-in to the web site? Or some type of authentication based on checking for a user’s PHP temp session file before allowing access from the video’s url?

It sounds as though you are asking for help in breaking a website’s terms of service…

I don’t get why it sounds that way. As the web site owner I set the terms

Probably just my suspicious nature :slight_smile:

Have the video player ‘play’ a PHP page; that way you can control if someone gets any data out of the page.

If you can afford it, there is software available to do that. I do not know what they are; one solution uses Flash but that is being dropped.

I am not an expert but I assume you could write something that works both client-side and server-side. The server could send each frame and the client shows each one. You would also want to obscure the client code. It would probably be possible for a hacker to figure out what is happening but it would not be easy. A hacker such as me could capture the window’s image and get the video that way. I know where there is sample Windows code that can do that, and it works with the new way that Windows shows graphics. The graphics of most browser windows cannot be captured using the old way (as in Capture a Screen Shot - C# sample code - developer Fusion) except that works for FireFox.

Thanks for the replies.
How can a video player ‘play’ a PHP page?

Are you using nginx or Apache?

Apache

In that case you can use X-SENDFILE headers in PHP.

There is a good explation here: https://tn123.org/mod_xsendfile/

Basically, instead of providing the user with the video URL, you provide the user with a PHP URL, that will check if they are logged in, and if they are, tell Apache to serve the user the video URL. This has the advantage that your PHP process can continue serving other requests instead of being tied up serving a video file.

If people know the actual URL of the video they can still access it, but it won’t be visible anywhere in the browser, it will be handled transparently inside of Apache. In Nginx you can prevent even that, but you’re not using Nginx, so :wink:

Generally mod_xsendfile is installed by default in Apache most of the time, if not you may need to ask your hoster to install it for you.

1 Like

Assuming you’re silly enough to put your videos below the docroot.

And I wasnt even talking about X-SENDFILE. I simply meant having PHP send a Filetype header and then include and echo the video file. But this works as well.

That first outbound arrow should say (User logged in) Here is ‘video.php’ though, right? Because otherwise the browser definitely knows the file name :stuck_out_tongue:

Well yes; Apache will serve secret-video.mp4, but tell the browser it’s serving video.php :slight_smile:

Thanks for your reply/suggestion.
Can X-SendFile be used to affect all subfolders (and all files in those subfolders) in a particular Folder?

Also, after reading more about it, I see this:The disadvantage to using X-SendFile is that you lose control over the transfer mechanism. What if you want to perform some tasks after the client has received the file? For example: to allow a user to download a file only once. With X-Sendfile this could not be done because the script continues to run as soon as it sends the file to the web server for processing and so the script could not know if the download was successful."

I look forward to any comments

I’m not sure what you’re asking here.

So? Do you need to limit the downloads to one per person, or do you need to know of the download was successful? If not, those limitations don’t apply. If you do, don’t use X-SendFile.

Thanks for your reply.

the videos are stored in subfolders of subfolders like so:
http://…com/upload/videos/2019/08/nq3W16rp3fkUM.mp4

so, I was asking if X-SENDFILES would work with that type of set up.

Regarding, limitations, wouldn’t it be important to know if files are playing/downloading?

I look forward to your comments. Thanks again

I think that’s the point of this comment:

If they’re in a public area, then there’s a chance that the direct URL can be found somehow, and then, because they’re in a public area, you’ve lost control. So the point would be for the video to actually be stored in a place where only your PHP code can get to it (above the docroot), and your PHP serves the video to the user.

That’s entirely down to the site owner, surely?

Thanks for your reply.
Regarding, making all the uploaded videos get stored in another location, seems to me would require a lot of rewriting of the web video script.
Regarding, “there’s a chance that the direct URL can be found”, all files in those folders are stored with names like this: burMunq3p8jf987_92_6der8evmervu538Etsns8fjf8flfyd3fkUM.mp4
which, I would think might be hard to be found?

I’m interested to see comments on whether X-Sendfile would be a better choice then an md5 hash solution, (or Symlink). I’ve read thata hash solution could show that a url like:http://mymp4.com?validate.php?video=40f67p113eb8269445d278b8d1d31, possibly?

instead of the actual file path, after running it thru a validate php script, something like:

<?phpsession_start(); 
if (!isset($_SESSION['login'])) { 
header ('Location: index.php'); 
exit(); 
} else { 
// Get server document root 
$document_root = $_SERVER['DOCUMENT_ROOT']; 
// Get request URL from .htaccess 
$request_url = $_GET['request_url']; 
// Get file name only 
$filename = basename($request_url); 
// Set headers 
header('Content-type: application/mp4'); 
header('Content-Disposition: inline; filename='.$filename); 
// Output file content 
@readfile($document_root.$request_url); }`

I look forward to any comments/suggestions

I know nothing about x-sendfile, but I’m sure someone else will expand on that. However, this bit of your code is something to consider:

header('Content-type: application/mp4'); 
header('Content-Disposition: inline; filename='.$filename); 
// Output file content 
@readfile($document_root.$request_url); }`

Specifically, the line where you output a header containing the filename. What’s to stop you here just sending

header('Content-Disposition: inline; filename=video.mp4'); 

and then sending the content of the video you want to serve?

What I mean by that is, if you use that method, don’t send the actual video filename as a header.

Yes, it would be quite difficult to guess that filename. But that’s something referred to as “security through obscurity”, which isn’t as good as proper security. If you’re storing the videos in a public-access area of the site, there’s a chance they can be accessed directly by the public without going through your code. Store them above the root and make it so that the only way they are accessed is via your code, and you don’t have that issue.

Thanks for your reply.

I’d like to test this, just to get an idea of how it might work;

I have added this code to an .htaccess file:

RewriteEngine OnRewriteCond %{REQUEST_URI} \.(mp4)$ [NC]
RewriteRule ^ validate.php?request_url=%{REQUEST_URI} [L]

I have added this (validate)php file:

<?php
$v = $_GET['video'] ?? null;

if(file_exists($v)) {
    unlink($v);
    header('Content-type: application/mp4');
    header('Content-Disposition: inline; filename=video.mp4');    
    readfile("./mytestvideoo.mp4");    
} else
   http_response_code(404);

I just don’t know what to do with this part that was provided:

//Generate the link

$normalText = "this is just your average string with words and stuff";

$hashedText = md5($normalText);

fopen($hashedTest, 'w');

echo "<a href='validate.php?video={$hashedText}'>Link to the video</a>

any additional guidance is appreciated.