Безопасная подача изображений в сочетании с использованием ImageResizer

[Это дополнительный / очищенный вопрос относительно предыдущего обсуждения здесь с компьютерным лингвистом, надеюсь, я указал это достаточно] Может ли ImageResizer захватывать файлы вне корня сайта и обслуживать их (таким образом избегая размещения неизмененных оригиналов в Интернете)? Или что лучше всего подходит для этого сценария?

* Должны ли оригиналы храниться за пределами корня сайта, изображение с измененным базовым размером должно храниться в Интернете (защищено с помощью проверки подлинности URL / httpmodule и т. д.), а затем позволить Imageresizer изменять размер на лету для больших пальцев и т. д. на основе этого изображения? Насколько я видел, я не нашел способа ограничить доступ к папке на 100%, за исключением случаев, когда это запрашивается через imageresizer. Если ImageResizer может изменять размер, пользователь может получить доступ к нему, кажется, иначе.

* Или, возможно, это решение с контроллером, обслуживающим исходное изображение, а затем обрабатывается ImageResizer.

Ключевая цель:

  1. Возможность полностью настроить правила разрешений

  2. Быть в состоянии обслуживать безопасным образом (по крайней мере, насколько я знаю, неизмененные изображения, загруженные пользователем, не должны быть доступны непосредственно в корне сайта). И сохранение оригиналов кажется перспективной стратегией.

  3. Иметь возможность использовать великолепие ImageResizer для изменения размера на лету.

Также приветствуется любой вклад в то, как другие реализовали это.


person Base    schedule 05.08.2012    source источник


Ответы (1)


  1. Расположение файлов вне корня сайта ничего не дает. Вам все равно придется смонтировать их как виртуальную папку, чтобы снова сделать их доступными.
  2. MVC написан таким образом, что здесь он будет абсолютно бесполезен — мусолит до тех пор, пока ProcessRequest ничего не сделает.
  3. ImageResizer совершенно не имеет отношения к этому вопросу - для ваших целей он ведет себя как StaticFileHandler - вам нужна общая система авторизации.
  4. Авторизация URL-адреса ASP.NET звучит как он может быть недостаточно сложным для желаемого уровня сложности.

Чтобы выполнить пользовательскую логику авторизации, вам потребуется обработать событие AuthorizeRequest в конвейере HTTP и реализовать логику синтаксического анализа пути с нуля. Вы можете обработать это событие в Global.asax.cs или путем реализации IHttpModule.

В AuthorizeRequest вы можете получить доступ к входящему пути и данным строки запроса до того, как ImageResizer или любой другой HttpModule или HttpHandler когда-либо увидит их, решить, должен ли пользователь иметь доступ к ним сегодня, и либо разрешить выполнение запроса, либо выдать ошибку HTTP 401. .

Я предлагаю использовать ILSpy для просмотра модуля UrlAuthorizationModule, найденного в System.Web.Security. Это всего пара страниц кода, и довольно просто.

person Lilith River    schedule 06.08.2012
comment
Ранее я немного просмотрел AuthorizeRequest и создал чистый httpmodule для установки моей структуры разрешений. Чего я действительно не мог понять, так это того, как лучше всего обрабатывать исходные изображения, видимые для xss и других вещей. НО я склонялся к принудительному перекодированию всех загрузок без изменения высоты/ширины и т. д. (думаю, я видел, как вы упомянули об этом в некоторых ваших документах) и использовал это как полноразмерное базовое изображение. В любом случае, вместе с проверками расширения, размера и формата при загрузке это, возможно, даст достойный уровень безопасности. Не уверен, что размещение файлов в виртуальной папке даст какие-либо преимущества. - person Base; 06.08.2012
comment
Однако я подумал о том, о чем вы кратко упомянули ранее в отношении дискового кеша. Кэш изображений, похоже, имеет правило web.config, запрещающее доступ к нему. Это должно означать, что пока я защищаю оригиналы, ImageResizer не будет обслуживать кешированные версии, верно? Или мне также придется реализовать авторизацию в событии ImageResizer? - person Base; 06.08.2012
comment
Пока вы защищаете оригиналы, ImageResizer будет защищать варианты. Никогда не используйте имя файла или расширение, указанное при загрузке. Используйте GUID и обнаруженное вами расширение формата. Это предотвратит попытки сервера и клиента интерпретировать загруженные данные, кроме статического изображения. Если вы действительно параноик, просто перекодируйте оригинал во время загрузки. - person Lilith River; 06.08.2012
comment
Обязательно примите во внимание «fakeExtensions» или отключите их. То есть image.jpg.ashx и image.jpg — это два способа доступа к одному и тому же файлу. И не используйте подключаемые модули FolderResizeSyntax или ImageHandlerSyntax, так как они выполняют перезапись после запуска вашего кода авторизации. Или, если вы хотите поддерживать перезапись после авторизации и поддельные расширения, создайте общедоступный метод, который проверяет путь/запрос/пользователя и вызывает его из Config.Current.Pipeline.AuthorizeImage (который запускается после завершения всех операций перезаписи). На этом этапе также проверяется UrlAuthorization. - person Lilith River; 06.08.2012
comment
Поскольку мой план — atm, структура разрешений будет основываться только на родительской папке (структурирована после имени пользователя/области/даты), а не для конкретных файлов. Таким образом, имена файлов не будут иметь значения для оценки. Суть в настройке разрешений для каждого пользователя, а не для отдельных файлов в настоящее время. Я устанавливаю либо статические имена для изображений, либо случайные, такие как guid или что-то в этом роде. Затем я, вероятно, сохраню очищенное исходное имя изображения в базе данных вместе с путем, но еще не добрался до этого. - person Base; 06.08.2012
comment
Что касается ввода, мой план был примерно таким: var settings = new ResizeSettings("process=always&format=jpg&quality=92"); var Processed = new ImageJob(InBytes, string.Concat(TargetPath, FileName), settings); Processed.AddFileExtension = true; Processed.CreateParentDirectory = true; Processed.Build(); FileName — это заданная мной строка, которая не содержит никакого расширения. Не конечный продукт, но, похоже, он отлично работает и должен перекодировать все входящие файлы в формате jpeg? Другие области, возможно, позволят сохранить и другие типы изображений. Но это другое дело. - person Base; 06.08.2012