none
Doesn't CLR check the hash of a netmodule file of a strongly named multi-module assembly ? RRS feed

  • Question

  • Hello,

    Here is a strongly named assembly (say ASM.dll) which was built along with a module via "/addmodule:MOD.netmodule". A client application was also created to bind the assembly.

    Then, the module MOD.netmodule was "tempered"  by modifing and rebuilding its source code. And I attempted to install the assembly ASM.dll into GAC, without question, the system rejected the assmebly and reported the below error message since one of its files has been tempered.
    "Failure adding assembly to the cache: One or more modules were streamed in which
     did not match those specified by the manifest. The hash of one or more modules
    found does not match the hash recorded in the manifest."

    However, the client application still able to run successfully without any exception(one of methods in the netmodule was indeed called). Doesn't CLR check the hash of a netmodule file of a strongly named multi-module assembly when loading it?

    Thanks,
    NetDNA

    Friday, April 30, 2010 9:53 AM

Answers

  • Isn't the old version still in the GAC? (gacutil -l) ... maybe you are using the old version without knowing it.

    AFAIK strong-name is verified only in untrusted scenarios. GAC is trusted and therefore I would expect the strong-name check to happen when you install it into GAC (which failed as you mentioned).

    -Karel

    • Marked as answer by SamAgain Tuesday, May 11, 2010 9:54 AM
    Friday, April 30, 2010 4:03 PM
    Moderator
  • AFAIK that is by design behavior. If someone tempered with your application on disk, it means that the person has the right to do that (admin rights) and therefore can do anything it wants. It is not a security risk.

    Also ask your question the other way around: Are you willing to pay the price of checking the signature every time an assembly loads into memory? That is a huge startup and working set hit. Is it worth it when it doesn't bring any advantage/better security?

    -Karel

    BTW: I am not expert on security in .NET at all. These are my personal opinions based on what I know. I might be wrong ...

    • Marked as answer by SamAgain Tuesday, May 11, 2010 9:54 AM
    Friday, April 30, 2010 5:56 PM
    Moderator
  • I believe always checking strong names was the normal behavior for .NET pre-2.0. Sometime in the 2.0/3.0 time frame, they changed the security with the concept full trust means full trust. This means that an application running full trust (e.g., local app) no longer needs publisher evidence, so it's not calculated on load. GAC assemblies may be used in partial trust scenarios and may need publisher evidence, which is calculated at the time of adding the assembly to the GAC for efficiency reasons.

    The phrase "its hash value is checked" may have nothing to do with strong name signing. There are several other hashes in the PE file structure.

    Finally, remember this key point: strong name signing has almost nothing to do with security. It only proves publisher identity. While the technology (cryptographically signing a hash using a private key) could be used for security-related purposes, Microsoft has historically taken the stance that it is only used to provide publisher evidence. Likewise, the use of a strong name hash in an assembly identity is only used to state that an assembly came from a particular publisher.

    Depending on strong-name signing to prevent tampering is not a supported scenario. That's more the realm of Authenticode, which has a full PKI infrastructure.

           -Steve


    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ
      and How to Implement IDisposable and Finalizers: 3 Easy Rules
    Microsoft Certified Professional Developer

    How to get to Heaven according to the Bible
    • Marked as answer by SamAgain Tuesday, May 11, 2010 9:54 AM
    Saturday, May 1, 2010 2:46 AM

All replies

  • Isn't the old version still in the GAC? (gacutil -l) ... maybe you are using the old version without knowing it.

    AFAIK strong-name is verified only in untrusted scenarios. GAC is trusted and therefore I would expect the strong-name check to happen when you install it into GAC (which failed as you mentioned).

    -Karel

    • Marked as answer by SamAgain Tuesday, May 11, 2010 9:54 AM
    Friday, April 30, 2010 4:03 PM
    Moderator
  • Hi Karel,

    I verified that the strongly named assembly had never get deployed into the GAC, and this is a desired behavior.

    However, what I concern is that CLR doesn't reject the tempered module when loading it from a non GAC location. (Process Explorer indicates that the tempered module was loaded from the location instead of GAC)

    Thanks,
    NetDNA

    Friday, April 30, 2010 5:11 PM
  • AFAIK that is by design behavior. If someone tempered with your application on disk, it means that the person has the right to do that (admin rights) and therefore can do anything it wants. It is not a security risk.

    Also ask your question the other way around: Are you willing to pay the price of checking the signature every time an assembly loads into memory? That is a huge startup and working set hit. Is it worth it when it doesn't bring any advantage/better security?

    -Karel

    BTW: I am not expert on security in .NET at all. These are my personal opinions based on what I know. I might be wrong ...

    • Marked as answer by SamAgain Tuesday, May 11, 2010 9:54 AM
    Friday, April 30, 2010 5:56 PM
    Moderator
  • Thanks for your reply, if an application is deployed on a folder of a non-system driver, a typical user without admin permission is still able to modify the application's files.

    Substaintially, I'm not going to develop such an application containing multi-module assemblys. The reason why I raised this question is that I read some statements(quoted below) on Jeffrey's book, after doing my experiment mentioned above, I was confused.

     Jeffrey says:"When resolving a referenced type, the CLR can find the type in one of three places:

    Same file Access to a type that is in the same file is determined at compile time
    (sometimes referred to as early bound). The type is loaded out of the file directly, and
    execution continues.

    Different file, same assembly The runtime ensures that the file being referenced is,
    in fact, in the assembly’s FileRef table of the current assembly’s manifest. The runtime
    then looks in the directory where the assembly’s manifest file was loaded. The file is
    loaded, its hash value is checked to ensure the file’s integrity, the type’s member is
    found, and execution continues.

    ..."

     

    Thanks,
    NetDNA

    Saturday, May 1, 2010 1:30 AM
  • I believe always checking strong names was the normal behavior for .NET pre-2.0. Sometime in the 2.0/3.0 time frame, they changed the security with the concept full trust means full trust. This means that an application running full trust (e.g., local app) no longer needs publisher evidence, so it's not calculated on load. GAC assemblies may be used in partial trust scenarios and may need publisher evidence, which is calculated at the time of adding the assembly to the GAC for efficiency reasons.

    The phrase "its hash value is checked" may have nothing to do with strong name signing. There are several other hashes in the PE file structure.

    Finally, remember this key point: strong name signing has almost nothing to do with security. It only proves publisher identity. While the technology (cryptographically signing a hash using a private key) could be used for security-related purposes, Microsoft has historically taken the stance that it is only used to provide publisher evidence. Likewise, the use of a strong name hash in an assembly identity is only used to state that an assembly came from a particular publisher.

    Depending on strong-name signing to prevent tampering is not a supported scenario. That's more the realm of Authenticode, which has a full PKI infrastructure.

           -Steve


    Programming blog: http://nitoprograms.blogspot.com/
      Including my TCP/IP .NET Sockets FAQ
      and How to Implement IDisposable and Finalizers: 3 Easy Rules
    Microsoft Certified Professional Developer

    How to get to Heaven according to the Bible
    • Marked as answer by SamAgain Tuesday, May 11, 2010 9:54 AM
    Saturday, May 1, 2010 2:46 AM
  • Hi Steve,

    Thanks for your explaination.

    "This means that an application running full trust (e.g., local app) no longer needs publisher evidence, so it's not calculated on load".  However, with regard to a single file assembly deployed on the local, if the assembly file was tempered, CLR would evaluate its integrity when loading it (although there is a performance overhead) and reject it with System.IO.FileNotFoundException.

    Yes I agreed, Strong Name isn't intended for security. However, SN can be used for versioning and temper-resistance to a certain extent. What I confused is the inconsistency between the multi-file assembly and single-file assembly validation mechanism.

    Thanks,
    NetDNA

    Saturday, May 1, 2010 6:58 AM