Attempt by security transparent method X to access

2020-05-18 17:16发布

问题:

I have a fairly stable server application version that's been deployed for nearly a year at dozens of customers.

One new customer recently setup the application and is getting the following error:

System.MethodAccessException: Attempt by security transparent method [SomeMethod] to access security critical method [SomeOtherMethod] failed.

Both SomeMethod and SomeOtherMethod are methods in assemblies that I wrote, that are built against .NET 4, and that are running inside a Windows Service. If it makes a difference, SomeOtherMethod does reference a type from a 3rd party assembly (EntLib 4.1) built against .NET 2.0. Looking at the code for EntLib 4.1, I do see that they use both SecurityTransparent and APTC attributes, but this has never caused issues at other clients.

These assemblies were upgraded from the .NET 2.0 CLR, but a long time ago. This exact code is running on other customers just fine, and I'm not explicitly using the APTC attribute nor am I using the SecurityCritical attribute anywhere.

This leads me to the conclusion that it's a configuration issue or perhaps .NET Framework patch issue. Has there been a patch released for .NET that would cause this breaking change? Is there a configuration setting some where that enforces this type of check which is off by default but that my customer may have enabled?

One last point. My service utilizes SSRS RDLCs to generate PDFs. Due to some changes in .NET 4, I must force the service to use the legacy security policy via the following config:

  <runtime>
    <NetFx40_LegacySecurityPolicy enabled="true" />
  </runtime>

For more details on why I need to do this, see this stackoverflow post: Very High Memory Usage in .NET 4.0

The important point is that I do this at all my other customers as well. Only this one customer is having issues.

回答1:

Sigh, the patterns and practices employed by the Microsoft Patterns And Practices team that's responsible for the Enterprise libraries are pretty deplorable. Well, the exception is accurate, you cannot call a method that's decorated as "I'll definitely check security" from code that's decorated with "Meh, I won't check security so don't bother burning the cpu cycles to check it". Which scales about as well as exception specifications as used in Java. CAS is incredibly useful, but diagnosing the exceptions is a major headache and often involves code that you don't own and can't fix. Big reason it got deprecated in .NET 4.

Editorial done. Taking a pot-shot at the problem, you need to find out why CAS is being enforced here. The simplest explanation for that is that the service doesn't run in full trust. The simplest explanation for that is that the client didn't install the service on the local hard drive. Or is generally running code in don't-trust-it mode even on local assemblies, a very paranoid admin could well prefer that. That needs to be configured with Caspol.exe, a tool whose command line options are as mysterious as CAS. Pot-shooting at the non-trusted location explanation, your client needs to run Caspol as shown in this blog post. Or just simply deploy the service locally so the default "I trust thee" applies.

Editing in the real reason as discovered by the OP: beware of the alternate data stream that gets added to a file when it is downloaded from an untrusted Internet or network location. The file will get a stream named "Zone.Identifier" that keeps track of where it came from with the "ZoneId" value. It is that value that overrides the trust derived from the storage location. Usually putting it in the Internet zone. Use Explorer, right-click the file and click "Unblock" to remove that stream. After you're sure you can trust the file :)



回答2:

In case it helps others i post my solution for this issue:

1) On the AssemblyInfo.cs, removed/commented the [assembly: SecurityTransparent] line.

2) The Class and the Method that does the actual Job was marked as [SecuritySafeCritical], in my case establishing a Network Connection:

[SecuritySafeCritical]
public class NetworkConnection : IDisposable
{
    [SecuritySafeCritical]
    public NetworkConnection(string networkName, NetworkCredential credentials)
    {
        .............
    }
}

3) The Caller Class and Method was market as [SecurityCritical]:

[SecurityCritical]
public class DBF_DAO : AbstractDAO
{
    [SecurityCritical]
    public bool DBF_EsAccesoExclusivo(string pTabla, ref ArrayList exepciones)
    {
        ....
        using (new NetworkConnection(DBF_PATH, readCredentials))
        {
            ....
        }
    }
}


回答3:

I was facing the similar issue while running the downloaded WCF sample from http://www.idesign.net/ while using their ServiceModelEx library. I commented out the below line in AssemblyInfo.cs in ServiceModelEx project

//[assembly: AllowPartiallyTrustedCallers]

and it worked for me.



回答4:

In my case it was an issue when I managed a NuGet packages in the solution some package overrides System.Web.Mvc assembly version binding in main web site project. Set back to 4.0.0.0 (I had 5.0 installed). I didn't change notice the change because Mvc v4.0 was installed and accessible via GAC. Set back