Securing Embedded Resources in .NET

In this guide, we will demonstrate how to protect embedded resources in .NET applications from unauthorized access.

Contents

What Are Embedded Resources and Why Should You Protect Them?

Embedded resources are commonly used in .NET to store data accessible by the currently running .NET assembly or other assemblies. These resources can include strings, images, and more. Sometimes, the types of resources are specific; for example, WPF applications use XAML resources to store UI markup. However, embedded resources are stored as-is within an assembly and can be read using the .NET API method Assembly.GetManifestResourceStream, or extracted by .NET assembly viewing tools like ILSpy.

Like code, resources are intellectual property that you might want to protect from unauthorized access; moreover, they can contain sensitive information such as passwords, URLs, and more. One potential solution is to store such data statically in the code, rather than in embedded resources. Unfortunately, in many cases, .NET expects to find data in specific embedded resources – for instance, XAML in WPF applications is converted into a binary form (BAML) and stored as an embedded resource under the same name.

What should you do in such a case? You can use .NET obfuscators. A .NET obfuscator not only obfuscates MSIL code but can also remove and modify embedded resources within an assembly. Also, this ensures that when a particular embedded resource is requested, its content is securely provided. Let’s explore how to use a .NET obfuscator to protect embedded resources.

Create a sample: WPF application with embedded resources

For this guide, we will create a WPF application. Of course, you could use any type of .NET application. To begin, open Visual Studio, click on “New” and then “Project”. Select “WPF Application” and name it “SecureEmbeddedResources”.

Build the application, then run ILSpy and load “SecureEmbeddedResources.dll”. You will see “mainwindow.baml”:

Embedded resources are visible to everyone

How to Protect Embedded Resources Using a .NET Obfuscator?

First, you need to add two NuGet packages to the project: ArmDot.Client and ArmDot.Engine.MSBuildTasks.

ArmDot.Client includes obfuscation attributes, while ArmDot.Engine.MSBuildTasks provides a task for obfuscation that MSBuild executes after building your assembly.

AAmong other obfuscation attributes, ArmDot.Client includes the ProtectEmbeddedResourcesAttribute, which instructs the .NET obfuscator to secure embedded resources. This attribute is applied to the entire assembly. Open AssemblyInfo.cs and add the following code::

[assembly: ArmDot.Client.ProtectEmbeddedResources]

Also you need to add the obfuscation task to the project. Open the project file for editing and add the following:

  <Target Name="Protect" AfterTargets="AfterCompile" BeforeTargets="BeforePublish">
    <ItemGroup>
      <Assemblies Include="$(ProjectDir)$(IntermediateOutputPath)$(TargetFileName)" />
    </ItemGroup>
  <ArmDot.Engine.MSBuildTasks.ObfuscateTask
    Inputs="@(Assemblies)"
    ReferencePaths="@(_ResolveAssemblyReferenceResolvedFiles->'%(RootDir)%(Directory)')"
    SkipAlreadyObfuscatedAssemblies="true" />
  </Target>
</Project>

Rebuild the project and ensure it is functioning properly. Then return to ILSpy and reload “SecureEmbeddedResources.dll”. As you will see, the embedded resources have disappeared:

Secured embedded resources

Final Thoughts

Embedded resources are openly stored in .NET assemblies, which is why it’s crucial to conceal them. Fortunately, .NET obfuscators enable the protection of these resources. To secure embedded resources, you need to specify the corresponding attribute and add the obfuscation task to the build process.