Безопасность плагина блока.NET

Из about.com :

Интерпретируемый язык обрабатывается во время выполнения. Каждая строка читается, анализируется и выполняется. Необходимость повторной обработки строки каждый раз в цикле делает интерпретируемые языки такими медленными. Это означает, что интерпретируемый код выполняется в 5–10 раз медленнее, чем скомпилированный код. Интерпретируемые языки, такие как Basic или JavaScript, являются самыми медленными. Их преимущество не нуждается в перекомпиляции после изменений, и это удобно, когда вы учитесь программировать.

Однако в 5-10 раз медленнее не всегда верно для таких языков, как Java и C #. Они интерпретируются, но компиляторы «точно в срок» могут генерировать инструкции машинного языка для некоторых операций, что значительно ускоряет процесс (в разы, около скорости компилируемого языка).

11
задан John Gietzen 29 August 2009 в 15:41
поделиться

6 ответов

1) строгое имя сборки с определенным ключом.

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

2 ) при загрузке убедитесь, что сборка имеет строгое имя с ожидаемым ключом

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

Пример:

public static StrongName GetStrongName(Assembly assembly)
{
    if(assembly == null)
        throw new ArgumentNullException("assembly");
    AssemblyName assemblyName = assembly.GetName();

    // get the public key blob
    byte[] publicKey = assemblyName.GetPublicKey();
    if(publicKey == null || publicKey.Length == 0)
       throw new InvalidOperationException( String.Format("{0} is not strongly named", assembly));

    StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey);

    // create the StrongName
    return new StrongName(keyBlob, assemblyName.Name, assemblyName.Version);
}


// load the assembly:
Assembly asm = Assembly.LoadFile(path);
StrongName sn = GetStrongName(asm);

// at this point
// A: assembly is loaded
// B: assembly is signed
// C: we're reasonably certain the assembly has not been tampered with
// (the mechanism for this check, and it's weaknesses, are documented elsewhere)

// all that remains is to compare the assembly's public key with 
// a copy you've stored for this purpose, let's use the executing assembly's strong name
StrongName mySn = GetStrongName(Assembly.GetExecutingAssembly());

// if the sn does not match, put this loaded assembly in jail
if (mySn.PublicKey!=sn.PublicKey)
    return false;

примечание: код не был протестирован и скомпилирован, может содержать синтаксические ошибки.

13
ответ дан 3 December 2019 в 05:59
поделиться

Если вы используете 3.5, есть что сказать о новом материале System.AddIns - взгляните на http://www.codeplex.com/clraddins для примеров.

-Oisin

1
ответ дан 3 December 2019 в 05:59
поделиться
  1. Если вас беспокоит безопасность ваших сборок, вы должны Назвать их строго. Это обеспечивает высокий уровень безопасности, так как сборка действительно является той, которую вы намеревались сделать.

  2. Исключения, с которыми вы можете столкнуться во время загрузки, следующие. Добавьте try / catch вокруг вашей попытки загрузки в Assembly.Load () и реагируйте в соответствии с типом ошибки:

    • ArgumentNullException
    • FileLoadException
    • FileNotFoundException
    • BadImageFormatException
  3. Сборки, которые вы загружаете динамически, должны иметь такие же права в качестве учетной записи пользователя, которая их загрузила, если эта сборка не находится в GAC. Создайте учетную запись службы с желаемыми правами и запустите приложение, используя эту учетную запись для управления доступом.

2
ответ дан 3 December 2019 в 05:59
поделиться

Я не знаю, лучший ли это способ, но когда вы вызываете LoadFile для недопустимой сборки, вы получите исключение BadImageFOrmatException, потому что у сборки нет манифеста.

Как ваш код написан в настоящее время, вы довольно широко открыты для атак на управление процессом . Любой, кто может получить доступ к каталогу и раскрыть сборку, реализующую ваш интерфейс, может выполнить эту атаку. Им даже не нужно очень хорошо реализовывать интерфейс, они могут просто предоставить конструктор по умолчанию и нанести им весь ущерб. Это позволяет злоумышленнику выполнять код с правами вашего приложения, что всегда плохо.

Таким образом, ваша единственная текущая защита - это защита доступа к каталогу на уровне ОС. Это может сработать для вас, но это только один уровень защиты, и вы полагаетесь на состояние безопасности, которое не можете контролировать.

Вот две вещи, на которые вы можете обратить внимание:

  1. Строгое присвоение имени сборке и требование регистрации сборки в GAC, скорее всего, является самым безопасным способом сделать это. Если вы можете это сделать, вам нужно найти способ предоставить своему приложению полное имя сборки и загрузить его с помощью Assembly.Load ().

Однако я сомневаюсь, что вы хотите установить эти плагины в GAC, чтобы вы могли это сделать. таким образом:

  1. В вашем приложении предоставьте пользователям возможность зарегистрировать плагин, по сути, мини-GAC. Когда они это сделают, вы сохраните местоположение и имя сборки, а также открытый ключ. Для этого требуется, чтобы сборка имела строгое имя.

Таким образом, вы будете загружать только те сборки, которые предоставил кто-то с правами доступа к вашему приложению, скорее всего, тот, у кого есть права на добавление плагина. Перед загрузкой сборки вы можете проверить, соответствует ли открытый ключ тому, который был предоставлен при регистрации сборки, чтобы злоумышленник не мог просто заменить сборку. Этот код довольно прост:

    private bool DoPublicKeysCompare(Assembly assembly, byte[] expectedPublicKey)
    {
        byte[] assemblyKey = assembly.GetName().GetPublicKey();
        return expectedPublicKey.SequenceEqual(assemblyKey);
    }

Итак, теперь, чтобы выполнить атаку на вас, я должен каким-то образом получить привилегию изменить значение PublicToken и получить доступ к каталогу и изменить файл.

    private bool DoPublicKeysCompare(Assembly assembly, byte[] expectedPublicKey)
    {
        byte[] assemblyKey = assembly.GetName().GetPublicKey();
        return expectedPublicKey.SequenceEqual(assemblyKey);
    }

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

    private bool DoPublicKeysCompare(Assembly assembly, byte[] expectedPublicKey)
    {
        byte[] assemblyKey = assembly.GetName().GetPublicKey();
        return expectedPublicKey.SequenceEqual(assemblyKey);
    }

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

3
ответ дан 3 December 2019 в 05:59
поделиться

Взгляните на платформу AddIn от Microsoft, поскольку она предоставляет некоторые из необходимых вам возможностей, таких как безопасность и изоляция.

Я также рекомендую вам использовать только методы отражения такие как ReflectionOnlyLoad и ReflectionOnlyLoadFrom, чтобы гарантировать, что ничто из сборки, из которой вы запрашиваете метаданные, не выполняется, когда вы ее просматриваете. Как только вы определите, что в сборке есть то, что вы ищете, вы можете загрузить ее.

1
ответ дан 3 December 2019 в 05:59
поделиться

Я предпочитаю использовать Assembly.ReflectionOnlyLoadFrom (...)

дополнительные сведения см. В следующей статье MSDN:

Как: загрузить сборки в контекст только для отражения

0
ответ дан 3 December 2019 в 05:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: