{"id":937,"date":"2010-07-13T00:00:00","date_gmt":"2010-07-13T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/whats-new-in-code-access-security-in-net-framework-4-0-part-2\/"},"modified":"2021-05-17T18:36:32","modified_gmt":"2021-05-17T18:36:32","slug":"whats-new-in-code-access-security-in-net-framework-4-0-part-2","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/whats-new-in-code-access-security-in-net-framework-4-0-part-2\/","title":{"rendered":"What&#8217;s New in Code Access Security in .NET Framework 4.0 &#8211; Part 2"},"content":{"rendered":"<div id=\"pretty\">\n<p class=\"pullout\"><strong>Table of Contents<\/strong><br \/>&#8211;<a href=\"#Introduction\">Introduction<\/a><br \/>&#8211;<a href=\"#APTCA\">The <em>Allow Partially Trusted Callers Attribute <\/em>(APTCA)<\/a><br \/>&#8211;<a href=\"#Custom_Resources\">Custom Resources<\/a><br \/>&#8211;<a href=\"#SecAnnotate\">The .NET Security Annotator Tool<\/a><br \/>&#8211;<a href=\"#Conclusion\">Conclusion<\/a><\/p>\n<h1><a id=\"Introduction\"><\/a>Introduction <\/h1>\n<p>This article is the second of a <a href=\"http:\/\/www.simple-talk.com\/dotnet\/.net-framework\/whats-new-in-code-access-security-in-.net-framework-4.0---part-i\/\">series of two<\/a> which introduce how Code Access Security has changed in .NET Framework 4.0. &#160;In the first article, we were introduced to the new .NET Framework 4.0 Level2 SecurityTransparence model and given some examples of its implementation. We&#8217;ve had a glimpse of the kind of changes which must be applied at assembly level in order to keep our code secure, and we have also seen that, with the new model, the host plays a principal role in defining what kind of resources can and cannot be accessed.<\/p>\n<p>from what we saw previously, it seems that the new Level2 SecurityTransparence model is an all or nothing technology; If the assembly is fully trusted, all resources are available, and if it is only partially trusted, none of them are.<\/p>\n<p>Thankfully, this is not the case, as we will see In this article. When protecting resources, in order to permit a more granular approach to security, an assembly can be marked with the <em>Allow Partially Trusted Callers Assembly<\/em> (<strong>APTCA<\/strong>) attribute. In this way, Security attributes become available at class or method level, bringing to more flexible configurations. &#160;<\/p>\n<p>Another important thing we will see is that, with the Level2 SecurityTransparence model, it is now possible to easily protect resources beyond the classical CAS resources defined in the .NET Framework, and we&#8217;ll call these new kinds of resources &#8220;custom resources&#8221;. Finally, we&#8217;ll finish this investigation into the new CAS implementation by describing how a new tool, called Security Annotator tool, can help us to discover the correct way to mix the <em>SecurityCritical<\/em> and the <em>SecuritySafeCritical<\/em> attributes to implement our desired security strategy. Without further ado, let&#8217;s get started.<\/p>\n<h1><a id=\"APTCA\"><\/a>The <em>Allow Partially Trusted Callers<\/em> <em>Attribute<\/em> (APTCA)<\/h1>\n<p>The <em>Allow Partially Trusted Callers Attribute<\/em> (<strong>APCTA<\/strong>) is an assembly-scoped attribute which changes how the assembly responds to the Level2 Security Transparence model.&#160; When used, the following modifications take place:<\/p>\n<ol>\n<li>All the classes and methods inside the assembly became <em>SecurityTransparent<\/em> unless otherwise specified.  <\/li>\n<li>To specify different behavior, the <em>SecurityCritical<\/em> or <em>SecuritySafeCritical<\/em> attributes can be added to desired class and\/or method implementations. <\/li>\n<\/ol>\n<p>The APCTA attribute is very similar to the <em>SecurityTransparent<\/em> attribute used <a href=\"http:\/\/www.simple-talk.com\/dotnet\/.net-framework\/whats-new-in-code-access-security-in-.net-framework-4.0---part-i\/\">in the previous article<\/a>, which we used to force an assembly to run as <em>SecurityTransparent<\/em>. As a result, when the caller assembly tried to access <em>SecurityCritical<\/em> code, an exception was thrown (remember the PermissionSet property?) As mentioned, the main differences among the two attributes lies in the fact that, when the APCTA attribute replaces the <em>SecurityTransparent<\/em> attribute, we are able to directly specify security settings for each class or method in an assembly through the use of <em>SecurityCritical<\/em> and\/or <em>SecuritySafeCritical<\/em> attributes. If the assembly were marked as <em>SecurityTransparent<\/em>, these two attributes would have no effect, due to the fact that the <em>SecurityTransparent<\/em> attribute only works at the assembly level, and no lower.<\/p>\n<p>So, with the APCTA attribute we are able to:<\/p>\n<ol>\n<li>Elevate the permissions of an individual class or method, transforming it into a <em>SecuritySafeCritical<\/em> class or method. By doing so, we grant the class or method all permissions to access protected resources (as <em>SecurityCritical<\/em> code) while it remains visible to <em>SecurityTransparent<\/em> code. Essentially, we create a sort of bridge between <em>SecurityTransparent<\/em> and <em>SecurityCritical<\/em> code.  <\/li>\n<li>Keep some classes or methods protected from the partially trusted assembly by marking them as <em>SecurityCritical<\/em>. <\/li>\n<\/ol>\n<p>As we will soon see, these two features remove the supposed &#8220;all or nothing&#8221; behavior of the <em>SecurityTransparent<\/em> attribute. To prove this, we&#8217;ll start by reusing the example provided in <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-CasWriterDemo.zip\">the previous article<\/a>, with some modifications:<\/p>\n<pre class=\"lang:c# theme:vs2012\">[assembly:AllowPartiallyTrustedCallers()]\n&#160;&#160;&#160;&#160;&#160;&#160;namespace CassAssemblyInfo\n&#160;&#160;{\n&#160;&#160;&#160;&#160;\/\/\/ &lt;summary&gt;\n&#160;&#160;&#160;&#160;\/\/\/ Demo class\n&#160;&#160;&#160;&#160;\/\/\/ &lt;\/summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public class AssemblyInfo\n&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ Write to the console the security settings of the assembly\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;\/summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public&#160;&#160;string GetCasSecurityAttributes()\n&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\/\/gets the reference to the current assembly\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Assembly a = Assembly.GetExecutingAssembly();\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StringBuilder sb = new StringBuilder();\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\/\/show the transparence level\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.AppendFormat(\"Security Rule Set: {0} \\n\\n\", a.SecurityRuleSet);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\/\/show if it is full trusted\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.AppendFormat(\"Is Fully Trusted: {0} \\n\\n\", a.IsFullyTrusted);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\/\/get the type for the main class of the assembly\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Type t = a.GetType(\"CasAssemblyInfo.AssemblyInfo\");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\/\/show if the class is Critical, Transparent or SafeCritical\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.AppendFormat(\"Class IsSecurityCritical: {0} \\n\", t.IsSecurityCritical);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.AppendFormat(\"Class IsSecuritySafeCritical: {0} \\n\",\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;t.IsSecuritySafeCritical);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.AppendFormat(\"Class IsSecurityTransparent: {0} \\n\",\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;t.IsSecurityTransparent);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\/\/get the MethodInfo object of the current method&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;MethodInfo m = t.GetMethod(\"GetCasSecurityAttributes\");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\/\/show if the current method is Critical, Transparent or SafeCritical\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.AppendFormat(\"Method IsSecurityCritical: {0} \\n\", .IsSecurityCritical);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.AppendFormat(\"Method IsSecuritySafeCritical: {0} \\n\",\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;m.IsSecuritySafeCritical);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.AppendFormat(\"Method IsSecurityTransparent: {0} \\n\",\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;m.IsSecurityTransparent);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;try\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.AppendFormat(\"\\nPermissions Count: {0} \\n\", a.PermissionSet.Count);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;catch (Exception ex)\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.AppendFormat(\"\\nError while trying to get the Permission Count:\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{0}&#160;\\n\", ex.Message);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return sb.ToString();\n&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;}\n&#160;&#160;}&#160;&#160;<\/pre>\n<p>With respect to the previous version of this dll library, we have inserted the following code prior to the namespace declaration:<\/p>\n<pre class=\"lang:c# theme:vs2012\">[assembly:AllowPartiallyTrustedCallers()]<\/pre>\n<p>&#8230; which states that our assembly is now <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-APTCACasAssemblyDemo.zip\">an APCTA assembly<\/a>. We have also added the following lines of code:<\/p>\n<pre class=\"lang:c# theme:vs2012\">\/\/get the MethodInfo object of the current method&#160;\nMethodInfo m = t.GetMethod(\"GetCasSecurityAttributes\");\n\/\/show if the current method is Critical, Transparent or SafeCritical\nsb.AppendFormat(\"Method IsSecurityCritical: {0} \\n\", m.IsSecurityCritical);\nsb.AppendFormat(\"Method IsSecuritySafeCritical: {0} \\n\",&#160;m.IsSecuritySafeCritical);\nsb.AppendFormat(\"Method IsSecurityTransparent: {0} \\n\", m.IsSecurityTransparent);<\/pre>\n<p>&#8230; which allow us to see if the <strong>GetCasSecurityAttributes<\/strong> method is <em>SecurityCritical<\/em>, <em>SecuritySafeCritical<\/em> or <em>SecurityTransparent<\/em>. By running the console application which we used to consume the previous assembly (and which you can <a href=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-APTCACasAssemblyDemo.zip\">download at the top of this article<\/a>), we obtain the following output:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure1.gif\" width=\"630\" height=\"318\" alt=\"1085-figure1.gif\" \/><\/p>\n<p class=\"caption\">Figure 1. The console output of our modified demonstration program<\/p>\n<p>Looking at figure 1, we can quickly see that: <\/p>\n<ol>\n<li>The assembly is running on the local computer,  <\/li>\n<li>The assembly is fully trusted, but the <strong>AssemblyInfo<\/strong> class is transparent, and &#8230;  <\/li>\n<li>Even the <strong>GetCasSecurityAttributes<\/strong>method is transparent;  <\/li>\n<li>When trying to get the <strong>PermissionSet.Count<\/strong> value, we get an exception which reminds us that the assembly is marked with the APTCA attribute, so all of its classes and methods are <em>SecurityTransparen<\/em>, and cannot call <em>SecurityCritical<\/em> code. <\/li>\n<\/ol>\n<p>At this point, it seems that we&#8217;re observing the same behavior we would have obtained by using the <em>SecurityTransparent<\/em> assembly attribute, so where is the difference? The difference lies in the fact that the APTCA attribute allow us to define the Security level of the code in a more granular way. With it, we can directly modify the Security level of the <em>GetCasSecurityAttributes<\/em> method, making it <em>SecurityCritical<\/em> or <em>SecuritySafeCritical<\/em>. At this point, we&#8217;ll choose to set it as <em>SecurityCritical:<\/em><\/p>\n<pre class=\"lang:c# theme:vs2012\">\/\/\/ &lt;summary&gt;\n\/\/\/ Write to the console the security settings of the assembly\n\/\/\/ &lt;\/summary&gt;\n&#160;&#160;&#160;&#160;[SecurityCrtitical()]\n&#160;&#160;&#160;&#160;public string GetCasSecurityAttributes()\n&#160;&#160;&#160;&#160;{<\/pre>\n<p>&#8230; and by running the .exe a second time, we obtain the following result:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure2.gif\" width=\"630\" height=\"228\" alt=\"1085-figure2.gif\" \/><\/p>\n<p class=\"caption\">Figure 2. Running the demonstration program with fine-grained control of method security level in place.<\/p>\n<p>As you can see, the exception message has disappeared because, even if the class is <em>SecurityTransparent<\/em>, the underlying method is now <em>SecurityCritical<\/em> and can execute the PermissionSet property&#8217;s accessor. Just to demonstrate the difference between the APTCA and <em>SecurityTransparent<\/em> attributes, if we replace the following line:<\/p>\n<pre class=\"lang:c# theme:vs2012\">[assembly:AllowPartiallyTrustedCallers()] <\/pre>\n<p>&#8230; with:<\/p>\n<pre class=\"lang:c# theme:vs2012\">[assembly:SecurityTransparent()]<\/pre>\n<p>which we used in Part I of this short series (as I mentioned at the start of this section), we get &#160;a familiar output:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure3.gif\" width=\"630\" height=\"262\" alt=\"1085-figure3.gif\" \/><\/p>\n<p class=\"caption\">Figure 3. Running the demonstration program with assembly-level SecurityTransparency in place, and no fine-grained control.<\/p>\n<p>As expected, the <em>SecurityCritical<\/em> attribute on the <em>GetCasSecurityAttributes<\/em> now has no effect, and the method remains <em>SecurityTransparent<\/em>.<\/p>\n<h1><a id=\"Custom_Resources\"><\/a>Custom Resources <\/h1>\n<p>Despite the simplicity of the previous example, <em>SecurityCritical<\/em> and <em>SecuritySafeCritical<\/em> attributes can be mixed together in APCTA assemblies in very different ways to set up custom protection strategies. Rather than always invoking the same classical protected resources of a system, let&#8217;s look at an example that shows how the Level2 Security Transparence model can be used to protect any type of resource we want, thus going beyond the legacy CAS Policy model. Consider the following <strong>CasWriter<\/strong> class, defined inside a demo assembly named <strong>CasWriter.dll<\/strong>:<\/p>\n<pre class=\"lang:c# theme:vs2012\">[assembly: AllowPartiallyTrustedCallers()]\n&#160;&#160;&#160;&#160;&#160;&#160;namespace CasWriterDemo\n&#160;&#160;{\n&#160;&#160;&#160;&#160;\/\/\/ &lt;summary&gt;\n&#160;&#160;&#160;&#160;\/\/\/ Write sentences\n&#160;&#160;&#160;&#160;\/\/\/ &lt;\/summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public class CasWriter\n&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ Write a sentence to console\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;\/summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;param id=\"text\"\"&gt;&lt;\/param&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public void WriteCustomSentence(string text)\n&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Console.WriteLine(text + \"\\n\");\n&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ Write a sentence to console\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;\/summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;param id=\"text\"\"&gt;&lt;\/param&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public void WriteDefaultSentence(int index)\n&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;switch (index)\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;case 0:\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;WriteCustomSentence(\"homo homini lupus\");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;break;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;case 1:\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;WriteCustomSentence(\"melius abundare quam deficere\");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;break;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;case 2:\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;WriteCustomSentence(\"audaces fortuna iuvat\");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;break;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ Get the Security status of each method developed\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;\/summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public string GetMethodsSecurityStatus()\n&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;\/\/get the MethodInfo of each method\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;MethodInfo[] infos = GetType().GetMethods();\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;StringBuilder sb = new StringBuilder();\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;foreach (MethodInfo m in infos)\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (m.ReturnType != typeof(void)) continue;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.Append(\"\\n\");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.Append(m.Name + \": \");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;if (m.IsSecurityCritical)\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.Append(\"SecurityCritical\\n\");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;else if (m.IsSecuritySafeCritical)\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.Append(\"SecuritySafeCritical\\n\");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;else if (m.IsSecurityTransparent)\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;sb.Append(\"SecurityTransparent\\n\");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return sb.Append(\"\\n\\n\").ToString();\n&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;}\n&#160;&#160;}\n<\/pre>\n<p>The class has the following three static methods:<\/p>\n<ul>\n<li><strong>WriteCustomSentence(string text):<\/strong> this method writes a sentence, passed to it as input, to the console.  <\/li>\n<li><strong>WriteDefaultSentence(int index):<\/strong> This method writes a fixed sentence to the console, selecting from among three possible values. The input parameter states which sentence to write.  <\/li>\n<li><strong>string GetMethodsSecurityStatus(): <\/strong>This method returns, as a string, the Security status of the two previous methods.<strong><\/strong> <\/li>\n<\/ul>\n<p>Now we write a console application (<strong>CasWriterDemo.exe<\/strong>) that consumes the previous methods:<\/p>\n<pre class=\"lang:c# theme:vs2012\">[assembly:SecurityTransparent()]\n&#160;&#160;&#160;&#160;&#160;&#160;namespace CasWriterDemo\n&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;class Program\n&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;static void Main(string[] args)\n&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;CasWriter writer = new CasWriter();\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Console.WriteLine(writer.GetMethodsSecurityStatus());\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;try\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Console.Write(\"Custom Sentence: \");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;writer.WriteCustomSentence(\"Barba non facit philosophum\");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;catch (Exception ex)\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Console.WriteLine(\"\\n\\n\" + ex.Message + \"\\n\\n\" );\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;try\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Console.Write(\"Default Sentence: \");\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;writer.WriteDefaultSentence(new Random().Next(0, 2));\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;catch (Exception ex)\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Console.WriteLine(\"\\n\\n\" + ex.Message);\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Console.ReadKey();\n&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;}\n&#160;&#160;}\n<\/pre>\n<p>We have marked the <strong>CasWriterDemo.exe<\/strong> assembly as <em>SecurityTransparent<\/em> because we want to test what happens when the <strong>CasWriter.dll<\/strong> assembly is called by partially trusted code. <\/p>\n<p>Given that the <strong>CasWriter.dll<\/strong> is marked with the APTCA attribute, all the code inside it is <em>SecurityTransparent<\/em>, and so we should expect that the application will run correctly. We are in a situation where <em>SecurityTransparent<\/em> code calls other <em>SecurityTransparent<\/em> code, and the Level2 <em>SecurityTransparent<\/em> model certainly allows this. Running the application, we obtain the following result:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure4.gif\" width=\"630\" height=\"206\" alt=\"1085-figure4.gif\" \/><\/p>\n<p class=\"caption\">Figure 4. Testing the new demonstration CASWriterDemo program.<\/p>\n<p>We see from figure 4 that, as expected, the two methods are both <em>SecurityTransparent<\/em> and the sentences are correctly written to the console. Now suppose that we want to prevent partially trusted code from being able to write a custom sentence, and only leave it with the ability to write a default sentence selected from an index. In this situation, the <strong>WriteCustomSentence<\/strong> therefore becomes our protected resource. To achieve this, we need to:<\/p>\n<ol>\n<li>Mark the <strong>WriteCustomSentence<\/strong> method as <em>SecurityCritical<\/em>, so that <em>SecurityTransparent<\/em> code cannot access it.  <\/li>\n<li>Mark the <strong>W<\/strong><strong>riteDefaultSentence<\/strong> method as <em>SecuritySafeCritical<\/em>. <\/li>\n<\/ol>\n<p>This second modification should sound a little strange; after all, the <strong>WriteDefaultSentence<\/strong> method is already <em>SecurityTransparent<\/em>, and so it can be accessed by other <em>SecurityTransparent<\/em> code. Our executable is also <em>SecurityTransparent<\/em>, so it can also access the <em>SecurityTransparent<\/em> <strong>WriteDefaultSentence<\/strong> method. However, you should note that the <strong>WriteDefaultSentence<\/strong> method uses the <strong>WriteCustomSentence<\/strong> method after a sentence has been selected. <\/p>\n<p>The overall effect is that the <em>SecurityTransparent<\/em> <strong>WriteDefaultSentence<\/strong> method now calls a <em>SecurityCritical<\/em> method: <strong>WriteCustomSentence<\/strong>. So, if we try to call <strong>WriteDefaultSentence<\/strong> from <em>SecurityTransparent<\/em> code, we&#8217;ll get an exception; let&#8217;s try to run our .exe without the second modification:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure5.gif\" width=\"630\" height=\"318\" alt=\"1085-figure5.gif\" \/><\/p>\n<p class=\"caption\">Figure 5. Running the demonstration .exe without marking the WriteDefaultSentence method as <em>SecuritySafeCritical.<\/em><\/p>\n<p>As we can see, the <strong>WriteCustomSentence<\/strong> method is now <em>SecurityCritical<\/em>, and cannot be accessed by <em>SecurityTransparent<\/em> code. You can find the exception associated with this behavior after the &#8220;<em>Custom Sentence:<\/em>&#8221; line in figure 5. To quickly recap, the <strong>WriteDefaultSentence<\/strong> method is <em>SecurityTransparent<\/em>, so the main method of the .exe can access it, but when <strong>WriteDefaultSentence<\/strong> tries to use the <strong>WriteCustomSentence<\/strong> method to write the output to the console, an exception occurs, as you can see after the &#8220;<em>Default Sentence:<\/em>&#8221; line in figure 5.<\/p>\n<p>So, analyzing the each step involved in this demonstration, we have:<\/p>\n<ol>\n<li>The Main method calls <strong>WriteCustomSentence<\/strong>, which leads to an exception. A <em>SecurityTransparent<\/em> method cannot call a <em>SecurityCritical<\/em> method.\n<\/li>\n<li>(a) The Main method calls <strong>WriteDefaultSentence<\/strong>, which is successful. A <em>SecurityTransparent<\/em> method can call a <em>SecurityTransparent<\/em> method. <\/li>\n<\/ol>\n<ol>\n<li>(b) The <strong>WriteDefaultSentence<\/strong> method calls <strong>WriteCustomSentence<\/strong>, which leads to an exception. A <em>SecurityTransparent<\/em> method cannot call a <em>SecurityCritical<\/em> method.<\/li>\n<\/ol>\n<p>If, as suggested in the second modification above, we mark the <strong>WriteDefaultSentence<\/strong> method as <em>SecuritySafeCritical<\/em>, we solve this potential problem. <em>SecuritySafeCritical<\/em> code is designed to act as a permission bridge, in that it can be called by <em>SecurityTransparent<\/em> code and it can, in turn, call <em>SecurityCritical<\/em> code. So, with this modification, we will create a bridge between the <em>SecurityTransparent<\/em> code (the Main method) and the <em>SecurityCritical<\/em> code (the <strong>WriteCustomSentence<\/strong> method). If we now run our .exe, we see this result:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure6.gif\" width=\"630\" height=\"240\" alt=\"1085-figure6.gif\" \/><\/p>\n<p class=\"caption\">Figure 6. Using <em>SecuritySafeCritical<\/em> code to bridge the permission gap between the Main method and the WriteCustomSentence method.<\/p>\n<p>&#8230; Which is exactly the result we want to achieve. We have protected the <strong>WriteCustomSentence<\/strong> method (our custom resource) from the partially trusted assembly (which is <em>SecurityTransparent<\/em> code) while allowing the same assembly to access the <strong>WriteDefaultSentence<\/strong> method!<\/p>\n<h1><a id=\"Inheritance\"><\/a>Inheritance and Override Rules <\/h1>\n<p>We&#8217;ve seen how resource protection works when one method calls another, but the security checks performed in these situations are not enough to achieve a complete set of security instruments. For example, we know that object oriented languages, such as those provided with .NET, allow inheritance and the overriding of classes, methods and types. So we need to protect those same objects with a derived version of the same inheritance structure. The new .NET Framework 4.0 Code Access Security system manages this need by using the following two rules:<\/p>\n<ol>\n<li>Derived types must be at least as restrictive as base types.  <\/li>\n<li>Derived methods cannot modify the accessibility of their base methods. <\/li>\n<\/ol>\n<p>Derived methods are <em>SecurityTransparent<\/em> by default and so, if the base method is not <em>SecurityTransparent<\/em>, the derived must be marked appropriately to prevent violating the first inheritance rule.<\/p>\n<p>To demonstrate the two rules, we&#8217;ll write a <strong>CasWriter2<\/strong> class that inherits from the <strong>CasWriter<\/strong> class, and will have a <strong>WriteCustomSentence<\/strong> method that inherits from the base <strong>WriteCustomSentence<\/strong> method (which we mark as virtual). The code for this will be:<\/p>\n<pre class=\"lang:c# theme:vs2012\">namespace CasWriterDemo\n&#160;&#160;{\n&#160;&#160;&#160;&#160;\/\/\/ &lt;summary&gt;\n&#160;&#160;&#160;&#160;\/\/\/ Write sentences\n&#160;&#160;&#160;&#160;\/\/\/ &lt;\/summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public class CasWriter2 : CasWriter\n&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ \n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;\/summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;\/\/\/ &lt;param id=\"text\"\"&gt;&lt;\/param&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;public override void WriteCustomSentence(string text)\n&#160;&#160;&#160;&#160;&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;base.WriteCustomSentence(text);\n&#160;&#160;&#160;&#160;&#160;&#160;}\n&#160;&#160;&#160;&#160;}\n&#160;&#160;}\n<\/pre>\n<p>&#160;To demonstrate the first inheritance and override rule, we&#8217;ll set the <strong>CasWriter<\/strong> class as <em>SecurityCritical<\/em>:<\/p>\n<pre class=\"lang:c# theme:vs2012\">\/\/\/ &lt;summary&gt;\n&#160;&#160;\/\/\/ Write sentences\n&#160;&#160;\/\/\/ &lt;\/summary&gt;\n&#160;&#160;&#160;&#160;&#160;&#160;[SecurityCritical()]\n&#160;&#160;&#160;&#160;&#160;&#160;public class CasWriter<\/pre>\n<p>&#8230; and, in the main method of the <strong>CasWriterDemo.exe<\/strong> assembly, we&#8217;ll substitute the <strong>CasWriter<\/strong> object with the <strong>CasWriter2<\/strong> object:<\/p>\n<pre class=\"lang:c# theme:vs2012\">static void Main(string[] args)\n&#160;&#160;{\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;CasWriter writer = new CasWriter2();\n&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;Console.WriteLine(writer.GetMethodsSecurityStatus());<\/pre>\n<p>So, we&#8217;ve tried to derived the <em>SecurityTransparent<\/em> <strong>CasWriter2<\/strong> class from a <em>SecurityCritical<\/em> <strong>CasWriter<\/strong> class, but, with the first rule in place, this is not possible because we have tried to create a <em>SecurityTransparent<\/em> (low protected) type from a <em>SecurityCritical<\/em> (high protected) type. As a result, if we run our .exe we obtain:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure7.gif\" width=\"630\" height=\"319\" alt=\"1085-figure7.gif\" \/><\/p>\n<p class=\"caption\">Figure 7. An exception thrown from trying to derive a <em>SecurityTransparent<\/em> type from a <em>SecurityCritical<\/em> one.<\/p>\n<p>As expected, a type load exception is thrown, stating that an inheritance security rule has been violated. Notice that the exe stop working as well; because the exception is detected when the assembly tries to load the CasWriter2 type, it&#8217;s not possible to handle the exception through code.<\/p>\n<p>To make this as clear as possible, the following table sums up the inheritance rules for classes:<\/p>\n<table>\n<tbody>\n<tr>\n<td valign=\"top\">\n<p class=\"style1\"><strong>Base Class<\/strong><\/p>\n<\/td>\n<td valign=\"top\">\n<p class=\"style1\"><strong>Derived Class &#160;<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Transparent<\/p>\n<\/td>\n<td>\n<p>Transparent<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Transparent<\/p>\n<\/td>\n<td>\n<p>SafeCritical <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Transparent<\/p>\n<\/td>\n<td>\n<p>Critical<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>SafeCritical <\/p>\n<\/td>\n<td>\n<p>SafeCritical <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>SafeCritical<\/p>\n<\/td>\n<td>\n<p>Critical<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Critical<\/p>\n<\/td>\n<td>\n<p>Critical<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>To demonstrate the second rule, we&#8217;ll remove the <em>SecurityCritical<\/em> attribute from the <strong>CasWriter<\/strong> class. In this case, the first rules is no longer violated as both classes are <em>SecurityTransparent<\/em>. However, there is a second issue to consider; we are trying to override <em>SecurityCritical<\/em> code (the base <strong>WriteCustomSentence<\/strong>) with what is now <em>SecurityTransparent<\/em> code (the derived <strong>WriteCustomSentence<\/strong>), which is not allowed by the second rule. Remember that the derived method is <em>SecurityTransparent<\/em> by default, and we haven&#8217;t specified any other security attribute for it. Running the .exe, we therefore get:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure8.gif\" width=\"630\" height=\"319\" alt=\"1085-figure8.gif\" \/><\/p>\n<p class=\"caption\">Figure 8. Our new demonstration program violating the second Inheritance and Override CAS rule, and throwing an exception.<\/p>\n<p>As expected, an exception is thrown saying that there is a violation on a security rule when overriding the <strong>WriteCustomSentence<\/strong>. I&#8217;ll leave it to you to mark the <strong>WriteCustomSentence<\/strong> method of the <strong>CasWriter2<\/strong> class as <em>SecurityCritical<\/em> and verify that, in this last situation, all goes well. To try it, you can download the supporting zip file at the top of the page, which contains the entire example provided in this article. Before we finish looking at methods, let&#8217;s just confirm their inheritance rules:<\/p>\n<table>\n<tbody>\n<tr>\n<td>\n<p class=\"style1\"><strong>Base Method<\/strong><\/p>\n<\/td>\n<td>\n<p class=\"style1\"><strong>Derived Method&#160; <\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Transparent<\/p>\n<\/td>\n<td>\n<p>Transparent<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Transparent<\/p>\n<\/td>\n<td>\n<p>SafeCritical <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>SafeCritical <\/p>\n<\/td>\n<td>\n<p>Transaprent<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>SafeCritical <\/p>\n<\/td>\n<td>\n<p>SafeCritical<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>Critical<\/p>\n<\/td>\n<td>\n<p>Critical<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>I&#8217;ll end this section by pointing that the same rules apply when we develop a class that implements an interface. The implemented method must respect the inheritance rules (the same as those in the table above) in relation to the attributes set for the interface members. &#160;<\/p>\n<h1><a id=\"SecAnnotate\"><\/a>The .NET Security Annotator Tool <\/h1>\n<p>In the previous example we saw how to mix the <em>SecurityCritical<\/em> and <em>SecuritySafeCritical<\/em> attributes to protect the <strong>WriteCustomSentence<\/strong> method from partially trusted code. Admittedly, that example was very easy and to set the correct attributes was a trivial task. Things are not so easy with more complex assemblies, and there is a risk of creating confusion as you try and unravel the security dependencies. This is precisely why Microsoft&#8217;s .NET Framework 4.0 provides a very useful tool, named <strong>.NET<\/strong> <strong>Security Annotator<\/strong> (<strong>SecAnnotate.exe<\/strong>), which can help developers to identify the correct attributes to use in theirs code. You can find it in the Microsoft Windows SDK version 7.0A, under the <em>\\bin\\NETFX 4.0 Tools<\/em> folder.<\/p>\n<p>The <strong>SecAnnotate.exe<\/strong> tool browses an assembly to identify what modifications have to be made to avoid security exceptions when the assembly runs, and checks are made in several passes. In the first pass, the tool discovers what modifications must be performed on the assembly as it initially exists. If it detects that some code must be marked as <em>SecurityCritical<\/em> or <em>SecuritySafeCritical<\/em>, it performs a second pass, applying, at run time, the modifications discovered to be necessary in the first pass. The tool then makes a third pass, and if it detects that <em>new<\/em> modifications are needed as a result of the previous changes, it then makes these modifications in a fourth pass . The process repeats itself (scan &#8211; modify &#8211; scan &#8211; modify&#8230;), and ends when the tool doesn&#8217;t find anything left to change. At the end of the execution, <strong>SecAnnotation.exe<\/strong> generates an output report that contains the result of the analysis performed in each step.<\/p>\n<p>There are two things you should bear in mind:<\/p>\n<ol>\n<li>If <strong>SecAnnotate.exe<\/strong> discovers that a method should be marked as either <em>SecurityCritical<\/em> or <em>SecuritySafeCritical<\/em>, it prefers the first attribute, it being a more secure option. Sometimes developers need to manually select the <em>SecuritySafeCritical<\/em> attribute instead of <em>SecurityCritical<\/em>, and this could generate problems during the following passes. We will see an example of what I mean in a moment. To avoid this, the <strong>SecAnnotate.exe<\/strong> tool comes with the <strong><em>\/p:&lt;n&gt;<\/em><\/strong> &#160;command-line switch, which can be used to set the maximum number of passes that can be performed prior to stopping the execution and generating the output. In terms of a more tightly-controlled process which allows you to take direct and fine-grained control of your code security, It would be better to:\n<ol>\n<li>run the tool with the \/p:1 command-line switch so that, at each pass, a new output is generated;  <\/li>\n<li>manually perform the desired modifications to the assembly on the basis of that output,  <\/li>\n<li>recompile your assembly and  <\/li>\n<li>re-run <strong>SecAnnotate.exe<\/strong> with the \/p:1 command-line switch to obtain a new output, and repeat. The procedure ends when no other modifications are needed, as when you allow <strong>SecAnnotate.exe<\/strong> to run without human intervention.\n<\/li>\n<\/ol>\n<\/li>\n<li>To perform the check, the <strong>SecAnnotate.exe<\/strong> tool has to verify how the assembly&#8217;s methods behave in relation to the methods that they call. Usually, assemblies use the .NET Framework base classes, and so checks regarding the attributes needed to call their methods can be performed.&#160; If an assembly uses other (third party or your own) assemblies, different from those present in .NET Framework base classes (and, in general, from those contained in the Global Assembly Cache), the path to them must be specified Using &#160;the <strong><em>\/d:&lt;directory&gt;<\/em><\/strong>&#160; command-line switch. <\/li>\n<\/ol>\n<p>With all that in mind, if we return to our <strong>CasWriter.dll<\/strong> assembly, remove the security attributes which we set in the previous section and launch the following command from the console:<\/p>\n<pre>SecAnnotate.exe CasWriter.dll <\/pre>\n<p>&#8230;we will obtain the following output:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure9.gif\" width=\"630\" height=\"195\" alt=\"1085-figure9.gif\" \/><\/p>\n<p class=\"caption\">Figure 9. Running SecAnnotate.exe against our demonstration program.<\/p>\n<p>The tool doesn&#8217;t find anything to annotate, because the assembly is made up of <em>SecurityTransparent<\/em> code that calls other <em>SecurityTransparent<\/em> code (specifically, those code of the .NET Framework base classes which we used).<\/p>\n<p>But, if we want to protect the <strong>WriteCustomSentence<\/strong> method by marking it as <em>SecurityCritical <\/em>(as we did earlier), and we launch the previous command on the newly compiled assembly, we get a different result:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure10.gif\" width=\"630\" height=\"228\" alt=\"1085-figure10.gif\" \/><\/p>\n<p class=\"caption\">Figure 10. Getting SecAnnotate.exe to do some work on our demo .exe.<\/p>\n<p>We can see that the tool found three necessary annotation and the jobs were completed in two passes.&#160; Moreover, it generated a detailed report titles <strong>TransparencyAnnotations.xml<\/strong> (we can override the name with the <strong><em>\/o:&lt;filename.xml&gt;<\/em><\/strong>command-line switch), the contents of which looks like this: <\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure11.jpg\" width=\"630\" height=\"597\" alt=\"1085-figure11.jpg\" \/><\/p>\n<p class=\"caption\">Figure 11. The contents of TransparencyAnnotations.xml<\/p>\n<p>We can quickly see that the <strong>SecAnnotation.exe<\/strong> tool made an annotation in the <strong>WriteDefaultSentence<\/strong> method, for three identical reasons. The rule violated is given by <em>TransparentMethodsMustNotReferenceCriticalCode<\/em>, as we expected. The three reasons are all identical because the <em>SecurityTransparent<\/em> <strong>WriteDefaultSentence<\/strong> method contains three calls to the <em>SecurityCritical<\/em> <strong>WriteCustomSentence<\/strong> method (inside the switch block of code).<\/p>\n<p>Another important aspect of this report to take note of is that the tool suggests four different ways to avoid the annotation:<\/p>\n<ol>\n<li><strong>WriteDefaultSentence<\/strong> must become <em>SecurityCritical<\/em>  <\/li>\n<li><strong>WriteDefaultSentence<\/strong> must become <em>SecuritySafeCritical<\/em>  <\/li>\n<li><strong>WriteCustomSentence<\/strong> must become <em>SecuritySafeCritical<\/em>  <\/li>\n<li><strong>WriteCustomSentence<\/strong> must become <em>SecurityTransparent<\/em> <\/li>\n<\/ol>\n<p>If they could all, separately, entirely resolve the problem, we know that, for the goals we have in mind, the only available solution is to make <strong>WriteDefaultSentence<\/strong> <em>SecuritySafeCritical<\/em>, in order to grant access to it from <em>SecurityTransparent<\/em> code, while leaving the <strong>WriteCustomSentence<\/strong> method protected. &#160;We also know that the tool, after the first pass, applies the rule that it consider to be preferable as it performs its second pass, and that it prefers changes that bring about the best possible security situation. <\/p>\n<p>In our example it might have chosen option number 1 and, as a result, the assembly would become fully <em>SecurityCritical<\/em>, and thus completely protected from <em>SecurityTransparent<\/em> code. This represents the more secure situation. However, we know that, for our goals, the solution that we need is number 2. Indeed, applying option number 1 instead of number 2 could bring about another round of checks that could have a totally different output, sending SecAnnotate.exe further and further away from our desired outcome. So, as I mentioned, we should probably use the tools with the <strong>\/p:1<\/strong> command-line switch, and make the changes manually.<\/p>\n<p>We&#8217;ll end this section by running the <strong>SecAnnotatio.exe<\/strong> tool against the console application, just to see what happens. To do so, we need to specify the location of the <strong>CasWriter.dll<\/strong> assembly from which <strong>CasWriterDemo.exe<\/strong> depends. As seen earlier, to do so, we must use the <strong>\/d<\/strong> command-line switch; assuming that the <strong>CasWriter.dll<\/strong> is contained in root of the <strong>D:\\<\/strong> drive, we need to run the following command:<\/p>\n<pre>SecAnnotate.exe \/d:D:\\ CasWriterDemo.exe <\/pre>\n<p>The output that we get is seen below:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure12.gif\" width=\"630\" height=\"228\" alt=\"1085-figure12.gif\" \/><\/p>\n<p class=\"caption\">Figure 12. Running SecAnnotate.exe against our console application.<\/p>\n<p>We can quickly see that the tool has found only one annotation, which we can see in the accompanying report:<\/p>\n<p class=\"illustration\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/1085-figure13.gif\" width=\"630\" height=\"394\" alt=\"1085-figure13.gif\" \/><\/p>\n<p class=\"caption\">Figure 13. The SecAnnotate.exe report for our console application.<\/p>\n<p>The annotation is related to the Main method, which is <strong><em>SecurityTransparent<\/em><\/strong> and is trying to access <strong><em>SecurityCritical<\/em><\/strong> code. Note that this is not an exception, but rather the behavior that we wanted to implement in our <strong>CasWriter.dll<\/strong> to protect <strong>WriteCustomSentence<\/strong> from <em>SecurityTransparent<\/em> code (such as the Main method). So, when using this tool, analyze the output generated with great care and attention.<\/p>\n<p>Beyond all this, there is one last important point to consider. We have written two assemblies, <strong>CasWriterDemo.exe<\/strong> and its related <strong>CasWriter.dll<\/strong> assemblies, and if we want to use the <strong>SecAnnotation.exe<\/strong> tool to check the CAS rules for the entire solution, we simply cannot do it in a single step. In the last example, we analyzed the <strong>CasWriterDemo.exe<\/strong> assembly by specifying its referenced <strong>CasWriter.dll<\/strong> assembly. However, from the output that we obtained, it&#8217;s clear that the checks were only made for the <strong>CasWriterDemo.exe<\/strong> assembly and how it behaves in relation to its dependent <strong>CasWriter.dll<\/strong> assembly &#8211; No check was made for the <strong>CasWriter.dll<\/strong> assembly (If you didn&#8217;t notice it at the time, the three annotations related to the <strong>CasWriter.dll<\/strong> assembly are not present in the later report). <\/p>\n<p>The point I&#8217;m trying to make is that, if you want to check your entire solution, you need to perform the check for each assembly, one at a time.&#160; Unless you have specific security goals in mind, the best way seem to be to check the dependent assembly first, and then its immediate callers. <\/p>\n<h1><a id=\"Conclusion\"><\/a>Conclusion <\/h1>\n<p>We&#8217;ve covered a huge amount of ground in this article (much of which was set up and based on material <a href=\"http:\/\/www.simple-talk.com\/dotnet\/.net-framework\/whats-new-in-code-access-security-in-.net-framework-4.0---part-i\/\">in my previous CAS article<\/a>, which you should read if you haven&#8217;t done so already). To start with, we&#8217;ve seen how to use <em>APTCA<\/em>, <em>SecurityCritical<\/em> and <em>SecuritySafeCritical<\/em> attributes to set up a protection strategy when an assembly must be callable by partially trusted code. We have also seen that the work that has to be done to implement security strategies within this new model is not as easy as we might like, but, fortunately, the new SecAnnotation.exe tool can give us a great head start. <\/p>\n<p>Let&#8217;s end this article with some reflections about how to set up a successful protection strategy when working with the new Level2 SecurityTransparence model. We can define two different situations&#160; which we are likely to find ourselves in:<\/p>\n<ol>\n<li><strong>Our assembly must protect the underlying dependent assemblies (for example, the .NET Framework base classes)<\/strong>. In this case, we need to maximize the amount of <em>SecurityCritical<\/em> code. In this way, we are able to protect all the dependent assemblies from partially trusted (<em>SecurityTransparent<\/em>) assemblies with an impenetrable &#8220;wall&#8221;.  <\/li>\n<li><strong>Our assembly will be protected by its potential callers.<\/strong> If our assembly needs to be accessed by partially trusted assembly, we need to maximize the amount of <em>SecurityTransparent<\/em> code. If the assembly doesn&#8217;t make use of protected resources, we only need to mark it as <em>SecurityTransparent<\/em>, otherwise, we must use the <em>APTCA <\/em>attributes and try, method by method, to maximize <em>SecurityTransparent<\/em> code and minimize <em>SecuritySafeCritical<\/em> code. <\/li>\n<\/ol>\n<p>Of course, it isn&#8217;t so easy to guess the entire spectrum of possible scenarios and verify if the two rules above are applicable to all of them, so those two must be considered as general guidelines instead. In any case, we shouldn&#8217;t enter too deeply into this particular subject at this stage; partly because it is too complex to analyze succinctly, and partly because the Level2 SecurityTransparence model is, at the time of writing, a very new, and not yet sufficiently documented technology. I&#8217;d suggest that you follow the <a href=\"http:\/\/blogs.msdn.com\/b\/shawnfa\/rss.aspx\">.NET Security Blog<\/a>, which will surely, over time, bring you up-to-date about the new Level2 SecurityTransparence model and its implementations.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Having introduced us to the basics of the new Code Access Security Model available in .NET Framework 4.0, Matteo Slaviero explains how to use this powerful new system to implement fine-grained code security in ways where have never before been possible.&hellip;<\/p>\n","protected":false},"author":221869,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538],"tags":[4143,5246,4229,5245,4242,5244,5216,4619],"coauthors":[],"class_list":["post-937","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","tag-net","tag-net-4-0","tag-net-framework","tag-net-framework-4-0","tag-basics","tag-cas","tag-code-access-security","tag-security"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/937","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221869"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=937"}],"version-history":[{"count":6,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/937\/revisions"}],"predecessor-version":[{"id":91123,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/937\/revisions\/91123"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=937"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=937"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=937"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=937"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}