Block direct access to images

Hi,

i want to block all direct access to images

(https://xyz.com/storage/app/media/example.jpg)

i blocked it via htaceess but problem is that when i click on “open image in n ew windows” it is still serving but after refresh it is 403.

how can i achieve this?

htaccess is

<IfModule mod_rewrite.c>
    RewriteEngine On

    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    # Handle Authorization Header
    RewriteCond %{HTTP:Authorization} .
    RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    # ====================================================
    # Block direct access & hotlinking to /storage/app/media/
    # ====================================================
    RewriteCond %{REQUEST_URI} ^/storage/app/media/.*\.(jpe?g|png|gif|webp|svg|ico)$ [NC]
    RewriteCond %{HTTP_REFERER} !^https?://(www\.)?(xyz\.de|xyz\.de) [NC]
    RewriteRule ^ - [F,L]

    # ====================================================
    # Block access to sensitive directories
    # ====================================================
    RewriteRule ^(bootstrap|config|vendor|storage/cms|storage/logs|storage/framework|storage/temp/protected|storage/app/uploads/protected)/ - [F,L]

    # ====================================================
    # Allow access to public assets
    # ====================================================
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_URI} !^/(index\.php|\.well-known|app/(assets|resources)|storage/(app/(resources|uploads/public)|temp/public)|themes/.*/(assets|resources)|plugins/.*/(assets|resources)|modules/.*/(assets|resources))/
    RewriteRule ^ - [L]

    # ====================================================
    # Block direct access to PHP files (except index.php)
    # ====================================================
    RewriteCond %{REQUEST_FILENAME} -f
    RewriteCond %{REQUEST_FILENAME} \.php$
    RewriteRule !^index\.php$ - [F,L]

    # ====================================================
    # Front controller (send everything to index.php)
    # ====================================================
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ index.php [L]
</IfModule>

Hi @ibrarartisan Try to add:

RewriteRule ^storage/app/media/.* index.php [L,NC]

to .htaccess (in Black Listed folder section)

thanks but this blocks all the images in the frontend.

Yes, sorry, this blocks every traffic. Try this:

Add the following to .htaccess ( not serve files directly, but instead send them to index.php):

# Intercept requests to /storage/media
RewriteCond %{REQUEST_URI} ^/storage/app/media
RewriteRule ^.*$ index.php [L]

Then create a Middleware, something like this:

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class PreventDirectMediaAccess
{
    public function handle(Request $request, Closure $next): Response
    {
        // Example: Block if no referrer or not from your domain
        $referer = $request->headers->get('referer');

        if (!$referer || !str_contains($referer, config('app.url'))) {
            abort(403, 'Direct access to media files is not allowed.');
        }

        return $next($request);
    }
}

Finally define a route with the middleware:

Route::get('storage/app/media/{path}', function () {
})->where('path', '.*')->middleware(\Path\To\Your\Middleware::class);
2 Likes