How to protect video and photos from folder

Hi everyone.

I have in my site one page with access login enabled, because it contains videos in mp4 format. If you access correctly and charge the page, in Chrome or Firefox, for example, with the developers tools, you can view the link to the videos. If these links are copied and paste to new tab or window in web browser you can download them.

Well, if you no longer have access to that folder but still keep the link, you can continue accessing the content (video.mp4 for example).

How do I protect efficiently way this folder?


@pmoreno, Interesting questions… Unfortunately, Grav is not going to provide you a solution on this. When you reference a media file using a url, the file is served by the webserver, not by Grav. Meaning: No Grav code is going to be executed.

You can test this by taking the url of an image/video in your site, rename Grav’s index.php and open de url in the browser.

In general: “When the user can see it, the user can copy it…”

  • The browser downloads the media into cache on disk
  • The user can copy the value of src and browse to the file.
  • The user might use software that captures the video being played
  • The user might point a camera to the screen…

Here is a discussion (one of many) on the same issue

  • this reply gives suggestions to mitigate some of the above.

    To prevent copy/paste of link:

    […] use a transmuxing wrapper like hls.js(for HLS) or dash.js(mpeg-dash). What will show in your html5 player is a locally generated blob url which means nothing.

    I took a look at hls.js and I’m afraid it is not a quick fix.

Based on my quick research, i’m afraid this isn’t easily solved.

Maybe someone else can prove me wrong…

Hi @pamtbaau,
Certainly, it’s very difficult to hide the media files in a website from the downloaders or the web browsers inspectors. Almost anyone can do it.
However, we have to learn some way to resolve this, because nowadays, with the new life styles by coronavirus effects, the only way to offer your work to your customers is with media systems.
I’ll investigate the hlj.js option.
Thanks so much for your help, always.

There is a way in Grav, using the Login plugin to restric access to page media. You first need to set protect_protected_page_media: true in login.yaml. Then, you need to link to your media using the page route, not the physical address, so instead of for example. That should work.

You can find a discussion and extra ideas here:

1 Like

@TheDancingCode, Thanks! That looks promising…

Important learnings (for me at least):

  • Contrary to my previous post, Grav does intercept requests to media when the url does not contain the file path. Meaning:

    localhost/user/pages/ --> No interception by Grav
    localhost/video/big_buck_bunny.mp4               --> Grav intercepts and can control access
  • Another important learning is a setting of the login plugin in user/config/plugins/login.yaml:

    protect_protected_page_media: true

    This setting will deny access to media files inside a folder under access control. But, as said, only when the url to the media is relative and does not contain the path.

To give it a spin, I did the following in a fresh Grav 1.6.23 + Admin installation:

  • Created a new page with the following in the header:
      site.login: true
      admin.login: true
    and the following content:
    <video controls controlsList="nodownload"> ** see notes at bottom
       <source src="/video/big_buck_bunny.mp4">
       Your browser does not support the video tag.
  • Added ‘big_buck_bunny.mp4’ to the folder of page
  • Added the following to /user/config/plugins/login.yaml:
    protect_protected_page_media: true

Results embedding video via Markdown:

  • After logging in, all three videos were shown, but with an important difference:
    • When using the markdown code ![name](url), a url with a path is generated: /user/pages/
      The user can now copy the url and access the video without being logged in.
    • Only the handcrafted <video> element shows a url without the path.

Adding video using Twig:

  • I tried the following 2 ways to embed the video into the page:
    {{['big_buck_bunny.mp4'].html }}
    <video controls controlsList="nodownload">  ** see notes at bottom
        <source src="{{ page.url~'/'['big_buck_bunny.mp4'].filename }}">
    • The first option again generated a url based on the path to the file.
    • The <video> element has to be handcrafted again using the second option.

Further notes:

  • The HTML5 <video> element allows the user to download the video. This can be switched of in Chrome (chromium-based) browsers, which is approx 66% of the user base.
    • There are other solutions, see this (old) answer on stackoverflow.
  • If user happens to know the folder structure the user could reproduce the path to the video and access it without logging in.
  • The above settings make it harder for the user to copy the video, but does not block the other options to grab/capture the video.

Any suggestions/approvements are welcome!

Hello there.

I’ve been testing all the posibilites that you offer, but the result has not been successful.

I’m going to explain with more details the scenario:

In the image, you can see that one video is used in differents pages, and it’s saved in one folder, out of the pages (for example, user/videos). The main idea is that the user 1 can acces to page 1, user 2 to page2, etc. If the user pay to access to page, he/she can view the video, but if he leave to pay, he couldn’t access to page. This is easy, enable o disabled the page. But if the user has saved the url of video (with F12 in Chrome, for example), this video will be available, because the other users are active, and the video is still saved in the videos common folder.
Moreover, I need not work with login, because it should be possible share the link (facebook, twitter, instagram, etc). You share the link page and when I want, I disabled or I set unpublished the page, and users couldn’t have access to it.

My twig code is the following:

<video src="{{base_url}}/videos/{{item.url_local}}" controls disablepictureinpicture controlslist="nodownload" oncontextmenu="return false;" data-plyr-config='{ "{{item.tvideo_local}}": "{{item.tvideo_local}}" }'></video>

Note: I’m working with Plyr player.

With the method proposed by @TheDancingCode, this is not possible, because I’m not using the login plugin.

Therefore, my question would be if Grav has the possibility to mask or hide the video link saved in this folder.

Thanks in advanced

@pmoreno, Quite essential info omitted from the original question…

In this scenario, are the links to Pages 1, 2, etc unguessable? I mean something like /4gh679gdt468ghjfkjg/ for example.

Why did you mention people log in in your opening question?

@pamtbaau, @TheDancingCode, you have reason in your latest post.
The first time when I explained this question, I wanted to do it with login plugin, but the original idea was saving the videos in one folder, and access to them from different pages, called "355srrgge ", “page 1”, or whatever.
However, the change appear when I decided that the users should be able to share the links of pages with anyone. In this scenario, the login access no longer does. Simply disabling the page, the users couldn’t access to it, however they could share the page with its link address.

Sorry if I didn’t know to explain better this question. Sometimes, some issues or questions are difficult to explain for me. My English domain is limited.

Thanks, for your patient. If we can find a solution, it would be good for this forum. I hope it.