allow image access only from specific html page - security

I've got different users for my website, owning different images which are all stored in the same folder. The images are stored in an incremental fashion, 1.jpg, 2.jpg etc.
User can view these pictures on a specific php page. Now I want to restrict the access to these images only through this php page so that they can't simply enumerate all the filenames to see the images of other users.
I thought of doing this with an .htaccess file which is stored besides the images in /shop/img/userimg/ and would look something like this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/shop/shop.php [NC]
RewriteRule .*\.(jpe?g|gif|bmp|png)$ - [F]
My site is a subsite (as you can see: /shop/) and the php page to view these images would be shop.php.
Now, is this possible at all? What am I doing wrong?

Note that the referer header is not to be trusted. Some proxies and firewall remove the header entirely, so you have to account for it not being present (that's what the 2nd line is for)
RewriteCond %{HTTP_REFERER} !/shop/shop\.php$ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule \.(jpe?g|gif|bmp|png)$ - [F,L]

Try adding the following to your htaccess file.
RewriteEngine On
RewriteBase /
#if the referer (page request came from) does not contain shop.php
RewriteCond %{HTTP_REFERER} !/shop/shop\.php [NC]
#and it is a request for images, then send a 403 forbidden
RewriteRule \.(jpe?g|gif|bmp|png)$ - [F,L]

Related

.htaccess allow hotlinking of images with parameter (?something)

I have code in my .htaccess file to prevent hot-linking of images on my site.
What I need is to make it allow hot-linking of images it they have some parameter at the end of URL, for example:
This image should be blocked:
https://my-site.com/my-images/some-image-file-name.jpg
BUT, ALLOW hot-linking if that same image have parameter at the end, for example:
https://my-site.com/my-images/some-image-file-name.jpg?allow_hot_linking
WHY I NEED SOMETHING LIKE THIS?
For example, if image is sent inside html email, it will not be displayed, but if I could make some .htaccess rule which would allow hot-linking of images with parameter I will simply put that parameter at the end of img source tag of image while making html email and it will appear when email is opened.
This is my .htaccess code
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?my-site.com [NC]
RewriteCond %{HTTP_REFERER} !^http(s)?://(www.)?nnn.nnn.nn.nnn [NC]
##Allow search engines
RewriteCond %{HTTP_USER_AGENT} !Googlebot-Image [NC]
.
.
.
##Allow blank referrers
RewriteCond %{HTTP_REFERER} !^$
## Redirect to hotlink image
RewriteRule ^my-images/(.*).(jpeg|jpg|bmp)$ https://my-site.com/no-hotlinking.html [NC,R,L]
## End - prevent image hotlinking
Love this solution, exactly what I was looking for to allow links from emails but not from blank referrers.
RewriteCond %{QUERY_STRING} !^ahl$ [NC]
Works a dream.

Hotlink protection excluding a particular URL

We have tried adding the below hotlink protection inorder to save the bandwidth.
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^https://(www\.)?domain [NC]
RewriteCond %{HTTP_REFERER} !^https://(www\.)?domain.*$ [NC]
RewriteRule \.(gif|GIF|jpg|JPG|PNG|png|jpeg|JPEG|mp4|MP4|mkv|MKV|webm|WEBM|ico|ICO)$ - [F]
This is working perfectly. Now, we want to exclude hotlink protection for the URL admin/thumbs (domain.tld/admin/thumbs/image.jpg) should be excluded from the hotlink protection.
We tried adding the below code however its not working. We searched on stackoverflow and multiple forums however none were helped us.
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^https://(www\.)?domain [NC]
RewriteCond %{HTTP_REFERER} !^https://(www\.)?domain.*$ [NC]
RewriteCond %{REQUEST_URI} !/admin/thumbs$
RewriteRule \.(gif|GIF|jpg|JPG|PNG|png|jpeg|JPEG|mp4|MP4|mkv|MKV|webm|WEBM|ico|ICO)$ - [F]
Any help would be appreciated.
RewriteCond %{REQUEST_URI} !/admin/thumbs$
This creates an exception for any URL that ends with /admin/thumbs, whereas it would seem you want to create an exception for any file in the /admin/thumbs subirectory, ie. any URL that starts /admin/thumbs.
The suggestion !^admin/thumbs/? in comments is incorrect, since the REQUEST_URI server variable always starts with a slash so the condition will always be successful and the request is potentially blocked.
You should use the CondPattern !^/admin/thumbs($|/) instead to exclude requests for /admin/thumbs, /admin/thumbs/ and /admin/thumbs/<anything>, but not /admin/thumbsomething. For example:
RewriteCond %{REQUEST_URI} !^/admin/thumbs($|/)
Your existing rule can be further simplified/refined since the existing conditions that check the HTTP_REFERER are "the same", but also match too much. And the mixed case RewriteRule pattern can be flattened by using the NC (nocase) flag instead.
For example, the complete rule would become:
# Hotlink protection for images, except those in "/admin/thumbs/..."
RewriteCond %{HTTP_REFERER} !^https://(www\.)?example\.com($|/) [NC]
RewriteCond %{REQUEST_URI} !^/admin/thumbs($|/)
RewriteRule \.(gif|jpg|png|jpeg|mp4|mkv|webm|ico)$ - [NC,F]
Note that this also blocks an empty Referer header. This includes direct requests (anyone typing the URL directly into the browser's address bar) and any user that has suppressed the Referer in their browser (which some users do for increased privacy).
Alternative solution with additional .htaccess file
Alternatively, you could create an additional .htaccess in the /admin/thumbs/ subdirectory and simply disable the rewrite engine. For example:
RewriteEngine Off
This overrides and prevents the hotlink-protection directives in the parent config from being processed when anything within this subdirectory is requested.

How to block files from access by URL

i have subpage like
mypage.com/subpage
But that is only alias and all files are in/data/subpage. And only file needed to be accessed by user himself is index.php and all other files are imported by index itself, depending on attributes (GET, sessions etc.)
I want this:
Let user to access index.php using /subpage but not /data/subpage
Do not let user directly access anything in /data/subpage and its subfolders
still let index.php to access those files.
I hope I wrote it understandably.
Thank you for your help
EDIT: My current .htaccess (located in root)
RewriteEngine On
RewriteRule ^subpage$ /data/subpage/index.php [L]
RewriteRule ^subpage/(?:([^/]+)/?|)(?:([^/]+)/?|)$ /data/subpage/index.php?section=$1&subsection=$2 [L]
RewriteRule ^edit/subpage/?(?:([^/]+)/?|)(?:([^/]+)/?|)$ /data/subpage/index.php?edit=true&section=$1&subsection=$2 [L]
Try:
RewriteCond %{THE_REQUEST} \ /+data/subpage/
RewriteRule ^ - [L,R=404]
so that any direct requests for /data/subpage/ results in a 404. You can replace R=404 with F if you would rather it result in a "403".
EDIT:
It's kinda right, thank you. I, as a viewer, can't access those files but my page also cant access it (for ex. images). Is there any way to do it?
This isn't your page accessing those files, it's your page telling the browser to access them. That means the only way you're going to know that the page told the browser to access them is to check the referer. Unfortunately, the referer can be trivially forged so this is no guarantee that people can't get to all your files.
RewriteCond %{THE_REQUEST} \ /+data/subpage/
RewriteCond %{HTTP_REFERER} !^http://yourdomain.com/subpage/(index\.php)?
RewriteRule ^ - [L,R=404]

How can I resolve these vbulletin 404 errors using htaccess?

I have a very big forum (230k threads, 3 million posts) that has a large number of 404 pages reported on Google Webmaster Tools, to the tune of about 14,000 404 URLs. Google is probably showing these 404s because I have incoming links to them, meaning I'm losing a lot of SEO benefit by not having these links follow through to the actual page.
I know why I have this problem, a year ago the URLs on my site were changed back to vBulletin default so that they look like this:
http://www.domain.com/showthread.php?t=323653&p=4230256
I would like to keep them this way since they've been that way for a year. The problem is that there were two previous formats that are showing 404 errors:
These:
http://www.domain.com/forums/showthread.php?t=21461
http://www.domain.com/forums/showthread.php?t=16187
Which just need to have forums/ removed from the URL, and these:
http://www.domain.com/forums/f8/39840-infractions_system_how_works.html
http://www.domain.com/forums/f11/67410-viewing_ijji_gunz_replays_while_offline.html
Which are a funky URL structure that was created back when I had vbSEO installed.
/forums/ needs to be removed and I think that the numbers 39840 and 67410 are probably the thread id. I think there's everything we need in the URL to rewrite but I'm not entirely sure how to achieve it using htaccess.
Assuming, your .htaccess is located at website root "/"
RewriteEngine on
RewriteBase /
# removes "forums/"
RewriteCond %{REQUEST_URI} !^/showthread.php$ [NC]
RewriteRule ^forums/([^/]+)$ $1 [R=301,NC,L]
# parses thread id
RewriteCond %{REQUEST_URI} !^/showthread.php$ [NC]
RewriteRule ^forums/[^/]+/(\d+)-.*$ showthread.php?t=$1 [R=301,NC,L]
Enable mod_rewrite and .htaccess through httpd.conf and then put this code in your .htaccess under DOCUMENT_ROOT directory:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# to redirect /forums/f8/39840-something.html to
# /showthread.php?t=39840
RewriteRule ^forums/[^/]+/([^-]+)-[^.]+\.html$ /showthread.php?t=$1 [R=301,NC,L,QSA]
# to redirect /forums//showthread.php?t=39840 to
# /showthread.php?t=39840
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^forums/([^/]+)/?$ /$1 [R=301,NC,L]

Prevent hot-linking of generated thumbnails?

I have a .htaccess file that contains directives to prevent the hot-linking of static assets (images, CSS and JavaScript files). The relavant code looks like this:
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?ipwuk.com/.*$ [NC]
RewriteRule \.(gif|jpg|js|css|png)$ - [F,L]
This is great and does the job; however, I have a PHP script that automatically generates thumbnails (and doesn't contain the file extension in the URL). A sample thumbnail URL looks like this:
http://example.com/inc/image.php/4e7efde2ee8ac.jpg/610/343/fill
Or:
http://example.com/inc/image.php/[seed].[extension]/[width]/[height]/[thumb type]
How can I prevent images generated by the above script from being hot-linked (which I suspect my client is doing and as a result is eating bandwidth to the tune of over 150MB a day)?
This code denies all requests for image.php that are NOT direct or from specified website.
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www\.)?ipwuk\.com/.*$ [NC]
RewriteCond %{REQUEST_URI} ^/image.php(.*)$ [NC]
RewriteRule ^(.*)$ - [F,L]
Could you not actually prevent - EDIT: discourage - it in the script that generates the thumbnail itself?
In pseudo-PHP:
if (parse_url($_SERVER['HTTP_REFERER']) != "yourSite"){
//generate thumbnail that says "don't hotlink, scum!"
}
else {
//do your normal thumbnail generation routine
}

Resources