Настройка защиты изображений от копирования 1С-Битрикс

Наша компания занимается разработкой, поддержкой и обслуживанием решений на Битрикс и Битрикс24 любой сложности. От простых одностраничных сайтов до сложных интернет магазинов, CRM систем с интеграцией 1С и телефонии. Опыт разработчиков подтвержден сертификатами от вендора.
Предлагаемые услуги
Показано 1 из 1 услугВсе 1626 услуг
Настройка защиты изображений от копирования 1С-Битрикс
Простая
~1 рабочий день
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1173
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    811
  • image_bitrix-bitrix-24-1c_development_of_an_online_appointment_booking_widget_for_a_medical_center_594_0.webp
    Разработка на базе Битрикс, Битрикс24, 1С для компании Development of an Online Appointment Booking Widget for a Medical Center
    564
  • image_bitrix-bitrix-24-1c_mirsanbel_458_0.webp
    Разработка на базе 1С Предприятие для компании МИРСАНБЕЛ
    745
  • image_crm_dolbimby_434_0.webp
    Разработка сайта на CRM Битрикс24 для компании DOLBIMBY
    655
  • image_crm_technotorgcomplex_453_0.webp
    Разработка на базе Битрикс24 для компании ТЕХНОТОРГКОМПЛЕКС
    976

Настройка защиты изображений от копирования 1С-Битрикс

Конкуренты копируют фотографии товаров с водяным знаком компании — это происходит постоянно. Полностью остановить загрузку изображений невозможно, но можно поднять стоимость копирования до уровня, когда проще снять свои фотографии.

Что реально работает, что нет

Не работает:

  • Запрет правой кнопки мыши через JavaScript (oncontextmenu="return false") — отключается в браузере за 3 секунды
  • CSS pointer-events: none — изображение всё равно доступно через DevTools
  • Запрет сохранения через JS-обработчик dragstart — копируется через скриншот или сетевую вкладку

Работает:

  • Водяной знак, нанесённый на изображение на сервере — сложно убрать, если знак полупрозрачный и расположен в центре
  • Отдача изображений через PHP с проверкой реферера — замедляет хотлинкинг
  • Подмена URL изображений на ресурс с авторизацией

Водяной знак через GD

Наиболее практичный подход — нанесение водяного знака при загрузке изображения в Битрикс. Обработчик события OnAfterFileSave:

// /local/php_interface/init.php
AddEventHandler('main', 'OnAfterFileSave', ['\Local\Security\WatermarkHandler', 'apply']);
namespace Local\Security;

class WatermarkHandler
{
    private const ALLOWED_DIRS = ['/upload/iblock/', '/upload/catalog/'];
    private const WATERMARK    = '/local/images/watermark.png';

    public static function apply(array $file): void
    {
        $path = $file['PATH'] ?? '';

        // Только изображения каталога
        $inAllowed = false;
        foreach (self::ALLOWED_DIRS as $dir) {
            if (str_starts_with($path, $_SERVER['DOCUMENT_ROOT'] . $dir)) {
                $inAllowed = true;
                break;
            }
        }

        if (!$inAllowed) return;
        if (!in_array(strtolower($file['CONTENT_TYPE'] ?? ''), ['image/jpeg', 'image/png', 'image/webp'])) return;
        if (!file_exists($path) || !file_exists($_SERVER['DOCUMENT_ROOT'] . self::WATERMARK)) return;

        self::applyWatermark($path, $_SERVER['DOCUMENT_ROOT'] . self::WATERMARK);
    }

    private static function applyWatermark(string $imagePath, string $wmPath): void
    {
        $imgInfo = getimagesize($imagePath);
        if (!$imgInfo) return;

        // Загружаем исходное изображение
        $image = match ($imgInfo[2]) {
            IMAGETYPE_JPEG => imagecreatefromjpeg($imagePath),
            IMAGETYPE_PNG  => imagecreatefrompng($imagePath),
            default        => null,
        };

        if (!$image) return;

        $wm     = imagecreatefrompng($wmPath);
        $imgW   = imagesx($image);
        $imgH   = imagesy($image);
        $wmW    = imagesx($wm);
        $wmH    = imagesy($wm);

        // Масштабируем знак до 30% ширины изображения, если он крупнее
        if ($wmW > $imgW * 0.3) {
            $ratio = ($imgW * 0.3) / $wmW;
            $newWmW = (int)($wmW * $ratio);
            $newWmH = (int)($wmH * $ratio);
            $resizedWm = imagecreatetruecolor($newWmW, $newWmH);
            imagealphablending($resizedWm, false);
            imagesavealpha($resizedWm, true);
            imagecopyresampled($resizedWm, $wm, 0, 0, 0, 0, $newWmW, $newWmH, $wmW, $wmH);
            imagedestroy($wm);
            $wm   = $resizedWm;
            $wmW  = $newWmW;
            $wmH  = $newWmH;
        }

        // Позиция: центр изображения
        $dstX = (int)(($imgW - $wmW) / 2);
        $dstY = (int)(($imgH - $wmH) / 2);

        imagecopy($image, $wm, $dstX, $dstY, 0, 0, $wmW, $wmH);

        // Сохраняем обратно
        match ($imgInfo[2]) {
            IMAGETYPE_JPEG => imagejpeg($image, $imagePath, 90),
            IMAGETYPE_PNG  => imagepng($image, $imagePath, 7),
        };

        imagedestroy($image);
        imagedestroy($wm);
    }
}

Защита от хотлинкинга через nginx

location ~* \.(jpg|jpeg|png|gif|webp)$ {
    valid_referers none blocked ~\.yourdomain\.com;
    if ($invalid_referer) {
        return 403;
    }
}

Или подменяем изображение при хотлинкинге:

location ~* \.(jpg|jpeg|png|gif|webp)$ {
    valid_referers none blocked ~\.yourdomain\.com;
    if ($invalid_referer) {
        rewrite ^ /local/images/hotlink-protected.jpg last;
    }
}

Отдача изображений через PHP (для приватных каталогов)

Если изображения должны быть доступны только авторизованным пользователям:

// /local/ajax/secure-image.php
$fileId  = (int)($_GET['id'] ?? 0);
$token   = $_GET['token'] ?? '';

if (!validateImageToken($fileId, $token)) {
    http_response_code(403);
    exit;
}

$file = \CFile::GetFileArray($fileId);
if (!$file) { http_response_code(404); exit; }

$path = $_SERVER['DOCUMENT_ROOT'] . $file['SRC'];
if (!file_exists($path)) { http_response_code(404); exit; }

header('Content-Type: ' . $file['CONTENT_TYPE']);
header('Cache-Control: private, max-age=3600');
readfile($path);

Токен — HMAC от ID файла и соли: hash_hmac('sha256', $fileId, SECRET_KEY).

Практические рекомендации

Водяной знак работает в сочетании с грамотным дизайном: полупрозрачный логотип в центре сложнее убрать, чем угловой. Для ценных товаров (ювелирка, дизайнерская мебель) — наносить на 100% изображений. Для массового каталога с тысячами SKU — только на главное изображение товара. Изображения брендов от поставщиков водяным знаком не трогаем — контракты запрещают.