Безпека Веб-Додатків При Завантаженні Зовнішніх Ресурсів
За замовчуванням Aspose.Words для C++ може завантажувати віддалені ресурси, такі як зображення, стилі CSS або зовнішні документи HTML під час імпорту документів або вставки зображень за допомогою DocumentBuilder. Така поведінка дозволяє детально обробляти документи, але може бути причиною деяких загроз безпеці, якщо бібліотека є частиною веб-програми.
У цій статті ми розглянемо поширені проблеми безпеки, які можуть виникнути при завантаженні зовнішніх ресурсів, і дамо рекомендації про те, як уникнути подібних проблем.
Питання безпеки
При завантаженні зовнішніх ресурсів виникає ряд типових проблем з безпекою.
Розкриття облікових даних за допомогою Пов’язаних зображень
На хостах, заснованих на Windows, документи, що містять посилання на ресурси, які використовують шляхи UNC, такі як * ' \ \example.com \a\b*' буде оброблено за замовчуванням. У доменному середовищі це призведе до того, що хост надішле свої доменні облікові дані у хешованому форматі на вказаний сервер.
Якщо зловмиснику вдасться переконати користувача або сервер обробити документ за допомогою такого посилання на ресурс, що вказує на контрольований ним хост, зловмисник отримає облікові дані облікового запису користувача або служби в хеш-форматі NTLM. Потім такі дані можуть бути повторно використані в класичній атаці передачі хешу, що дозволяє зловмиснику отримати доступ до будь-якого ресурсу як користувач жертви або обліковий запис служби.
Якщо відповідний обліковий запис використовує слабкий пароль або пароль, який можна вгадати, зловмисник може додатково здійснити атаку злому пароля, щоб відновити пароль облікового запису для подальшого шкідливого використання.
Локальне розкриття зображень за допомогою Пов’язаних зображень
Як і в попередньому випадку, обробка документа з посиланням на локальний файл зображення призведе до включення цього файлу в остаточний документ. Це може призвести до розкриття конфіденційної інформації.
Відмова в обслуговуванні
Зловмисник може завантажити документ, який або містить посилання на зображення дуже великого розміру, або містить їх у собі – так звані “декомпресійні бомби”. При обробці цих зображень бібліотека буде споживати величезні обсяги пам’яті і CPU часу.
Підробка запитів на стороні Сервера за допомогою пов’язаного вмісту
Зловмисник може створити серію документів, що містять вбудовані посилання на поширені комбінації внутрішньої адреси IP і порту, а потім відправити їх у веб-службу, що використовує бібліотеку Aspose.Words для обробки документів.
Виходячи з тривалості часу, який служба використовує для обробки документа, зловмисник може визначити, чи брандмауер фільтрує задану комбінацію IP/порт:
- більш тривалий час обробки вказує на те, що пакет TCP SYN, надісланий сервером, був видалений брандмауером
- швидкий час обробки вказує на успішне встановлення з’єднання
Вирішення питань безпеки
Щоб вирішити вищезазначені проблеми та підвищити безпеку веб-додатків, ви можете контролювати або вимикати завантаження зовнішніх ресурсів за допомогою IResourceLoadingCallback.
Наступний приклад коду показує, як вимкнути завантаження зовнішніх зображень:
C++
class DisableExternalImagesHandler : public IResourceLoadingCallback
{
public:
ResourceLoadingAction ResourceLoading(System::SharedPtr<ResourceLoadingArgs> args) override
{
// Skip external images loading.
return args->get_ResourceType() == ResourceType::Image
? ResourceLoadingAction::Skip
: ResourceLoadingAction::Default;
}
};
void LoadDocument(const System::String& documentFilename)
{
auto disableExternalImagesHandler = System::MakeObject<LoadOptions>();
disableExternalImagesHandler->set_ResourceLoadingCallback(System::MakeObject<DisableExternalImagesHandler>());
auto doc = System::MakeObject<Document>(documentFilename, disableExternalImagesHandler);
}
Наступний приклад коду показує, як вимкнути віддалені ресурси:
C++
class DisableRemoteResourcesHandler : public IResourceLoadingCallback
{
static bool IsLocalResource(const System::String& originalUri)
{
// CodePorting.CsToCpp.Native.API can handle only absolute uri
auto uri = System::MakeObject<System::Uri>(originalUri);
if (uri->get_IsAbsoluteUri())
{
return uri->get_Scheme().Equals(u"file", System::StringComparison::OrdinalIgnoreCase);
}
return false;
}
public:
ResourceLoadingAction ResourceLoading(System::SharedPtr<ResourceLoadingArgs> args) override
{
return IsLocalResource(args->get_OriginalUri())
? ResourceLoadingAction::Default
: ResourceLoadingAction::Skip;
}
};
void LoadDocument(const System::String& documentFilename)
{
auto disableRemoteResourcesHandler = System::MakeObject<LoadOptions>();
disableRemoteResourcesHandler->set_ResourceLoadingCallback(System::MakeObject<DisableRemoteResourcesHandler>());
auto doc = System::MakeObject<Document>(documentFilename, disableRemoteResourcesHandler);
}