Защита скрипта, предназначенного для крона, от случайного запуска из вне

Всем привет!

Вот есть скрипт, который лежит в корне сайта, и который предназначен для запуска через крон. Как предотвратить его выполнение при запуске из браузера?

P.S. Предположим, что кто угодно может обратиться к этому файлу, набрав его в адресной строке и кто угодно знает адрес.
И желательно разрешить выполнять его залогиненному админу.

Я накидал вот такое решение:
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);

define('MODX_API_MODE', true);
require 'index.php';

$modx->getService('error','error.modError');
$modx->setLogLevel(modX::LOG_LEVEL_INFO);
$modx->setLogTarget(XPDO_CLI_MODE ? 'ECHO' : 'HTML');

$userId = $modx->user->id;
if ($userId != 1 && !XPDO_CLI_MODE) {
    header('HTTP/1.1 404 Not Found');
    exit;
}
if (!XPDO_CLI_MODE) set_time_limit(0);

Достаточно ли этого? Или есть ещё какие-нибудь нюансы?
Спасибо!
Алексей Карташов
20 февраля 2013, 07:47
modx.pro
2
3 948
0

Комментарии: 18

Василий Наумкин
20 февраля 2013, 12:16
0
Можно просто по ip проверять.
    Алексей Карташов
    20 февраля 2013, 12:26
    0
    ну когда ip домашнего компа — динамика, да ещё и с частыми реконнектами, то не выход)
      Евгений Дурягин
      20 февраля 2013, 12:40
      0
      Дак вы все-таки скрипт хотите запускать на сервере по крону или из браузера?
        Алексей Карташов
        20 февраля 2013, 12:51
        0
        И так, и так.

        Представьте ситуацию, что есть некий сайт, который предоставляет некое апи для доступа к своим данным, которые периодически обновляются. Заранее об обновлениях неизвестно, да и обновления не такие уж и частые.
        Поэтому пишем скрипт для работы с этим апи, чтобы проверять обновления данных и отображать их у себя, ставим в крон, к примеру раз в сутки в ночное время, когда нагрузка на сервер небольшая. А может быть и раз в двое суток — обновления-то не частые.

        Но вот я заметил, что произошло обновление этих данных на том самом сайте и мне не за чем ждать до ночи, чтобы эти обновления увидеть у себя. А то и до ночи следующего дня.
        Тогда я просто логинюсь в админку, открываю в браузере свой файл и, собственно, вуаля :-)
          Евгений Дурягин
          20 февраля 2013, 12:57
          0
          Ну тогда комбинация авторизованный пользователь или IP. Сервер то всегда выполняет скрипт от не авторизованного пользователя. Можно конечно предусмотреть авторизацию при выполнении из крона, но по мне это лишнее усложнение кода.
            Алексей Карташов
            20 февраля 2013, 13:03
            0
            Так серверной авторизации-то и не надо. Из командной строки сервера этот скрипт смогу запустить только я (и крон). А вот из браузера не только я.

            Поэтому отсекаем всех, кто не из консоли и кто запускает скрипт через веб-сервер, кроме авторизованного юзера с id администратора. который залогинен:
            if ($modx->user->id != 1 && !XPDO_CLI_MODE) {
            	// ...
            Просто может есть ещё какие-то тонкости, о которых я не подумал?
              Іван Клімчук
              20 февраля 2013, 13:18
              0
              А зачем такой огород городить внутри файла?

              Если вы можете через консоль сами обновить данные, и крон это делает сам, то закройте файл вообще для внешнего мира через конфиг nginx или apache.

              Нужно — зашли на сервер по ssh, запустили свой скрипт и все.
                Алексей Карташов
                20 февраля 2013, 13:31
                0
                Вы безусловно правы, но не везде есть возможность использовать putty. Да и с планшета/мобильника куда проще сперва залогиниться, а потом открыть файл, чем искать и настраивать ssh-клиенты для ондроеда и иос)

                Ну это уже больше прихоти, конечно :-) Да к тому же, не сильно влияющие на конечную безопасность.

                Да и не такой уж и большой огород :-)
                if ($modx->user->id != 1 && !XPDO_CLI_MODE) {
                    header('HTTP/1.1 404 Not Found');
                    exit;
                }
                if (!XPDO_CLI_MODE) set_time_limit(0);
    Мордынский Николай
    20 февраля 2013, 14:01
    0
    Вообще с помощью .htaccses можно черта лысого сделать можно поставить пароль на дерикторию или файл можно вообще запретить открытие его из вне либо использовать выше указанный пакет
      Алексей Карташов
      20 февраля 2013, 14:41
      0
      Про паролирование через htaccess и htpasswd знаю и пользуюсь, да.
      Но планирую слезать с апача. А nginx пока не знаю. С ним ещё только буду разбираться.
      Поэтому такой вариант не особо рассматриваю. Но спасибо, что напомнили :-)
        Василий Наумкин
        20 февраля 2013, 17:14
        0
        В nginx base auth тоже есть.
          Алексей Карташов
          20 февраля 2013, 17:47
          0
          Да это понятно) Было бы удивительно, если бы его не было :-) Это ж nginx!
          Просто времени с этим разбираться пока нету, а переезд будет не завтра и не послезавтра. Поэтому изучение nginx'а пока откладываю.
          А вот решение с кроном уже сейчас нужно.
      Олег Максименко
      20 февраля 2013, 14:38
      0
      а почему бы не добавить какой нибудь параметр к урлу и потом его проверять?

      <?php
      if(!isset($_GET['key']) || $_GET['key'] != 'DY3lcju42hwC') exit();
      
      // выполнение скрипта
      
      ?>
      а запускать так:
      site.ru/cron.php?key=DY3lcju42hwC
        Алексей Карташов
        20 февраля 2013, 14:46
        0
        Ну это вообще не защита :-)
        Такой адрес запишется во все логи по всей цепочке «пользователь» => «сервер».
        В том числе всякими Яндекс.Недобраузерами и иже с ними, роботы которых любят посещать проснифанные урлы на предмет индексации.
        Так что это вообще не выход)
          Олег Максименко
          20 февраля 2013, 14:59
          0
          а как по вашему делают? например, апи с токенами для входа? если всё проснифанно
            Алексей Карташов
            20 февраля 2013, 15:07
            0
            Это смотря что вы имеете ввиду под апи с токенами для входа. Сходу сказать не могу — потому что реализаций море и у всех по своему. Поэтому пример немного не корректен. Если бы вы конкретный пример привели, можно было бы посмотреть)
        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        18