Pull to refresh

Comments 50

UFO just landed and posted this here
Фотографии хранятся на CDN. Статика по авторизации (=сверх короткий кеш) стоит дорого очень дорого. Можно, конечно, ввести доп параметр ?sid=[a-zA-Z0-9]{32} к примеру, без которого основа будет выдавать заглушку, но такие операции (как и авторизация) не планировались.
Поэтому CDN сервер отдает все, что ему отдает основной сервер.
UFO just landed and posted this here
Согласен, что timestamp не даст абсолютной защиты от "очень любопытного" пользователя. Но от "просто любопытного" защитит.
  • P20140903170712.jpg
  • P20140903170833.jpg

Как минимум 48+33 вариантов, лучше чем 1н.
Поэтому в статье рассмотрен вариант рандомных префиксов, которые можно перебирать достаточно долго.

Любая система уязвима, не только WP.
у меня все фото отдаются по соли и id. соль a-z0-9. id просто 0-9. перебирать замучаешься :)
То есть у вас может быть один и тот же файл, но с разными id и солью?
Вообще да, на самом деле архитектора такова что это не имеет значение. Всегда есть запись в бд и запрос идет через cdn на сервера обработки фотографий где кусок от laravel и запрос к бд, и если фото найдено, то выдается локальный редирект на nginx который уже его и отдает и ресайзит при необходимости. Помимо эоого соль помогает понять на каком сервере физически находится изображение.
Я правильно понимаю: вы предлагаете править файл «functions.php» после каждого обновления Wordpress? Да и вообще, правка файлов CMS — моветон.
Да, я не php программист и писать плагины под WP не умею. Правка — громко сказано, всего лишь заменить одну строчку на другую.
На счет того, mauvais tone или нет — если CMS позволяет отключать некоторый функционал в конфигах то правка не нужна, но если она использует некоторые функции, которые никак не отключить, то, конечно, можно их поправить.
Вы понимаете, что после обновления CMS все ваши изменения канут в Лету? Вы после каждого обновления будете проделывать эту процедуру или собираетесь отказаться от обновлений?

Ваша статья из разряда вредных советов и является довольно костыльным решением. Вы решаете одну проблему создавая другую. Если вы не php программист и не знаете как лучше решить вопрос без последствий — то лучше всего будет обратится к тем, кто знает.
Ваша статья из разряда вредных советов и является довольно костыльным решением. Вы решаете одну проблему создавая другую. Если вы не php программист и не знаете как лучше решить вопрос без последствий — то лучше всего будет обратится к тем, кто знает.

Это вы загнули. Во-первых такие обновления можно автоматизировать. WP кроме вас никто не обновит. Значит после обновления запустить скрипт, который пропатчит нужный вам файл.
Во-вторых избежать ахтунга после автопатчинга позволит чтение changelog (вы ведь их читаете?) и создание копии файла.
Я предпочитаю решать проблемы методом «сделал и забыл», вы можете делать это как вам удобно, но зачем других так учить? Хотя бы в статью добавьте информацию о том, с какими трудностями в дальнейшем столкнется пользователь, который решит воспользоваться вашим методом.
Очевидно, что если человек лезет во внутренности ПО и ПО обновляется, то он должен понимать, что результаты его работы могут быть перетерты. Сделал и забыл в текущих реалиях (hb/poodle) уже не работает, все приходится переделывать :)
Добавил комментарий и diff файл.
Статья, точнее «статья», из раздела «вредные советы».

Никогда нельзя править код CMS, только расширять предоставляемыми ею способами. Про проблемы обновления, совместимости уже выше сказали.

Microtime — это не ГСПЧ. Если уж генерируете хеш, делайте это нормально. CRC32 — это не хеш, а код проверки целостности.

Изучайте PHP, если это вам интересно. Полезное дело. Давать вредные советы — вредное дело, если вы не Г. Остер.
Microtime — это не ГСПЧ.

Статьи не читали, контекста не поняли?

CRC32 — это не хеш, а код проверки целостности.

Повторяю вопрос, заданный строчками выше.
Статью читал, контекст понял. Не понял, зачем публиковать такое вместо того чтоб разобраться как это делать правильно. Но дело, конечно, ваше.
Я не вижу ничего зазорного в том, чтобы редактировать исходный код хоть WP, хоть nginx, хоть того же gnupg так, как я этого хочу, и затем использовать продукт.
Правка кода после каждого обновлений — если это помогает решать какую-либо задачу, это уже не пустая трата времени.
Конечно можно извернуться, вникнуть во внутреннюю архитектуру и затем сделать людям плагин, который будет жить пока совместим, а можно сделать diff, который увеличит длину ключа и буфер (как с gnupg), или расширит листинг папок со стандартных 50 символов (nginx). И еще много разного мелкого софта, где своя польза. Тот же postfix и самопальные квоты, если кто помнит.

Поэтому фраза, что это сделано неправильно в корне неверна. Это открытое ПО с, естественно, открытым кодом. А раз код открыт, то его можно модифицировать. Главное знать что хочешь получить и что нужно править.
Классно, но почему префикс, а не суффикс? Сортировка же полетит к чертям. Не?
Спасибо. Сортировка «где»?
post_title, post_name — неизменны. Только guid отличаются. То бишь если закачали image.jpg, то только в guid будет 12345_image.jpg
Поправьте меня, если я не прав, но, похоже, что более чистого способа изменить переменную $filename в WordPress до сих пор не предусмотрено, хотя просьба добавить фильтр для функции wp_unique_filename висит с 2011 года: pytest-commit.git.net/wp-trac/msg57744.html
Это значит, что простым плагином здесь, к сожалению, не отделаться.
Интересный поворот, спасибо!
Даже в ветке тикета они предлагают diff.
Зачем добавлять файлу префикс, если можно просто класть его в рандомную директорию?
Сугубо личное мнение — неудобно. Иногда, когда консоль запущена, простой ls с копирую имя файла, чтобы кому-то скинуть ссылку и глазу приятнее видеть файлы.
В случае с рандомными папками придется использовать find вместо ls для ручного поиска, только и всего.
метод «название файла = его хэш + правильное расширение, в папке — две/три буквы этого хэша» решат указанные проблемы и бонусом: вычисление уникального содержимого; снисходительность к просмотрщикам, которые задумываются над большим кол-вом файлов в папке; это его id — если задать соотв. генератор последовательностей в базе.
название файла = его хэш + правильное расширение, в папке — две/три буквы этого хэша

Тогда пропадает оригинальное название файла, что для меня неприемлемо.
тогда почему бы не использовать имя, данное пользователем?
как вариант, можно вставить в случайных местах «невидимые» символы, типа неразрывного пробела, благодаря современной поддержке юникода.
вставить в случайных местах

Это уже больше чем 1-на строка кода, если только не писать подряд через ";" :)
Тогда я не смогу удобно искать файлы. Файл «image_h ol idays .jpg» по слову «holidays» не найти (в папке на сервере).
Так же если захочется сделать что-нибудь на основе аплоада WP, но без базы WP, то пробелы будут резать глаз.
Это tutorial не человеку, который поставил WP на shared хостинг или у которого он автообновляется, а тому, кто использует его как минимум на виртуалке и перодически работает с файлами на уровне MC, а не cpanel'ного редактора.

Большая же часть критиков пытается упростить донельзя работу с WP, поставив его в корень / apache и дав ему доступ к автоапдейтам, крайне негодуя против правки исходников as is.

Но жизнь после install продолжается!
1. Создайте файл в /wp-content/plugins/
2. В начале файла напишите блок с комментарием:
/**
 * Plugin Name: %Имя_Вашего_Великолепного_Плагина%
 */

3. add_action на add_attachment
4. По ID аттачмента меняйте ему имя
5. Включайте свой плагин

Это было бы быстрее и практичнее, чем каждый раз править файлы движка.
Плагин в WP будет работать по принципу:
  • загрузил файл на сервер
  • взял id аттача
  • переименовал загруженный файл

?
Да. «add_attachment» срабатывает после загрузки аттачмента и в кач-ве параметра передаст ID. По ID можно получить все данные по аттачменту и делать с ним что угодно
В таком случае не подходит. На лицо лишние файловые операции, причем как по оригиналу так и по превьюшкам. Именно поэтому я про загрузку и спрашивал.
Дело, конечно, Ваше. По мне, так проще один раз плагин на 10-15 строчек написать, чем править код движка :)
Вот сегодня прилетело обновление и что я сделал? Я запустил patch. Не вижу трудностей.
На сервер по ssh я могу и со смартфона зайти в любой точке мира.
Вот сегодня прилетело обновление и что я сделал? — Ничего, потому что написал плагин и в любой точке мира, даже без интернета сплю спокойно.

Минусы вашего решения:
— Нужно после каждого обновления править файлы движка
— Можно править движок с помощью patch, но на шаред хостинга такой вариант не прокатит
— Минимальные изменения в исходном коде строки, которую нужно заменить и ваш diff файл поломан, нужно его править ( опять :-( ). Да даже банальное переименование файла и вам снова нужно лезть и копаться в коде

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

В сухом остатке имеем костыльное решение (правка движка), которое порождает неудобства (необходимость повторения операции после каждого обновления движка), которые в свою очередь решаются еще одним костылём (diff файл, который не имеет никаких гарантий, что правила прописанные в нём сработают, так как исходный файл может быть изменен в процессе обновления).

Еще раз повторюсь: вы можете делать со своим сайтом что и как вам вздумается, это ваше право, но зачем учить плохим решениям других и еще и доказывать, что это лучшее решение?
Ничего, потому что написал плагин и в любой точке мира, даже без интернета сплю спокойно.

Поделитесь ссылкой на ваш плагин с wordpress.org.

В сухом остатке имеем костыльное решение (правка движка), которое порождает неудобства (необходимость повторения операции после каждого обновления движка), которые в свою очередь решаются еще одним костылём (diff файл, который не имеет никаких гарантий, что правила прописанные в нём сработают, так как исходный файл может быть изменен в процессе обновления).

Вы чрезмерно драматизируете и паникуете. patch можно обернуть в bash скрипт, который проверит --dry-run проходит ли он, и если все в порядке — удаляет .orig файл и применяет diff. В противном случае сообщает пользователю что что-то поменялось внутри файла.

Если вдруг WP переименует functions.php, это тоже не конец света, а всего лишь новое имя файла в команде, скопировать и вставить. Далее как написано выше — если пользователь обернул patch, то его скрипт сообщит то, что он в него заложил. Иначе первый «сухой» прогон выдаст ошибку.
Так никто и не говорит, что ситуация не поправимая, но это не отменяет того, что это минусы. Для того, чтобы работал плагин не нужен доступ по SSH, не нужны патч файлы, не нужны bash скрипты и не нужно никуда лезть и что-то редактировать и менять. Всё что нужно — это установить и запустить плагин, с этим справится даже самый неопытный пользователь. Ваше решение требует наличие некоторого количества умений, больше доступа и больше телодвижений. Плагин — это отличная альтернатива решения проблемы которая лишена всех этих недостатков и ваше решение на его фоне выглядит плохим.

Если бы вы написали, что «да, моё решение не идеально, но тем не менее оно имеет право на жизнь хотя бы потому, что показывает как можно решать проблемы, которые нельзя решить с помощью плагинов», то я бы на этом и завершил диалог. Но вы упрямо продолжаете доказывать, что все те минусы на которые вам указывают полная ерунда и не стоят выеденного яйца.
Ваше решение требует наличие некоторого количества умений, больше доступа и больше телодвижений

Так статья изначально была об этом. Добавление нужного функционала путем модификации софта. Что замечательно — код был улучшен и сокращен, о чем я указал.
А вы пытаетесь переписать ее через меня «как сделать тоже самое, но через плагин».
Я согласен с вами, что плагин это очень простое решение, ниже по ветке есть даже пример вроде бы рабочего плагина.
Теперь кому-то надо сделать статью про аналогичный функционал и про плагин + запостить таки на оффресурсе.
/**
 * Plugin Name: %Имя_Вашего_Великолепного_Плагина%
 */

add_action('add_attachment', function ($attachmentId) {
    $attachment = get_post($attachmentId);
    $path = get_attached_file($attachmentId);

    // в $path у Вас полный путь к файлу, а в $attachment - объект WP_Post вашего аттачмента
    // ... здесь Ваша логика для того, чтоб переименовать файл.
});


Вот по сути весь Ваш плагин. Вам просто нужно в объекте $attachment заменить урл в свойстве guid на новый, который будет вести к переименованному файлу. Как-то так:
$uploads = wp_upload_dir();

wp_update_post(array(
    'ID'   => $attachment->ID,
    'guid' => trailingslashit($uploads['url']) . basename($path_to_renamed_file)
))
Опубликуйте и если оно работает, то сообщество WP скажет вам спасибо.
На здоровье
<?php

/**
 * Plugin Name: Rename Attachments
 */

/**
 * Class RenameAttachments
 * @package RenameAttachments
 */
class RenameAttachments
{
    /**
     * Hooks the "add_attachment" action.
     */
    public static function register()
    {
        add_action('add_attachment', array(__CLASS__, 'rename'));
        add_filter(
            'filter_attachment_filename',
            array(__CLASS__, 'filterAttachmentFileName')
        );
    }

    /**
     * Filters attachment file name.
     * @param string $file Attachment file name.
     * @returns string
     */
    public static function filterAttachmentFileName($file)
    {
        return crc32(md5(mt_rand() . microtime()) . sanitize_file_name($file)) . '_' . sanitize_file_name($file);
    }

    /**
     * Renames the attachment.
     * @param int $attachmentId Attachment ID.
     */
    public static function rename($attachmentId)
    {
        if (!$path = get_attached_file($attachmentId)) {
            return;
        }

        $trash = array();
        $uploads = wp_upload_dir();
        $original = basename($path);

        $filtered = apply_filters(
            'filter_attachment_filename',
            $original
        );

        $images = glob(dirname($path) . '/' . pathinfo($original, PATHINFO_FILENAME) . '*');
        if ($images === false || (is_array($images) && count($images) === 0)) {
            return;
        }

        foreach ($images as $image) {
            $name = str_replace($original, $filtered, $image);
            if (copy($image, $name)) {
                $trash[] = $image;
            }
        }

        $path = dirname($path) . '/' . $filtered;
        $attachedFile = str_replace($uploads['basedir'] . '/', '', $path);

        if (update_post_meta($attachmentId, '_wp_attached_file', $attachedFile) === true) {
            foreach ($trash as $file) {
                @unlink($file);
            }
        }
    }

}

RenameAttachments::register();

Не мне публикуйте, а сообществу WP:)
	$bs_extid=strpos(strrev(sanitize_file_name($filename)),".");
	if($bs_extid){
		$bs_extid=strlen(sanitize_file_name($filename))-1-$bs_extid;
		$filename = substr(sanitize_file_name($filename),0,$bs_extid)."_".crc32(md5(microtime()).sanitize_file_name($filename))."_".substr(sanitize_file_name($filename),$bs_extid);
	} else {
		$filename = sanitize_file_name($filename)."_".crc32(md5(microtime()).sanitize_file_name($filename)).sanitize_file_name($filename)),0,16);
	}
Зачем городить такой огород?

$filename = sanitize_file_name($filename);
$filename = pathinfo($filename, PATHINFO_FILENAME) . '_' . mt_rand() . (pathinfo($filename, PATHINFO_EXTENSION) ? '.' . pathinfo($filename, PATHINFO_EXTENSION) : '');

И crc32(), и mt_rand() возвращают int. Зачем считать crc32 от md5 от имени файла, если проще и надежднее взять псевдослучайное число. Повторная вычислимость? Для этой задачи наоборот она не нужна. Иначе злоумышленник точно так же как просто перебрать фотки по номерам сможет заново высчитать «мусор», перебирая фотки по номерам.
Спасибо за короткий вариант.

md5 был не от имени файла, а от имени файла + микротайма, поэтому не перебрать по основе:)
Если злоумышленник знает время загрузки файла, то можно перебрать. И чем точнее он знает время, тем меньше запросов нужно.

В принципе, вообще int перебрать не так сложно. Поэтому несмотря на «некрасивость», лучше использовать более длинный (в битах энтропии) «мусор».
Обновил на ваш вариант и указал комментарий.
Там можно помимо mtrand использовать и текстовую строку. Которую знает только владелец. "blablabla" была упомянута в статье как пример. В таком случае даже зная время создания файла и имя файла не получить следующего файла, так как неизвестна строка, участвующая в генерации.
Запустите на свои альбомы renrot — и дело с концом!
Хмм, даже не слышал о нем. Я вот так делаю правильные «копии» с датойвременем:
for file in *; do cp $file ${file}_`identify -format '%[EXIF:DateTimeOriginal]' $file|sed 's/[ :]//g'`.jpg ;done
Можно и mv делать, если места мало.
Ну, он есть в поставках Debian и Fedora несколько лет как. Там хороший мануал по теме.
Sign up to leave a comment.

Articles