📜 ⬆️ ⬇️

Protection from saving images

image
Hello, dear harbread readers.
Some time ago I ran into a very, in my opinion, an interesting task. The essence of the task was that it was necessary to complicate the process of saving images from the pages of the site. In this case, the pictures can be of different sizes.

The task is clear, let's proceed to its solution. In general, the process of saving a picture is quite simple: click on it with the right mouse button and in the opened menu select “Save image ...” (the inscription may differ in different browsers). Intercepting the right-click of a mouse partially solves this problem, but bypassing this restriction is an outrageous way simple - we disable JavaScript and calmly call the context menu. In this case, it is enough to make a picture as a background image:


<div id="img" style="width: 220px; height: 130px; background-image: url(http://example.ru/img/Habrahabr_logo.png);"></div> 

But in this example, the fixed block size, and under the conditions of the problem, the size can be any. This is where PHP comes to the rescue and the getimagesize () function.
 $size = getimagesize(ROOT."/img/Habrahabr_logo.png "); $html = "<div id=\"img\" style=\"width: {$size[0]}px; height: {$size[1]}px; background-image: url(http://example.ru/img/Habrahabr_logo.png);\"></div>"; echo $html; 

The problem is almost solved, but in the code of the page there is a direct link to this image, according to which you can safely download it: you can simply copy the address of the image and paste it into the address bar of the browser and save. But not everything is as bad as it seems at first glance. It is enough to write a simple script and through it to give the image to the browser, while checking the referrer header, and if it is missing or different from example.ru, then give an error. It is worth noting here that in order to improve performance and security, in solving this problem, information about the image was stored in a database. Each image had a unique identifier that could be passed to the script (image.php):
 <?php define("ROOT", dirname(__FILE__)); include_once ROOT."/images_db.php"; if (isset($_SERVER['HTTP_REFERER']) && eregi("example.ru", $_SERVER['HTTP_REFERER'])) { $img_path = ROOT."/img/".$images[intval($_GET['id'])]['file_name']; switch ($images[intval($_GET['id'])]['file_ext']) { case "png": $image = imagecreatefrompng($img_path); header("Content-Type: image/png"); imagepng($image); break; case "jpg": $image = imagecreatefromjpeg($img_path); header("Content-Type: image/jpeg"); imagejpeg($image); break; case "gif": $image = imagecreatefromgif($img_path); header("Content-Type: image/gif"); imagegif($image); break; } } else { $img_path = ROOT."/img/no_image.jpg"; $image = imagecreatefromjpeg($img_path); header("Content-Type: image/jpeg"); imagejpeg($image); break; } @imagedestroy($image); ?> 

The file images_db.php stores an array with a description of pictures, this is done solely for example:
 <?php $images = array("123" => array("file_name" => "Habrahabr_logo.png", "file_ext" => "png", "file_id" => "123"), "124" => array("file_name" => "php-logo1.jpg", "file_ext" => "jpg", "file_id" => "124"), "125" => array("file_name" => "google-logo.gif", "file_ext" => "gif", "file_id" => "125")); ?> 

Replace the direct link to the image in the code and the index.php file will look like this:
 <?php define("ROOT", dirname(__FILE__)); include_once ROOT."/images_db.php"; $html = ""; foreach($images as $im) { $size = getimagesize(ROOT."/img/".$im['file_name']); $html .= "<div id=\"img{$im['file_id']}\" title=\"File name: {$im['file_name']}, File width: {$size[0]}px, File height: {$size[1]}px\" style=\"width: {$size[0]}px; height: {$size[1]}px; background-image: url(http://example.ru/image.php?id={$im['file_id']});\"></div>\r\n"; } echo $html; ?> 

Now, when directly accessing the address example.ru/image.php?id=123, we will receive a no_image.jpg image, since the referrer header is not transmitted.
')
There are only two ways to pull out the picture: to fake a request or to take a screenshot. Unfortunately, I did not find a solution that could withstand these methods. But from the majority of inexperienced users protection is quite working.

I hope this information will be useful to anyone.
Thanks for attention.

Sample sources

Source: https://habr.com/ru/post/132228/


All Articles