Что значит рекомендация CA2122 Security::Permissions LinkDemand при анализе C++clr кода?

194
31 октября 2019, 08:00

Я провел анализ своего кода и получил рекомендацию от анализатора (см. ниже). Не понимаю, что он хотел этим сказать? (VS-2017)

Код:

try
{
    SD::Imaging::BitmapData ^bmd0 = nullptr;
    SD::Imaging::BitmapData ^bmd1 = nullptr;
    dataComparable *dc = nullptr;
    try
    {
        bmd0 = bmp0->LockBits(
            SD::Rectangle(Point(0, 0), bmp0->Size),
            SD::Imaging::ImageLockMode::ReadOnly,
            SD::Imaging::PixelFormat::Format32bppArgb
        );
        bmd1 = bmp0->LockBits(
            SD::Rectangle(Point(0, 0), bmp1->Size),
            SD::Imaging::ImageLockMode::ReadOnly,
            SD::Imaging::PixelFormat::Format32bppArgb
        );
        dc = new dataComparable();
        dc->d1.d = xUtils::IntPtrToPointer<PBYTE>::get(bmd0->Scan0);
        dc->d2.d = xUtils::IntPtrToPointer<PBYTE>::get(bmd1->Scan0);
        dc->d1.sz = static_cast<size_t>(bmd0->Stride * bmp0->Height);
        dc->d2.sz = static_cast<size_t>(bmd1->Stride * bmp1->Height);
        return funcComparable(dc);
    }
    finally
    {
        if (dc)
            delete dc;
        if (bmd0 != nullptr)
            bmp0->UnlockBits(bmd0);
        if (bmd1 != nullptr)
            bmp1->UnlockBits(bmd1);
    }
}
catch (Exception ^)
{
    return 0.0f;
}

Рекомендации анализатора:

csemudev.h(276): warning CA2122: Microsoft.Security : 'EmuDev::CompareBitmap(Bitmap^, Bitmap^)' выполняет вызов в 'Bitmap::UnlockBits(BitmapData^)', для которого задана проверка LinkDemand. Выполняя этот вызов, 'Bitmap::UnlockBits(BitmapData^)' косвенно предоставляется пользовательскому коду.

Рассмотрите следующий стек вызовов, который может раскрыть способ обхода защиты безопасности:
csemudev.h(276): warning CA2122:
->'EmuDev::CompareBitmap(Bitmap^, Bitmap^)'

csemudev.h(276): warning CA2122:
->'EmuDev::CompareBitmap(Bitmap^, Bitmap^)'

Answer 1

В двух словах, сам MSDN описывает это коротко и не очень понятно. Смысл сводиться к тому, что в стандартных библиотеках некоторые вызовы уже защищены атрибутами System::Security::Permissions::* и, при обращении к ним, требуют аналогичного установленного атрибута доверия со стороны кода вызывающего эти функции/методы.

LinkDemand- требование ссылки - это информация о безопасности доступа к коду (CAS), которая гарантирует, что код имеет достаточные права для выполнения. Предупреждение как таковое может не относится к логике вашего кода, если вы уверены что этот код не будет выполнен снаружи. Защитив "ненадежный код" атрибутами безопасности, можно быть уверенным что код не сможет выполнить "джит" и не сможет быть выполнен извне.

Зачем так сделано

Помеченный атрибутами безопасности код будет использовать повышение привилегии стека вызовов. По умолчанию .NET предполагает, что ваш код полностью доверенный, пока не будет установлен соответствующий атрибут. Этот механизм обеспечивает выполнение кода с более низкими учетными записями и приоритетами (зависит от настроек атрибутов).

Проверка Требование ссылки выполняется во время компиляции и проверяет разрешения вызывающего. Возможная утечка безопасности может произойти из-за того, что ваша ссылка на метод/функцию/класс может быть вызвана другим кодом позднее. Этот код не получит такую ​​же проверку разрешения, потому что в ссылке отсутствует атрибут безопасности. Чтобы избежать этой проблемы, рекомендуют использовать опцию атрибутов безопасностиFullTrust.

Путей решения я нашел три:

  1. Запретить вывод предупреждения использовав атрибут SupressMessage, так себе решение..

[SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands")]

  1. Использовать глобальные атрибуты на всю сборку снимающие проверки System::Security::Permissions в той или иной степени: MSDN blog MSDN SecurityTransparent
[assembly: SecurityRules(SecurityRuleSet.Level2)]
если сборка помечена как:  
[assembly: SecurityTransparent]
[assembly: SecurityCritical]
[SecurityCritical(SecurityCriticalScope.Everything)] Class/Method
  1. Использовать необходимые атрибуты на вашем методе, который вызывает метод/функцию помеченную атрибутами System::Security::Permissions, общий работающий атрибут касающийся Unmanaged кода у меня выглядит так:

    [System::Security::Permissions::SecurityPermission(
        System::Security::Permissions::SecurityAction::LinkDemand,
        Flags = System::Security::Permissions::SecurityPermissionFlag::UnmanagedCode,
        Unrestricted = false
    )]

так-же, из общих соображений я перенес тело функции в internal:, возможно это и не обязательно, но без этого подавить ошибку не удавалось.

READ ALSO
Правильная сериализация

Правильная сериализация

Познаю науку JSON в C#Действую по статьям и мануалам

158
Активная вкладка браузера Selenium

Активная вкладка браузера Selenium

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

151
Жидкость в Unity [закрыт]

Жидкость в Unity [закрыт]

Как можно сделать подобие воды или лавы в Unity?

123
Счетчик запущенных Task

Счетчик запущенных Task

В своем приложении использую много фоновых задач

118