Simplest way to prevent someone from loading my managed assembly?
Asked Answered
M

4

7

.Net security noob here... What is the simplest way to prevent someone else from loading my assembly?

Background: Although I am really looking for just 'good enough' protection (with enough time/money/smarts someone can successfully crack, hack and attack), this seems like it should already be a solved problem and I'm just missing it.

Here is what I (think) I know:

  1. While strong naming can be used a layer of security, it wasn't necessarily intended to be, according to this microsoft documentation (see Warning: Do not rely on strong names for security. They provide a unique identity only.)

    On that^ note I have encountered situations where I wasn't able to load a third party assembly (Aspose I think it was) because they did not sign their assemblies, however all of mine were. So I had to ildasm their assembly, sign it with our own snk, then ilasm back) in order to use their library. So, strong naming doesn't seem like a good security mechanism to me. HOWEVER...what about a simple check, in code, to verify that the calling assembly is signed with the my public key token? Is this effective enough?

  2. If strong naming shouldn't be used for what I'm trying to accomplish, is implementing an Authenticode digital signature check on the dll the better a route (seems wintrust.dll can help with this)?

    I've been going through a several vendors' tooling for obfuscation and many come with licensing and all kinds of stuff. I will likely use a little bit of obfuscation to hide some sensitive parts, however I would still like to have a mechanism for preventing someone from loading my sensitive library, without having to use features such as string and code encryption, which often come with performance (and other) costs.

So back to the question, What is the simplest way to prevent someone from loading my assembly?

Melanosis answered 8/1, 2017 at 23:44 Comment(4)
Was there a vote to close this? if so, why? Maybe point me to where this has been answered. Possible I missed something already out there. Or its also possible that this hasn't really been answered effectivelyMelanosis
What do you mean exactly by "prevent from loading"? In the general case, it's impossible, because your assembly is an opaque file like any other. What's possible is prevent your .NET code inside that assembly from running, or hide things inside it. PS: as you found out, strong naming is just about identification. When you resign an assembly, it does not come anymore from the same publisher. If that assembly contains code that checks its publisher, the code inside can use it to change its course of action, but the assemly can still be loaded.Hung
Are you looking to stop you .Net dll been COM readable?Muscovado
@Muscovado no, that's not an issueMelanosis
P
4

In fact you cannot provide 100% guaranty that your assembly won't be downloaded and used in a bad way. But some measures can help you:

  1. Signing your installation package (msi). You need for this a SSL certificate. Users will see the publisher of downloaded files while installation process. If your installation package is modified – signing will be broken and user while installation will see that app is from Unknown publisher or other publisher than you.
  2. Strong assembly naming allows you to prevent library substitution onto another “bad” library. Let’s consider the next scenario: You deployed your app with library A to some server or a user installed your app onto his/her computer. Without strong name a library A or any others can be substituted or modified by some code onto another version. This new version, for instance, can sends all user passwords somewhere or do another malicious actions. If one library was changed .Net while downloading it will throw strong name validation exception. So, your app will be broken. Malicious code should recompile all app libraries in order to make app working. It's harder.
  3. Obfuscation is also a very important thing which allows to do very hard or even impossible understanding what’s going on inside assembly (code renaming, string encryption and so on).
  4. If you have some very critical intellectual code it’s better to rewrite it into native (C/C++) code.
  5. If your app is a mobile or desktop app and it makes backend request you can move important code to server side.
Pamilapammi answered 17/1, 2017 at 18:23 Comment(4)
On your first point: I've always done so with my MSIs and their bootstrappers, etc. Are you suggesting that the digital signature signing on the assembly/file would be a route towards making it un-callable (un-loadable I guess is impossible)?Melanosis
Digital signing allows to identify file publisher only. So, if you download msi or exe from Microsoft site while installing you see Microsoft company as verified publisher. That's it.Pamilapammi
Let me put it this way: say I put in a mechanism to disallow the caller from doing certain things with my assembly unless the calling assembly has some secure unique identifier, is it better to have this unique identifier be a digital signature on the assembly doing the calling? Or the the strong name key? I'm thinking the later.Melanosis
Something like. About strong name: When assembly A is signed (has strong name) another assembly B before calling some code from A will do digital signing verification. For this B has public key and encrypted assembly hash (digital signature). Assembly B calculate hash of assembly A, decrypt encrypted hash by using public key and verify if these hashes are the same. It's no so reliable because you can change signature in both A and B (recompiling both). But it adds some security protectionPamilapammi
E
2

Obvious, but maybe not so helpful: the simplest way is to delete the assembly.

Electrodynamic answered 17/1, 2017 at 14:46 Comment(1)
Hah good answer. However part of security is that it still needs to be usable. Sure, the best way to secure something existing might be to put it in a lock box at the bottom of the ocean, turned off. However if its not usable, it doesn't meet security requirement of...being usable :)Melanosis
S
2

I think what you want is to prevent people to reverse engineer you assembly, right? Tools like JustDecompiler can get your assembly code easily. To obfuscate your code you can always resort to some paid product (Eazfuscator), or some open source (Obfuscar, or ConfuserEx).

Sender answered 17/1, 2017 at 17:26 Comment(1)
Already doing this. However note that de4dotnet has a pretty good track record of de-obfuscating just about any vendor's obfuscation tool. I've been testing it a lot.Melanosis
D
1

One option (which may or may not be feasible) is to not give the assembly to them. If you can make your application web-based (like Software as a Service), then (with properly secured servers) your clients would have no access to the assemblies.

Daytime answered 17/1, 2017 at 23:31 Comment(2)
Correct, and this is already the case for the most part, being behind properly secured servers. However - although unlikely, it is not impossible for the assembly to get in the hands of someone its not intended for. Example one: disgruntled employee.Melanosis
@Melanosis If that's part of your threat model then you're correct.Daytime

© 2022 - 2024 — McMap. All rights reserved.