<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Fabulous Adventures In Coding : Security</title><link>http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx</link><description>Tags: Security</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Sorry about the CAPTCHA</title><link>http://blogs.msdn.com/ericlippert/archive/2009/09/10/sorry-about-the-captcha.aspx</link><pubDate>Thu, 10 Sep 2009 16:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9893152</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>18</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9893152.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9893152</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;A quick metablogging note. Those of you who comment on this blog (6700+ comments and counting, thank you all) have probably noticed that it now has a CAPTCHA, that little "please prove you're a human" test before the comment is posted.&lt;/P&gt;
&lt;P&gt;I understand why. The MSDN and TechNet blog sites are high-value targets for unwanted commercial advertisers, for attackers who wish to attempt to influence search engines to drive traffic to their sites, and for&amp;nbsp;vandals. The people who run security for this site have their hands full; we've experienced some pretty serious denials of service based on ham-fisted spammer attacks. Adding a CAPTCHA to regulate comments massively slows down the rate of successful comment spam. &lt;/P&gt;
&lt;P&gt;That said, I'm not thrilled about this.&amp;nbsp;I find&amp;nbsp;CAPTCHA-style solutions distasteful for several reasons:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The benign commenter -- precisely the kind of person we want to encourage -- is forced to do additional work. This is a small but nonzero disincentive to writing comments. &lt;/LI&gt;
&lt;LI&gt;Sometimes mistakes will be made; providing new ways that computers can tell us on a daily basis that we are failures seems irksome. &lt;/LI&gt;
&lt;LI&gt;The assumption of innocence is changed to an assumption of guilt; the benign commenter must prove their innocence. Every time I have to fill out a CAPTCHA I feel a small but real insult; I'm a trustworthy person, so trust me already. As &lt;A class="" href="http://www.joelonsoftware.com/articles/BuildingCommunitieswithSo.html" mce_href="http://www.joelonsoftware.com/articles/BuildingCommunitieswithSo.html"&gt;Joel Spolsky once pointed out&lt;/A&gt;, it's like walking into a&amp;nbsp;train station&amp;nbsp;and the first thing you see is the NO SKATEBOARDING NO PANHANDLING NO THIS NO THAT NO THE OTHER THING sign. Its unwelcoming. It makes you feel attacked and guilty and reminds you that there is evil in the world.&lt;/LI&gt;
&lt;LI&gt;There are accessibility concerns. Not everyone who uses computers&amp;nbsp;has decent vision but that doesn't make them evil robots. They deserve as much as a chance as everyone else to contribute and have to overcome plenty of&amp;nbsp;obstacles already; let's not throw more in their way.&lt;/LI&gt;
&lt;LI&gt;And so on&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;So, sorry about that, commenters. I don't like it any more than you do, but there's not much I can do about it; I don't run the blog servers. The only thing I can control is how purple the text is.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9893152" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Metablogging/default.aspx">Metablogging</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/CAPTCHA/default.aspx">CAPTCHA</category></item><item><title>What's the Difference, Part Five: certificate signing vs strong naming</title><link>http://blogs.msdn.com/ericlippert/archive/2009/09/03/what-s-the-difference-part-five-certificate-signing-vs-strong-naming.aspx</link><pubDate>Thu, 03 Sep 2009 16:48:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9885577</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9885577.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9885577</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Both strong naming and digital signatures use &lt;STRONG&gt;public key cryptography&lt;/STRONG&gt; to provide &lt;STRONG&gt;evidence&lt;/STRONG&gt; about the &lt;STRONG&gt;origin&lt;/STRONG&gt; of an assembly, so that you can apply &lt;STRONG&gt;security policy&lt;/STRONG&gt; to determine what &lt;STRONG&gt;permissions&lt;/STRONG&gt; are granted to the &lt;STRONG&gt;assembly&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;They differ most importantly not in their mathematical&amp;nbsp;details, but in what problems they are intended to solve.&lt;/P&gt;
&lt;P&gt;The purpose of a strong name is solely to ensure that &lt;STRONG&gt;when you load an assembly by name, you are loading exactly the assembly you think you are loading&lt;/STRONG&gt;.&amp;nbsp;You say "I want to load Frobber, version 4, that came from FooCorp". The strong name gear ensures that you actually load precisely that DLL, and not another assembly called Frobber, version 4, that came from Dr. Evil Enterprises. You can then set security policy which says "if I have an assembly from FooCorp on my machine, fully trust it." These scenarios are the only by-design purposes of strong names.&lt;/P&gt;
&lt;P&gt;In order to achieve this, all that is required is that you know the public key token associated with FooCorp's private key. How you come to know that public key token is entirely your business. There is no infrastructure in place designed to help you get that information safely. You're just expected to know what it is, somehow. If evil people can trick you into believing that their key token is in fact FooCorp's key token, then you have a problem. You are expected to come up with some reasonable way to determine what FooCorp's real key token is.&lt;/P&gt;
&lt;P&gt;The purpose of a digital signature from a publisher certificate is to &lt;STRONG&gt;establish a verifiable chain of identity and trust&lt;/STRONG&gt;. The chain of trust goes from a hunk of code of unknown or uncertain origin up to a "trusted root" -- an entity which you have configured your operating system to trust. &lt;/P&gt;
&lt;P&gt;You download some code, and the code has a digital signature with a certificate from FooCorp. You examine the certificate and it says "this program comes from FooCorp. The accuracy of this certificate is vouched for by VeriSign." Since VeriSign is one of your trusted roots, you now have confidence that this code actually did come from FooCorp.&lt;/P&gt;
&lt;P&gt;Notice how much more complex the problem solved by digital signatures is. We're not trying to simply determine "is this hunk of code associated with this name or not?" Instead we're trying to determine where did this code come from, and who vouches for the existence of the company allegedly responsible, and should we trust that company?&lt;/P&gt;
&lt;P&gt;The difference between strong names and digital signatures emphasizes what is hard about crypto-based security. The hard problem isn't the cryptography; that's just math. The hard problem is safely managing distribution of information about the keys and associating them with the correct entities. Strong names, because they attempt to solve a very small but important problem, do not have key management issues. Or, rather, they foist the key management problem off to you, the user. Digital signatures are all about trying to automate safe distribution of key information via certificates, in order to solve much more complex problems of trust and identity.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9885577" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/cryptography/default.aspx">cryptography</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/digital+signatures/default.aspx">digital signatures</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/certificates/default.aspx">certificates</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/strong+names/default.aspx">strong names</category></item><item><title>Alas, Smith and Jones</title><link>http://blogs.msdn.com/ericlippert/archive/2009/06/04/alas-smith-and-jones.aspx</link><pubDate>Thu, 04 Jun 2009 17:04:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9641041</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>14</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/9641041.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=9641041</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;We have a feature in C# which allows you to declare a "&lt;A class="" href="http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx" mce_href="http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx"&gt;friend assembly&lt;/A&gt;". If assembly Smith says that assembly Jones is its friend, then code in Jones is allowed to see "internal" types of Smith as though they were public(*). It's a pretty handy feature for building a "family" of assemblies that share common implementation details.&lt;/P&gt;
&lt;P&gt;The compiler enforces one particularly interesting rule about the naming of friendly assemblies. If assembly Smith is a strong-named assembly, and Smith says that assembly Jones is its friend, then Jones must also be strong-named. If, however, Smith is not strong-named, then Jones need not be strong-named either.&lt;/P&gt;
&lt;P&gt;I'm occasionally asked "what's up with that?"&lt;/P&gt;
&lt;P&gt;When you call a method in Smith and pass in some data, you are essentially trusting Smith to (1) make proper use of your data; the data might contain sensitive information that you don't want Smith to misuse, and (2) take some action on your behalf. In the non-computer world an entity which you share secrets with&amp;nbsp;and then empower to take actions on your behalf is called an "attorney" (**).&amp;nbsp; That got me thinking, which usually spells trouble.&lt;/P&gt;
&lt;P&gt;You want to hire an attorney. You go to Smith &amp;amp; Jones, Esqs. You meet with Smith, the trustworthy-looking man on the left of this photo:&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.bbc.co.uk/comedy/alassmithandjones/" mce_href="http://www.bbc.co.uk/comedy/alassmithandjones/"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=226 alt=alassmithandjones src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/AlasSmithandJones_12853/alassmithandjones_3.jpg" width=400 border=0 mce_src="http://blogs.msdn.com/blogfiles/ericlippert/WindowsLiveWriter/AlasSmithandJones_12853/alassmithandjones_3.jpg"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Scenario (1):&lt;/P&gt;
&lt;P&gt;You check Smith's ID. It really is Mel Smith. You are contemplating giving Smith a secret, and empowering Smith to act on your behalf with the knowledge of that secret. Smith says "I share my secrets with my partner Griff Rhys Jones, whose identity you may now verify, here is Jones and here is Jones' ID. Jones will also be acting on your behalf. Jones has full access to all secrets which are internal to this organization."&lt;/P&gt;
&lt;P&gt;You decide that you trust both Smith and Jones, so you share your secrets with Smith. A series of wacky sketch comedy hijinks then ensues.&lt;/P&gt;
&lt;P&gt;(Smith and Jones are both strong-named assemblies. That is, they have&amp;nbsp;"ID" you can verify. Smith's internals are visible to Jones. Everything is fine.)&lt;/P&gt;
&lt;P&gt;Scenario (2):&lt;/P&gt;
&lt;P&gt;You check the ID. It is Mel Smith. Smith says "By the way, I share my internal secrets with everyone in the world who claims their name is Jones, I don't bother to check IDs, I just trust 'em, and you should too! Everyone named Jones is trustworthy! Oh, and that includes my partner over here, Jones. Good old Jones! No, you can't check Jonesie's ID. Doesn't have any ID, that Jones." &lt;/P&gt;
&lt;P&gt;This is ludicrous. Obviously this breaks the chain of trust that you showed you were looking for when you checked Smith's ID in the first place. &lt;/P&gt;
&lt;P&gt;(The compiler keeps you from getting into this terrible situation by preventing Smith from doing that; Smith, a strong-named assembly, can only state that it is sharing his internal details with another strong-named assembly. Smith cannot share its internals with any assembly named Jones, a weakly-named assembly in this scenario. We restrict Smith from exposing internals to weakly-named assemblies so that Smith does not accidentally create this security hole or accidentally mislead you into believing that Smith's internals are in any way hidden from partially-trusted code.)&lt;/P&gt;
&lt;P&gt;Scenario (3):&lt;/P&gt;
&lt;P&gt;You don't bother to check Smith's ID. In fact, you give your secrets and power of attorney to anyone named Smith, regardless of who they actually are or where they came from. The first Smith you pick off the street says "By the way, I'll give my internal secrets to anyone named Jones".&amp;nbsp; &lt;/P&gt;
&lt;P&gt;Do you care?&amp;nbsp; Why would you?&amp;nbsp; You're already giving secrets away to anyone named Smith! If a con artist wants your secrets, he can pretend to be Jones and take them from Smith, or he can pretend to be Smith and get them from you directly, but either way, the problem is that you are giving away secrets and power of attorney to strangers off the street. &lt;/P&gt;
&lt;P&gt;(Smith and Jones are both weakly named assemblies, Smith exposes internals to Jones. This is perfectly legal, because if you don't care enough about who you're talking to to check IDs then what's the point of the security system preventing those random strangers from talking to each other?)&lt;/P&gt;
&lt;P&gt;**************&lt;BR&gt;(*) Fully trusted assemblies of course can always use reflection to see private and internal details of other assemblies; that is what "full trust" means. And in the new CLR security model, two assemblies that have the same grant set can see each other's private and internal details via reflection. But friend assemblies are the only mechanism that allow &lt;STRONG&gt;compile time&lt;/STRONG&gt; support for peering at the internal details of another assembly.&lt;/P&gt;
&lt;P&gt;(**) or "delegate", which obviously I want to avoid because that means something technical in C#.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9641041" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/strong+names/default.aspx">strong names</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/BBC+Television/default.aspx">BBC Television</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/friend+assemblies/default.aspx">friend assemblies</category></item><item><title>Preventing third-party derivation, part two</title><link>http://blogs.msdn.com/ericlippert/archive/2008/10/06/preventing-third-party-derivation-part-two.aspx</link><pubDate>Mon, 06 Oct 2008 17:50:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8977947</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>8</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/8977947.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=8977947</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;If you find a class in a library that has all private/internal constructors, it is pretty clear that the author of the class is sending you the deliberate&amp;nbsp;message that this class is not to be extended by you. In our previous example, it was not so clear. Obviously the author of the class in question did not think that extending the class was a by-design scenario (because if they did, their scenario tests would have immediately caught the problem) but it is not so clear that this restriction was deliberate, rather than accidental.&lt;/P&gt;
&lt;P&gt;I say that writing code and writing mystery novels are two entirely different things; don't give the user of your code a&amp;nbsp;twisty-turny puzzle to figure out with a surprise at the end. Make it obvious. If I wanted to make a class that was not third-party extensible by design, I'd not only make the constructors private, I'd slap one of these on the class:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;[PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Meaning: “Only classes inside assemblies which the current user’s security policy fully trusts may extend my class.”&lt;/P&gt;
&lt;P&gt;Or this:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;[StrongNameIdentityPermissionAttribute(SecurityAction.InheritanceDemand, &lt;BR&gt;PublicKey="00240000048000009400000006020000002400005253413100040000010001005" +&lt;BR&gt;"38a4a19382e9429cf516dcf1399facdccca092a06442efaf9ecaca33457be26ee0073c6bde5" +&lt;BR&gt;"1fe0873666a62459581669b510ae1e84bef6bcb1aff7957237279d8b7e0e25b71ad39df3684" +&lt;BR&gt;"5b7db60382c8eb73f289823578d33c09e48d0d2f90ed4541e1438008142ef714bfe604c41a4" +&lt;BR&gt;"957a4f6e6ab36b9715ec57625904c6")]&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;Meaning: “Only classes inside assemblies that were signed with the corresponding private key may extend my class.” (FYI, the binary blob there is an encoding of Microsoft's public key.)&lt;/P&gt;
&lt;P&gt;You'll notice that I said that I would make the constructors inaccessible &lt;EM&gt;and&lt;/EM&gt; put a security annotation in the metadata as well. Why both? Two reasons. First, &lt;STRONG&gt;defense in depth&lt;/STRONG&gt;. Don't just make something impossible, make it impossible in multiple ways. That way, if you're wrong about one of them, you've still got all the others to back you up.&lt;/P&gt;
&lt;P&gt;Second, because in this case, &lt;STRONG&gt;going with just the metadata solution is not enough&lt;/STRONG&gt;. &lt;/P&gt;
&lt;P&gt;This was surprising to me. I cut my teeth on the .NET security system back in its earliest incarnation; things have changed since then. The meaning I gave of the second attribute up there is subtly wrong. It should have said&lt;/P&gt;
&lt;P&gt;&amp;nbsp;“Only classes inside&amp;nbsp;partially trusted assemblies that were signed with&amp;nbsp;the corresponding&amp;nbsp;private key, or any fully trusted assembly, may extend my class.”&lt;/P&gt;
&lt;P&gt;In recent versions of .NET, "full trust means full trust". That is, fully-trusted code satisfies all demands, including demands for things like "was signed with this key", whether it actually was signed or not.&lt;/P&gt;
&lt;P&gt;Isn't that a deadly flaw in the security system? No. Fully trusted code always had the ability to do that, because fully trusted code has the ability to control the evidence associated with a given assembly. If you can control the evidence,then you can forge an assembly that looks like it came from Microsoft, no problem. (And if you already have malicious full-trust code in your process then you have already lost -- it doesn't need to impersonate Microsoft-signed assemblies; it already has the power to do whatever the user can do.)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Credit where it's due:&lt;/STRONG&gt; Special thanks goes out to .NET security guru&amp;nbsp;&lt;A class="" href="http://blogs.msdn.com/shawnfa/" mce_href="http://blogs.msdn.com/shawnfa/"&gt;Shawn Farkas&lt;/A&gt; for taking the time to explain to me&amp;nbsp;the differences between various versions of the .NET security system.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Coming up:&lt;/STRONG&gt; in anticipation of the PDC later this month, over the next few postings I'll be responding vaguely and overcautiously to recent newgroup postings about proposed language features for some fictitious, hypothetical, unnannounced language called "C# 4".&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8977947" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Preventing third-party derivation, part one</title><link>http://blogs.msdn.com/ericlippert/archive/2008/09/26/preventing-third-party-derivation-part-one.aspx</link><pubDate>Fri, 26 Sep 2008 18:17:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8966641</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>27</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/8966641.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=8966641</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;In this episode of FAIC,&amp;nbsp;a conversation I had with a C# user recently. Next time, some further thoughts on how to use the CLR security system in this sort of scenario.&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;&lt;STRONG&gt;Him: I have this abstract class defined in one assembly:&lt;/STRONG&gt;&lt;/EM&gt;&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;// Assembly FooBar.DLL&lt;BR&gt;public abstract class Foo&lt;BR&gt;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal abstract void DoSomething();&lt;BR&gt;// ...&lt;BR&gt;}&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;I want to create a concrete class derived directly from &lt;SPAN class=code&gt;Foo&lt;/SPAN&gt; in another assembly, Blah.DLL.&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Me: You are going to have to learn to live with disappointment.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;Him: But I should be able to because I have public access to the class &lt;SPAN class=code&gt;Foo&lt;/SPAN&gt;!&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Me: That statement is false. Having public access to a class absolutely does not mean that it is always legal to create a subclass in another assembly. There are any number of reasons why it might not be legal to create a subclass in another assembly; you happen to have run across just one of them. (There are plenty more -- for example, you could make a public class and mark all the constructors as internal. It's not possible to subclass that from another assembly either, since the derived class constructor does not have an accessible base class&amp;nbsp;constructor that it can call.)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;Him: You're right. In this case, I can’t provide an overriding implementation for the internal abstract method &lt;SPAN class=code&gt;DoSomething()&lt;/SPAN&gt; because it is not accessible. Therefore the compiler will give an error when I try to subclass &lt;SPAN class=code&gt;Foo&lt;/SPAN&gt;. How do I get around this?&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Me: You don’t get around it. The type safety system is working as designed; don’t try to defeat it.&lt;/P&gt;
&lt;P&gt;If you own the FooBar.DLL assembly then of course there are several ways you can do what you want. Two that immediately come to mind are (1) mark Blah.DLL as a friend assembly of FooBar.DLL using the &lt;SPAN class=code&gt;InternalsVisibleTo&lt;/SPAN&gt; attribute (2) change the accessibility of &lt;SPAN class=code&gt;DoSomething&lt;/SPAN&gt; to &lt;SPAN class=code&gt;public&lt;/SPAN&gt;, &lt;SPAN class=code&gt;protected&lt;/SPAN&gt; or &lt;SPAN class=code&gt;protected internal&lt;/SPAN&gt;.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;Him: Why is it even allowed to have&amp;nbsp;a nonextensible class like this&amp;nbsp;in the first place?&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Me:&amp;nbsp;It is sometimes a good thing to make a class that cannot be extended arbitrarily. I have myself occasionally used a similar technique to ensure that no third party can subclass one of my public base classes, though, as we’ll see later, there are other, perhaps better ways.&lt;/P&gt;
&lt;P&gt;Look at it this way: if the author of the class &lt;EM&gt;wanted&lt;/EM&gt; you to be able to&amp;nbsp;subclass it, they probably would have made it &lt;EM&gt;possible.&lt;/EM&gt; Clearly they do not want you to subclass this class.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;Him: My previous question has been thoroughly begged. Why would someone want to prevent a third party from subclassing?&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Me: I can think of a few reasons. Here are two:&lt;/P&gt;
&lt;P&gt;1) Designing a class to be extended effectively by third parties is work, and work requires effort. If the class is not intended to be extended by third parties, but must be unsealed (for internal extension, for example) then the implementer is faced with a choice: spend the time/money/effort unnecessarily, provide an extensible but brittle class, or prevent extension by some other method.&lt;/P&gt;
&lt;P&gt;This trick is a cheap, easy and straightforward way to prevent extension by arbitrary third parties &lt;EM&gt;without preventing extension by internal classes&lt;/EM&gt;. As we'll see next time, there are other ways you can do this too.&lt;/P&gt;
&lt;P&gt;2) A class may need to be extensible internally and used externally, but must not be extended by third parties for security reasons. Imagine you have a method &lt;SPAN class=code&gt;Transfer&lt;/SPAN&gt; which takes two instances of your class &lt;SPAN class=code&gt;BankAccount&lt;/SPAN&gt;. Suppose &lt;SPAN class=code&gt;BankAccount&lt;/SPAN&gt; is an abstract class with two derived classes, &lt;SPAN class=code&gt;CaymanIslandsAccount&lt;/SPAN&gt; and &lt;SPAN class=code&gt;SwissAccount&lt;/SPAN&gt;. Do you really want arbitrary third parties able to make new objects which fulfill the &lt;SPAN class=code&gt;BankAccount&lt;/SPAN&gt; contract but were not implemented by you?&lt;/P&gt;
&lt;P&gt;Again, you end up with a tradeoff – either implement &lt;SPAN class=code&gt;Transfer&lt;/SPAN&gt; so that it does type checks on the &lt;SPAN class=code&gt;BankAccount&lt;/SPAN&gt; passed to it (possibly expensive both in initial implementation and maintenance), implement &lt;SPAN class=code&gt;Transfer&lt;/SPAN&gt; so that it accepts any old thing (dangerous!), or prevent anyone from making an unknown kind of &lt;SPAN class=code&gt;BankAccount&lt;/SPAN&gt; (cheap, safe).&lt;/P&gt;
&lt;P&gt;In general, good security design is “make them do something impossible in order to break the system”. (Or even better “make them do seven impossible things”.) By making it impossible for third parties to fulfill the contract, you add additional security to the system. (By no means &lt;EM&gt;enough&lt;/EM&gt; security, but a little bit &lt;EM&gt;more&lt;/EM&gt;.)&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;EM&gt;Him: Thanks, I see what's going on here. Clearly I got into this situation because this trick of using access modifiers to prevent extension is insufficient to convey the author of FooBar.DLL's intentions.&lt;/EM&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Me: Next time we'll talk about more obvious ways to state the intention of "please don't subclass this thing".&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8966641" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Dialogue/default.aspx">Dialogue</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Begging+the+question/default.aspx">Begging the question</category></item><item><title>Tasty Beverages</title><link>http://blogs.msdn.com/ericlippert/archive/2008/08/19/tasty-beverages.aspx</link><pubDate>Wed, 20 Aug 2008 00:09:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8879813</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>35</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/8879813.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=8879813</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;“&lt;EM&gt;Diet Dr. Pepper tastes more like regular Dr. Pepper.”&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;That was a previous advertising slogan for Diet Dr. Pepper, my personal favourite source of both caffeine and phenylalanine; I’m drinking it right now as I write this. &lt;/P&gt;
&lt;P&gt;The present slogan is the brain-achingly oxymoronic “&lt;EM&gt;Diet Dr. Pepper: There’s Nothing Diet About It&lt;/EM&gt;” – really?&amp;nbsp; Seems like one ought to change the name then, if the name of one’s product is so misleading as to &lt;EM&gt;require its complete and utter disavowal in the slogan&lt;/EM&gt;. &lt;/P&gt;
&lt;P&gt;But that’s not what I want to talk about today. I actually want to talk about &lt;EM&gt;predicates&lt;/EM&gt;. &lt;/P&gt;
&lt;P&gt;The word “predicate” is one of those slippery words that has multiple technical meanings depending on the domain, all related but subtly different enough that one really ought to carefully call out how one is using the term. &lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;In &lt;EM&gt;C# programming&lt;/EM&gt; a predicate is a function which takes a bunch of arguments and returns a Boolean. customer=&amp;gt;customer.Age &amp;lt; 21, for example. &lt;/LI&gt;
&lt;LI&gt;In &lt;EM&gt;mathematical logic&lt;/EM&gt;, a predicate is a function (or relation) which indicates the membership of a set. For example, “all integers x such that x is both even and prime” is a predicate for the set containing only the number 2.&lt;/LI&gt;
&lt;LI&gt;In &lt;EM&gt;English&lt;/EM&gt; &lt;EM&gt;grammar&lt;/EM&gt;, a predicate is that part of a statement which claims to represent a fact about the subject. For example, in “&lt;EM&gt;Thucydides fought in the Peloponnesian War&lt;/EM&gt;”, “&lt;A class="" href="http://blogs.msdn.com/ericlippert/archive/2004/08/18/the-attribute-of-manliness.aspx" mce_href="http://blogs.msdn.com/ericlippert/archive/2004/08/18/the-attribute-of-manliness.aspx"&gt;Thucydides&lt;/A&gt;” is the subject and the rest is the predicate. This predicate happens to be true for the subject “Thucydides”, and false for a different subject, say, “Julius Caesar”.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;What all of these things have in common is that &lt;STRONG&gt;a predicate is something into which you can "substitute" a value to obtain&amp;nbsp;a result&amp;nbsp;of either truth or falsity.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;What on earth does this have to do with Diet Dr. Pepper tasting more like regular Dr. Pepper?&lt;/P&gt;
&lt;P&gt;Is “&lt;EM&gt;tastes more like regular Dr. Pepper&lt;/EM&gt;” actually a predicate? If it is then when it is applied to a subject it must produce a statement which can be classified as true or false. Let’s leave the subjective nature of taste aside for a moment; that’s not the fundamental logical problem here. &lt;/P&gt;
&lt;P&gt;Rather, consider this utterance: “&lt;EM&gt;Diet Dr. Pepper tastes more like&lt;/EM&gt;”&amp;nbsp; Is “&lt;EM&gt;tastes more like&lt;/EM&gt;” a predicate? Of course not. That utterance doesn’t make any sense. Tastes more like… what? This utterance &lt;STRONG&gt;cannot be classified as true or false for any subject&lt;/STRONG&gt;, so the latter part of it cannot actually be a predicate.&lt;/P&gt;
&lt;P&gt;But the same thing goes for “&lt;EM&gt;tastes more like regular Dr. Pepper&lt;/EM&gt;”!&amp;nbsp; Tastes more like regular Dr. Pepper… than what?&lt;/P&gt;
&lt;P&gt;In order to actually be a predicate it needs more objects. For example, “&lt;EM&gt;Diet Dr. Pepper tastes more like regular Dr. Pepper than a pint of Guinness tastes like a mango lassi&lt;/EM&gt;” is a statement which actually has a truth value.&amp;nbsp;Perhaps a subjective and&amp;nbsp;arguable truth value, but at least this sentence has the form of a statement with a subject and a real predicate now. The original slogan’s “predicate” isn’t really a predicate at all; one might think of it as a &lt;STRONG&gt;pseudopredicate&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;Advertisers &lt;EM&gt;love&lt;/EM&gt; pseudopredicates. Once you realize that they exist you see them all the time. Advertisers love them because they make no testable claim which could be shown to be false in a court of law. Rather, they rely on either the irrational belief that “more” anything means “better”, or upon your brain’s ability to fill in the rest of the objects which they intend you to infer.&lt;/P&gt;
&lt;P&gt;In this particular case, I imagine that the crafters of this slogan intended your brain to fill in “&lt;EM&gt;Diet Dr. Pepper tastes more like regular Dr. Pepper than our previous formulation of Diet Dr. Pepper tasted like regular Dr. Pepper&lt;/EM&gt;” – that is, they want to make the claim that the product has improved without making the admission that the previous formulation was less than delicious. &lt;/P&gt;
&lt;P&gt;Or, perhaps they want you to fill in “&lt;EM&gt;Diet Dr. Pepper tastes more like regular Dr. Pepper than Diet Coke tastes like regular Coke&lt;/EM&gt;” – that is, they want to assert that their product is superior to a competing product. This assertion is in my personal opinion true, but the Coca Cola company could potentially take issue with if stated baldly as an objective claim. By relying upon a pseudopredicate to make a slogan which actually is so malformed as to have no truth value at all, the copywriters duck these thorny issues. There are lots of ways that clever advertisers leverage our tendancies to "fill in the blanks" in order to sell products.&lt;/P&gt;
&lt;P&gt;That’s not actually what I want to talk about today either.&amp;nbsp;&amp;nbsp;I &lt;EM&gt;actually&lt;/EM&gt; want to talk about &lt;EM&gt;writing secure code&lt;/EM&gt;.&lt;/P&gt;
&lt;P&gt;What on earth does Diet Dr. Pepper tasting more like regular Dr. Pepper have to do with writing secure code?&lt;/P&gt;
&lt;P&gt;The other day I got a question about the characteristics of a particular bit of source code obfuscation technology, which we shall call X; what the technology actually consists of and what the precise question was&amp;nbsp;are irrelevant to this discussion. &lt;/P&gt;
&lt;P&gt;I answered the question with a question; I asked why it was that the questioner wanted to use technology X. The answer was “&lt;EM&gt;To protect the source code&lt;/EM&gt;”. Leave aside for the moment the fact that I could probably have deduced from the original query that the questioner was interested in protecting some resource. There’s a deeper problem here. In the utterance “&lt;EM&gt;technology X protects the source code&lt;/EM&gt;”, is “&lt;EM&gt;protects the source code&lt;/EM&gt;” a predicate, or a pseudopredicate?&lt;/P&gt;
&lt;P&gt;It’s a pseudopredicate. There is an object missing. To make this a predicate, it needs to be something like “&lt;EM&gt;protects the source code from casual inspection and editing by snoopy people&lt;/EM&gt;” – as it happens, this predicate was true for technology X. What I was rather worried about was that the questioner actually had in his head the predicate “&lt;EM&gt;protects the database administrator password that I’ve stuck into my source code from discovery and misuse by a determined and intelligent attacker&lt;/EM&gt;”. That predicate happens to be utterly false for technology X. Because he was&amp;nbsp;not actually stating a predicate that&amp;nbsp;could be true or false of X&amp;nbsp;I was unable to answer the guy's question about X.&lt;/P&gt;
&lt;P&gt;I never, ever lock my car doors anymore. Why?&amp;nbsp;I drive a soft-top convertible.&amp;nbsp;One day I woke up to discover that someone had sliced open the top and unlocked the car. The two bucks in quarters I keep in the car for parking meters was a trivial loss compared to the hundreds my insurance company paid to get the top replaced and the hours of my time wasted in dealing with the situation. The locks are not a mitigation to that vulnerability at all! Locking my car doors makes it &lt;EM&gt;more&lt;/EM&gt;&amp;nbsp;prone to be damaged, not less.&lt;/P&gt;
&lt;P&gt;I do, however, lock my house, to protect it against random people wandering in. However, the locks are hardly any mitigation to the vulnerability of the house to determined attack from a wily, hostile burglar. It would be foolish of me to say that “&lt;EM&gt;the locks protect my house&lt;/EM&gt;” without mentioning the &lt;STRONG&gt;threat&lt;/STRONG&gt;. &lt;/P&gt;
&lt;P&gt;What I’m rambling on about here is this: the fitness of a particular security technology to &lt;STRONG&gt;mitigate a vulnerability&lt;/STRONG&gt; can only be evaluated in the context of a &lt;STRONG&gt;stated threat&lt;/STRONG&gt; against a &lt;STRONG&gt;stated resource&lt;/STRONG&gt;. That’s because &lt;STRONG&gt;every security technology is designed to mitigate specific vulnerabilities to particular threats&lt;/STRONG&gt;. When you’re evaluating the benefit of a particular security system, make sure that the predicates you are using to talk about the system are actually predicates, not pseudopredicates; &lt;STRONG&gt;state the threats&lt;/STRONG&gt;.&lt;BR&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8879813" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Rants/default.aspx">Rants</category></item><item><title>Protected Member Access, Part Four</title><link>http://blogs.msdn.com/ericlippert/archive/2008/05/02/protected-member-access-part-four.aspx</link><pubDate>Fri, 02 May 2008 19:13:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8450993</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/8450993.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=8450993</wfw:commentRss><description>&lt;div class="mine"&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;In &lt;a href="http://blogs.msdn.com/ericlippert/archive/2008/03/28/why-can-t-i-access-a-protected-member-from-a-derived-class-part-two-why-can-i.aspx"&gt;Part Two&lt;/a&gt; I asked a couple of follow-up questions, the first of which was:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;&lt;font color="#8080ff"&gt;Suppose you were a hostile third party and you wanted to mess up the parenting invariant. Clearly, if you are sufficiently trusted, you can always use private reflection or unsafe code to muck around with the state directly, so that's not a very interesting attack. Any other bright ideas come to mind for ways that this code is vulnerable to tampering?&lt;/font&gt;&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Before I get into some ideas for attacks, I want to re-emphasize the bit in the middle there: &lt;strong&gt;attacks which presuppose that the attacker is already an administrator on your machine are not interesting attacks&lt;/strong&gt;. A number of people came up with attacks involving the attacker being able to run debuggers or even replace the entire CLR with a custom-built runtime.&lt;/p&gt; &lt;p&gt;Since there is no point in protecting code from hostile code which is &lt;em&gt;already stronger than the security system itself&lt;/em&gt;, it's not very interesting to consider such attacks. The interesting question is how to protect yourself against hostile code which is &lt;em&gt;weaker&lt;/em&gt; than the code you are attempting to protect. That's what attackers want to do -- they want to leverage vulnerabilities in your strong code to turn their weak code into strong code. If they already have strong code, they don't need to lure your code into doing something, they can just do it directly.&lt;/p&gt; &lt;p&gt;Anyway, that said, there are a number of flaws in my proposed implementation from a security perspective: &lt;/p&gt; &lt;ul&gt; &lt;li&gt;Eamon Nerbonne pointed out the implementation is not in the slightest thread-safe; hostile code which wished to mess up the parenting invariant could run adds and removes on the same objects on multiple threads at once, and when the smoke clears, pretty much any weird parenting arrangement you care to name could be the case.  &lt;li&gt;Matt pointed out that the implementation relies upon a correct implementation of hashing/equality. If a hostile or buggy object provides an implementation of hashing which is inconsistent with its implementation of equality, it is possible to put stuff into a hash set and never get it back out again. The parenting invariant in this implementation relies upon being able to use hash sets correctly.  &lt;li&gt;Jon Skeet pointed out that the implementation has no protections against parenting relationships which are locally sensible but not globally sensible, like a box containing itself.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;All of these vulnerabilities could of course be mitigated without too much difficulty; the trick is in remembering to look for the vulnerability in the first place!&lt;/p&gt; &lt;p&gt;Getting the parenting relationship consistently acyclic is an interesting algorithmic problem. There are numerous ways to do it. Two sketches for your consideration:&lt;/p&gt; &lt;p&gt;1) Every time you add an item to a container, search the parent list of the container for the item. Hopefully containment relationships are shallow and this is not too expensive.&amp;nbsp; &lt;/p&gt; &lt;p&gt;2) Only allow adding an item to a container if the item and the container are different but are themselves in the same immediate container. If you have a box in a bag, and you want to put a ball in the box, first put it in the bag, and then in the box.&amp;nbsp; &lt;/p&gt; &lt;p&gt; Next time, some thoughts on immutability and parenting relationships.&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8450993" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Why Can't I Access A Protected Member From A Derived Class, Part Two: Why Can I?</title><link>http://blogs.msdn.com/ericlippert/archive/2008/03/28/why-can-t-i-access-a-protected-member-from-a-derived-class-part-two-why-can-i.aspx</link><pubDate>Sat, 29 Mar 2008 02:30:43 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:8342569</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>36</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/8342569.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=8342569</wfw:commentRss><description>&lt;div class="mine"&gt; &lt;p&gt;This is a follow-up to &lt;a href="http://blogs.msdn.com/ericlippert/archive/2005/11/09/491031.aspx"&gt;my 2005 post on the same subject&lt;/a&gt;&amp;nbsp; which I believe sets a personal record for the longest time between parts of a series. (Of course, I didn't know it was a series when I started it.) Please read the previous article in this series, as this post assumes knowledge of part one.&lt;/p&gt; &lt;p&gt;.......&lt;/p&gt; &lt;p&gt;OK, now that you've read that, it's clear why you can only access a protected member from an instance of an object known to be of a type at least as derived as the current context. You can therefore deduce the answer to the question asked to me by a (very polite) reader this morning: &lt;strong&gt;Why did this code compile in C# 2.0 but give an error in C# 3.0?&lt;/strong&gt;&lt;/p&gt;&lt;span class="code"&gt; &lt;p&gt;public abstract class Item{&lt;br&gt;&amp;nbsp; private Item _parent;&lt;br&gt;&amp;nbsp; public Item Parent { &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; get { return _parent; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected set { _parent = value; }&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;public class Bag:Item{&lt;br&gt;&amp;nbsp; private List&amp;lt;Item&amp;gt; list = new List&amp;lt;Item&amp;gt;();&lt;br&gt;&amp;nbsp; public void Add(Item item)&lt;br&gt;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; item.Parent = this; // Error in C# 3.0&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; list.Add(item);&amp;nbsp; &lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;public class Torch : Item { }&lt;/p&gt;&lt;/span&gt; &lt;p&gt;It compiled in C# 2.0 because the compiler had a bug. We forgot to enforce the semantics of "protected" access for the property setter. Though the compiler did not generate an error, it did generate code which would not pass the CLR verification check! The code would run if it happened to be fully trusted, but it was not safe to do so. We fixed the bug in C# 3.0 and took the breaking change.&lt;/p&gt; &lt;p&gt;This raises a more interesting point though. Now that we correctly prevent you from setting the "parent" reference in this manner, how would you implement the desired pattern? The reader wanted the following conditions to be met:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;There are two kinds of items -- "leaf" items, and "container" items. Container items may contain either kind of item, so you could have a box containing a bag, which in turn contains a torch.  &lt;li&gt;An item may be in a container, and if it is, its parent reference refers to that container.  &lt;li&gt;These classes must be extensible by arbitrary third parties.  &lt;li&gt;"Unauthorized" code must not be able to muck around with the parenting invariants.&amp;nbsp; &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;The reader was attempting to enforce these invariants by making the parent setter protected. But even in a world where it is legal to access a protected member from an arbitrary derived class, that does not ensure that the invariants are maintained! If you allow any derived class to muck with the parenting, then you are relying upon every third-party derived class to "play nicely" and maintain your invariant. If any of them are buggy or hostile, then who knows what can happen?&lt;/p&gt; &lt;p&gt;When I'm faced with this kind of problem, I try to go back to first principles. Considering each design constraint leads us to an implementation decision which implements that constraint:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;There are two kinds of abstract items -- items and containers. Therefore, there should be two abstract base classes, not just one.  &lt;li&gt;Containers are items. Therefore, the container class should derive from the item class.  &lt;li&gt;The parenting invariant must be maintained across all containers. Therefore the invariant implementation must be inside the abstract container base class.  &lt;li&gt;Every possible container requires "write" access to the parent state of every possible Item.&amp;nbsp; We want that access to be as restricted as possible. Ideally, we want it to be private. &lt;em&gt;The only by-design way to get access to a private is to be inside the class&lt;/em&gt;. &lt;/li&gt;&lt;/ul&gt; &lt;p&gt;And now a full solution becomes very straightforward:&lt;/p&gt;&lt;span class="code"&gt; &lt;p&gt;using System;&lt;br&gt;using System.Collections.Generic;&lt;br&gt;&lt;br&gt;public abstract class Item {&lt;br&gt;&amp;nbsp; public Item Parent { get; private set; }&lt;br&gt;&amp;nbsp; public abstract class Container : Item {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; private HashSet&amp;lt;Item&amp;gt; items = new HashSet&amp;lt;Item&amp;gt;();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Add(Item item) {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (item.Parent != null)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception("Item has inconsistent containment.");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; item.Parent = this;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; items.Add(item);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void Remove(Item item) {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (!Contains(item))&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new Exception("Container does not contain that item.");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; items.Remove(item);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; item.Parent = null;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public bool Contains(Item item) {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return items.Contains(item);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public IEnumerable&amp;lt;Item&amp;gt; Items {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Do not just return items. Then the caller could cast it&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // to HashSet&amp;lt;Item&amp;gt; and then make modifications to your&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // internal state! Return a read-only sequence:&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach(Item item in items) yield return item;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp; }&lt;br&gt;}  &lt;p&gt;// These can be in third-party assemblies:&lt;br&gt;&lt;br&gt;public class Bag : Item.Container { }&lt;br&gt;public class Box : Item.Container { }&lt;br&gt;public class Torch : Item { }&lt;br&gt;public class TreasureMap : Item { }&lt;br&gt;&lt;br&gt;public class Program {&lt;br&gt;&amp;nbsp; public static void Main() {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var map = new TreasureMap();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var box = new Box();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; box.Add(map);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; var bag = new Bag();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; bag.Add(box);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach(Item item in bag.Items) &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(item);&lt;br&gt;&amp;nbsp; }&lt;br&gt;}&lt;/p&gt;&lt;/span&gt; &lt;p&gt;Pretty slick eh?&lt;/p&gt; &lt;p&gt;A couple questions for you to ponder:&lt;/p&gt; &lt;p&gt;1) Suppose you were a hostile third party and you wanted to mess up the parenting invariant. Clearly, if you are sufficiently trusted, you can always use private reflection or unsafe code to muck around with the state directly, so that's not a very interesting attack. Any other bright ideas come to mind for ways that this code is vulnerable to tampering?&lt;/p&gt; &lt;p&gt;2) Suppose you wanted to make this hierarchy an immutable collection, where "Add" and "Remove" returned new collections rather than mutating the existing collection. How would you represent the parenting relationship?&lt;/p&gt; &lt;p&gt;Next time, another oddity involving "protected" semantics. Have a good weekend! &lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/div&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=8342569" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category></item><item><title>How do I mitigate a SQL injection vuln?</title><link>http://blogs.msdn.com/ericlippert/archive/2006/11/01/how-do-i-mitigate-a-sql-injection-vuln.aspx</link><pubDate>Wed, 01 Nov 2006 23:32:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:926955</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>22</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/926955.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=926955</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Joel &lt;A href="http://www.joelonsoftware.com/items/2006/11/01.html" mce_href="http://www.joelonsoftware.com/items/2006/11/01.html"&gt;points out today&lt;/A&gt; that SQL injection vulnerabilities are common and bad, bad, bad. He does a good job of describing the attack but doesn't really talk about how to mitigate it. &lt;/P&gt;
&lt;P&gt;When I advise people on how to close security holes like this I always tell them that &lt;STRONG&gt;closing the original hole is probably not enough&lt;/STRONG&gt;. You don't want to make the attackers do one "impossible" thing because you just might be mistaken about what is actually impossible. &lt;STRONG&gt;Make them do three or four impossible things&lt;/STRONG&gt;, and odds are good that it really&amp;nbsp;will be&amp;nbsp;impossible to cause harm. &lt;/P&gt;
&lt;P&gt;To start with, &lt;STRONG&gt;run all strings that come from users through a string checker&lt;/STRONG&gt; looking for anything out of the ordinary. If you expect a string to contain only letters, numbers and spaces, then write a regular expression that verifies that and get in the habit of rejecting all input that doesn't conform. That should make it impossible for attackers to put special characters like quotation marks in there. &lt;/P&gt;
&lt;P&gt;Assume that a clever attacker will subvert that. &lt;STRONG&gt;Assume that you've made a mistake&lt;/STRONG&gt; and forgotten to put a check in somewhere. Look for every&amp;nbsp;place in the code that uses that user-supplied string. Don't stop at SQL construction. Anything that gets passed to JScript's &lt;STRONG&gt;eval&lt;/STRONG&gt; could be an injection attack. &lt;STRONG&gt;Anything that gets echoed back to the user could be a cross-site scripting attack&lt;/STRONG&gt;. Anything that gets &lt;STRONG&gt;written to disk&lt;/STRONG&gt; could be an attempt to write a script onto the server's disk to trick an admin into running it. Eliminate as many of these as you can. &lt;/P&gt;
&lt;P&gt;But how do you eliminate them? A great way to mitigate the risk of a SQL injection attack is to &lt;STRONG&gt;use stored procedures&lt;/STRONG&gt;. Stored procedures ensure that only the query that you want to run actually runs. But they have nice properties in addition to being more secure against injection. They can be updated in the database, so that when the database structure changes, you change the stored procedure rather than searching through your code for SQL statement construction. And stored procedures often run faster because the database can optimize itself for them. &lt;/P&gt;
&lt;P&gt;How else can we make it impossible for an attacker to run Joel's proposed attack? The attack Joel describes deletes stuff from the database, which is pretty unsubtle. A more subtle attack would consist of an update query which ups the user's available credit, or changes the prices of products, or some such thing. The database code should make use of the &lt;STRONG&gt;principle of least privilege&lt;/STRONG&gt;. If you only expect it to look up results from particular database tables, then create a database account that only has those permissions, and then use that account from the server code. &lt;STRONG&gt;Don't connect to the database as admin if you don't need admin privileges&lt;/STRONG&gt;; that's just asking for someone to abuse those privileges. &lt;/P&gt;
&lt;P&gt;Furthermore, &lt;STRONG&gt;don't keep&amp;nbsp;secrets in source code.&lt;/STRONG&gt; For instance, put the name of the database server, the name of the database account, and the password&amp;nbsp;in a registry key or an ACL'd file. Assume that attackers will obtain your source code. Keep machine names, employee names,&amp;nbsp;&lt;STRONG&gt;keep&amp;nbsp;anything sensitive that an attacker could use out of the source code. &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;How did Joel find out that the server was vulnerable at all? When the server helpfully told him that there was malformed SQL, and furthermore, what part of it was. Not only is this potentially a cross-site scripting attack (because user-supplied data is echoed back) but it is like waving a big sign explaining exactly how to construct an attack! Detailed error messages that describe the internal state of the server should only be given to users who have been authenticated by the server and are known to be server developers. &lt;STRONG&gt;Ordinary users should get a generic "something bad happened" error that explains nothing. &lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;For Joel's proposed attack to succeed, &lt;EM&gt;everything&lt;/EM&gt; has to go wrong. The server has to fail to validate input, then use it in an insecure way, then connect to the database as an administrator. Regrettably, many server-side web apps leave themselves wide open to these sorts of attacks.&amp;nbsp;&lt;STRONG&gt;Eliminate all of these problems&lt;/STRONG&gt;, not just the string concatenation.&amp;nbsp;Remember, think like an evil person, assume the worst, and make evildoers jump through as many hoops as you possibly can. Defense in depth! &lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=926955" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category></item><item><title>Why are base class calls from anonymous delegates nonverifiable?</title><link>http://blogs.msdn.com/ericlippert/archive/2005/11/14/why-are-base-class-calls-from-anonymous-delegates-nonverifiable.aspx</link><pubDate>Mon, 14 Nov 2005 22:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:492607</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>17</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/492607.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=492607</wfw:commentRss><description>&lt;FONT face="Lucida Sans Unicode" color=purple size=2&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;I'm still learning my way around the C# codebase – heck, I'm still learning my way around the Jscript codebase and I've been working on it for nine years, not nine weeks. Here's something I stumbled across while refactoring the anonymous method binding code last week that I thought might be interesting to you folks.&lt;/P&gt;
&lt;P&gt;Consider this simple program:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;
&lt;P&gt;using System;&lt;BR&gt;public delegate void D ();&lt;BR&gt;public class Alpha {&lt;BR&gt;&amp;nbsp; public virtual void Blah()&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Alpha.Blah");&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;BR&gt;public class Bravo : Alpha {&lt;BR&gt;&amp;nbsp; public override void Blah() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Bravo.Blah");&lt;BR&gt;&lt;FONT color=#ff0000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base.Blah();&lt;/FONT&gt;&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;Pretty straightforward so far. Any &lt;STRONG&gt;virtual&lt;/STRONG&gt; call to &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;Blah&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; on an instance of &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;Bravo&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; does a &lt;STRONG&gt;non-virtual&lt;/STRONG&gt; call to the base class implementation. Now let's do a similar thing from an anonymous delegate in &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;Bravo&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#000080 size=2&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;
&lt;P&gt;&amp;nbsp; public void Charlie()&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int x = 123;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = delegate&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; base.Blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(x);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;When you compile this thing up you get a crazy-sounding warning:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;
&lt;P&gt;warning CS1911: Access to member 'Alpha.Blah()' through a 'base' keyword from an anonymous method or iterator results in unverifiable code. Consider moving the access into a helper method on the containing type.&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;And indeed, if you compile this up and run it through PEVERIFY.EXE, sure enough you'll get an unverifiable code warning. Unverifiable code requires full trust and is generally to be avoided – what is going on here?&lt;/P&gt;
&lt;P&gt;This is an artefact of the way that C# realizes anonymous delegates. The anonymous delegate above captures both &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;this&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; and &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;x&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;, and therefore we actually generate code that would look something like this if you decompiled it:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;
&lt;P&gt;public class Bravo : Alpha {&lt;BR&gt;&amp;nbsp; public override void Blah() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine("Bravo.Blah");&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;base.Blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp; private class __locals {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int __x;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public Bravo __this;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public void __method() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.__this.blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#ff0000 size=2&gt;__nonvirtual__&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt; ((Alpha)this.__this).Blah());&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(this.__x);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;BR&gt;&amp;nbsp; public void Charlie() {&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; __locals locals = new __locals();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; locals.__x = 123;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; locals.__this = this;&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = new D(locals.__method);&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; d();&lt;BR&gt;&amp;nbsp; }&lt;BR&gt;}&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;Of course there is no such thing in C# as &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;__nonvirtual__&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;, so really there is no way to decompile this thing back into real C#.&amp;nbsp; Which is exactly the problem! What's happening here is that we are doing a non-virtual call on a &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;this&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; reference which is not the "real" &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;this&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; reference of the call.&lt;/P&gt;
&lt;P&gt;That's a pretty suspicious programming practice.&amp;nbsp; People who build object hierarchies that manipulate sensitive information have a reasonable expectation that the &lt;I&gt;only&lt;/I&gt; way to call a base class implementation of a virtual method is from the derived class itself, not from some third-party method.&amp;nbsp; Therefore the CLR treats this as unverifiable code, and therefore we have to issue a warning. (I suppose the CLR team could have made an exception for nonvirtual references from classes scoped to within the class in question, or for that matter, classes from the same assembly, but they didn't.)&lt;/P&gt;
&lt;P&gt;Now, I was refactoring the code that generates the captured variable class, and so of course I wanted to write a few additional unit tests to make sure that I wasn't breaking anything. When I ran into this warning the first unit test that I wrote was actually a somewhat simplified version of the above:&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;
&lt;P&gt;&amp;nbsp; public void Charlie()&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; D d = delegate&amp;nbsp;{&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; base.Blah();&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;d();&lt;BR&gt;&amp;nbsp;&amp;nbsp;}&lt;/P&gt;&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;
&lt;P&gt;This issues the warning above, but when I ran the generated executable through PEVERIFY I was surprised to discover that it verified just fine.&lt;/P&gt;
&lt;P&gt;As it turns out, the compiler is clever about this one. It sees that the only captured variable is the &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;this&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; reference, and therefore it can optimize away the locals class.&amp;nbsp; For this case it simply generates the anonymous method as just another method on the &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;Bravo&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; class. Since this is a method of &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;Bravo&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt;, not a special locals class, the nonvirtual call is on the real &lt;/FONT&gt;&lt;FONT face="Lucida Console" color=#000080 size=2&gt;this&lt;/FONT&gt;&lt;FONT face="Lucida Sans Unicode" color=#800080 size=2&gt; reference, so it is verifiable.&lt;/P&gt;
&lt;P&gt;We decided to issue the warning even in this case because we thought that it would make C# seem really weird and brittle to suddenly start issuing the warning when you add an additional outer local variable reference to the anonymous delegate. &lt;B&gt;Even when this doesn't actually generate nonverifiable code, it's a good idea to get in the habit of creating a helper method on the real class that does the nonvirtual access.&lt;/P&gt;&lt;/B&gt;
&lt;P&gt;Of course, all of the stuff above is implementation details. &lt;B&gt;You cannot rely upon future versions of C# to continue to generate anonymous methods in this manner.&lt;/B&gt; We probably will, but who knows what new features will be added to the CLR that might make it possible to not generate a bunch of hidden classes behind the scenes to do this work? Please do not attempt to do anything silly like reflecting upon the class to discover the hidden nested classes and use them; you're just asking for future pain if you do.&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=492607" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Lambda+Expressions/default.aspx">Lambda Expressions</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Code+Generation/default.aspx">Code Generation</category></item><item><title>Do not use string hashes for security purposes</title><link>http://blogs.msdn.com/ericlippert/archive/2005/10/24/do-not-use-string-hashes-for-security-purposes.aspx</link><pubDate>Mon, 24 Oct 2005 17:00:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:482447</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>12</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/482447.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=482447</wfw:commentRss><description>&lt;FONT face="lucida sans unicode" size=2&gt;&lt;FONT color=#800080 size=2&gt;
&lt;P&gt;A recent question I got about the .NET CLR's hashing algorithm for strings is apropos of our discussion from January on using salted hashes for security purposes. (If you missed it, you can read it here: &lt;/FONT&gt;&lt;a href="http://blogs.msdn.com/ericlippert/archive/2005/01/28/362587.aspx"&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;Part One&lt;/U&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT color=#800080 size=2&gt;, &lt;/FONT&gt;&lt;a href="http://blogs.msdn.com/ericlippert/archive/2005/01/31/363844.aspx"&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;Part Two&lt;/U&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT color=#800080 size=2&gt;, &lt;/FONT&gt;&lt;a href="http://blogs.msdn.com/ericlippert/archive/2005/02/03/366274.aspx"&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;Part Three&lt;/U&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT color=#800080 size=2&gt; and &lt;/FONT&gt;&lt;a href="http://blogs.msdn.com/ericlippert/archive/2005/02/07/368569.aspx"&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;Part Four&lt;/U&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT color=#800080 size=2&gt;).&amp;nbsp; The question was basically "my database of password hashes doesn't seem to work with .NET v2.0, what's up with that?"&lt;/P&gt;
&lt;P&gt;To make a long story short, the answer is &lt;B&gt;UNDER NO CIRCUMSTANCES SHOULD YOU USE THE .NET STRING HASH ALGORITHM (that is, String.GetHashCode()) FOR SECURITY PURPOSES. That is not what it was designed for. If it hurts when you do that then stop doing it!&lt;/P&gt;&lt;/B&gt;
&lt;P&gt;The slightly longer version goes like this. Suppose you want to store some secrets in a database, but you only need to be able to confirm that the user knows the secret. As I discussed in my series on salted hashes, a hash is a commonly used tool for this task because a cryptographic hash has some nice properties. Namely, it is a&amp;nbsp;fixed number of bits (in the 100's of bits range), small changes to input produce huge changes in output, and it is very difficult to go from the hash back to the original secret. Another nice property that I didn't call out in my earlier article is that there are industry-standard hash algorithms where you can be reasonably guaranteed that any two implementations will produce the same results when given the same set of bits. &lt;/P&gt;
&lt;P&gt;The .NET CLR string hash algorithm has none of these nice properties, and therefore is completely unsuitable for a cryptographic hash function. Specifically:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;The string hash algorithm was designed to be blindingly fast rather than hard to run backwards, so it is likely that a mathematically astute attacker will be able to rapidly deduce facts about the input knowing only the hash. 
&lt;LI&gt;Worse, being only 32 bits, using brute force to find a message that produces a given hash becomes doable in an afternoon with a PC rather than a trillion years. 
&lt;LI&gt;Finally, the string hash algorithm is not an industry standard and is &lt;/FONT&gt;&lt;A href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemstringclassgethashcodetopic.asp"&gt;&lt;U&gt;&lt;FONT color=#0000ff size=2&gt;not guaranteed to produce the same behaviour between versions&lt;/U&gt;&lt;/FONT&gt;&lt;/A&gt;&lt;FONT color=#800080 size=2&gt;. And in fact it does not. The .NET 2.0 CLR uses a different algorithm for string hashing than the .NET 1.1 CLR. If you are saving .NET 1.1 CLR&amp;nbsp;hash values in a database then&amp;nbsp;you will not be able to match them&amp;nbsp;when you upgrade to 2.0. &lt;/FONT&gt;&lt;FONT color=#800080 size=2&gt;The hash algorithm was specifically NOT designed to be forward/backward compatible and we called that out in the documentation because we knew that it probably would not be. Unlike last week, I have no problem whatsoever with making breaking changes when we call out in the documentation that you cannot rely on version-to-version identical output for a function.&lt;/FONT&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;FONT color=#800080 size=2&gt;So please don't do that; you're just asking for a world of hurt if you do. Use SHA1 or MD5 or some other algorithm designed for that purpose. (Yes, I know that weaknesses have been discovered in these algorithms, but they are still orders of magnitude better than a hash designed for hash table balancing!)&lt;/P&gt;&lt;/FONT&gt;&lt;/FONT&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=482447" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Breaking+Changes/default.aspx">Breaking Changes</category></item><item><title>How To Obtain The Name Of The Client From The ASP Server</title><link>http://blogs.msdn.com/ericlippert/archive/2005/05/09/how-to-obtain-the-name-of-the-client-from-the-asp-server.aspx</link><pubDate>Mon, 09 May 2005 22:18:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:415763</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/415763.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=415763</wfw:commentRss><description>&lt;DIV class=mine&gt;
&lt;P&gt;Here's a question about client side vs. server side scripting that I got recently:&lt;/P&gt;
&lt;P&gt;&lt;EM&gt;I want to get the machine name of the client the request is being made from. With ASP I can get the IP address using this code: &lt;SPAN class=code&gt;ipaddr = Request.ServerVariables("REMOTE_ADDR") &lt;/SPAN&gt;But I don’t know how to get the name of the machine. Is there something I could do from the client side?&lt;/EM&gt;&lt;/P&gt;
&lt;P&gt;No, the web browser client cannot determine the name of the machine for two reasons.&lt;/P&gt;
&lt;P&gt;First, &lt;STRONG&gt;if it could then the client could be instructed to send the name of the machine to an evil server&lt;/STRONG&gt;. Evil hackers would love to have an &lt;I&gt;internet&lt;/I&gt; web page that harvested &lt;I&gt;intranet&lt;/I&gt; machine names that they could then attack. Knowing the name of a machine is particularly useful for social engineering attacks -- if someone phoned me up claiming to be from our IT department, I'd be a lot more inclined to believe them if they knew the names of all my machines.&lt;/P&gt;
&lt;P&gt;Second,&amp;nbsp;look at it from the other way.&amp;nbsp; Suppose the client magically figures out its name and sends it to the server.&amp;nbsp; &lt;I&gt;Why should the server trust the client?&lt;/I&gt; &amp;nbsp;What stops an evil client from sending a bogus name to the server? Even if the client could send the name, the server can't make any decisions based on that name, so it's kind of useless.&lt;/P&gt;
&lt;P&gt;Clients and servers should not trust each other.&amp;nbsp; In the absence of authentication evidence, clients must assume that all servers&amp;nbsp;are run by evil hackers and servers must assume that all clients are run by evil hackers.&amp;nbsp; Once you accept that fundamental design principle then it becomes much easier to reason about client-server interactions.&amp;nbsp;Think like an evil person!&lt;/P&gt;
&lt;P&gt;Another developer who saw this question suggested running this code on the server:&lt;/P&gt;&lt;SPAN class=code&gt;
&lt;P&gt;name = Request.ServerVariables("REMOTE_HOST")&lt;/P&gt;&lt;/SPAN&gt;
&lt;P&gt;That's a good start but not the whole story. By default this doesn't actually give you the remote host -- it just gives you the IP address again. If you want this to actually give you the name of the remote machine then&amp;nbsp;there's some additional work you have to do. Since we have the IP address then we can do a reverse DNS lookup to see if there is a friendly name associated with that address. Now the server is trusting not&amp;nbsp;an&amp;nbsp;arbitrarty&amp;nbsp;client but rather&amp;nbsp;a specific reverse DNS server.&lt;/P&gt;
&lt;P&gt;Read this Knowledge Base article on how to configure your server to automatically do Reverse DNS lookups when the code above is called.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q245574" mce_href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q245574"&gt;http://support.microsoft.com/default.aspx?scid=kb;en-us;Q245574&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Note that this will make your server performance worse, and of course is not guaranteed to work if the client machine is disguising its identity via a firewall, etc.&lt;/P&gt;&lt;/DIV&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=415763" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Scripting/default.aspx">Scripting</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Performance/default.aspx">Performance</category></item><item><title>A Face Made For Email, Part Two</title><link>http://blogs.msdn.com/ericlippert/archive/2005/04/01/a-face-made-for-email-part-two.aspx</link><pubDate>Fri, 01 Apr 2005 16:45:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:404642</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/404642.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=404642</wfw:commentRss><description>&lt;font face="lucida sans unicode"&gt;&lt;font color="#800080" size="2"&gt; &lt;p&gt;&lt;A href="http://blogs.msdn.com/ericlippert/archive/2004/04/06/108652.aspx"&gt;One year ago this week &lt;/a&gt;I was the &lt;/font&gt;&lt;a href="http://channel9.msdn.com/"&gt;&lt;u&gt;&lt;font color="#0000ff" size="2"&gt;Channel Nine&lt;/u&gt;&lt;/font&gt;&lt;/a&gt;&lt;font color="#800080" size="2"&gt; guinea pig -- I'm still not sure why, but for some reason &lt;/font&gt;&lt;a href="http://scoble.weblogs.com/"&gt;&lt;u&gt;&lt;font color="#0000ff" size="2"&gt;The Scobelizer&lt;/u&gt;&lt;/font&gt;&lt;/a&gt;&lt;font color="#800080" size="2"&gt; and his cohort chose me to be the first guy interviewed for their project. (Probably because I'm mostly harmless.)&lt;/p&gt; &lt;p&gt;Channel Nine has succeeded tremendously, and I'm very pleased to have been a part of it at its birth. Recently Charles and Robert tracked me down and cornered me in a room with a &lt;strong&gt;really big&lt;/strong&gt; XBOX screen to talk about Visual Studio Tools For Office and how we use .NET code access security. &lt;/p&gt; &lt;p&gt;If you've got 53 minutes to kill and you want to hear me ramble on about what I love to talk about most, &lt;/font&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=53466"&gt;&lt;u&gt;&lt;font color="#0000ff" size="2"&gt;check it out&lt;/u&gt;&lt;/font&gt;&lt;/a&gt;&lt;font color="#800080" size="2"&gt;.&lt;/font&gt;&lt;font color="#800080" size="2"&gt;&lt;/p&gt;&lt;/font&gt;&lt;/font&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=404642" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/VSTO/default.aspx">VSTO</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Video/default.aspx">Video</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Channel+9/default.aspx">Channel 9</category></item><item><title>You Want Salt With That? Part Four: Challenge-Response</title><link>http://blogs.msdn.com/ericlippert/archive/2005/02/07/you-want-salt-with-that-part-four-challenge-response.aspx</link><pubDate>Mon, 07 Feb 2005 18:28:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:368569</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>21</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/368569.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=368569</wfw:commentRss><description>&lt;font face="Lucida Sans Unicode"&gt;&lt;font color="#800080" size="2"&gt; &lt;p&gt;My friend Kristen asked me over the weekend when I was going to stop blogging about crypto math and say something funny again.&amp;nbsp;Everyone's a critic!&lt;/p&gt; &lt;p&gt;Patience. my dear. Today, the final entry in my series on salt. Tomorrow, who knows?&lt;/p&gt; &lt;p&gt;***********************&lt;/p&gt; &lt;p&gt;So far we've got a system whereby the server does not actually know what your password is, it just has a salted hash of your password. But we're still sending the password over the wire in clear text, which seems risky.&lt;/p&gt;&lt;/font&gt;&lt;b&gt;&lt;font color="#333399" size="2"&gt; &lt;p&gt;System #4&lt;/p&gt;&lt;/b&gt;&lt;/font&gt;&lt;font color="#800080" size="2"&gt; &lt;p&gt;What if the&lt;/font&gt;&lt;i&gt;&lt;font face="Times New Roman"&gt; &lt;/font&gt;&lt;font color="#800080" size="2"&gt;hash&lt;/i&gt; goes over the wire?&amp;nbsp; The client sends the user name to the server. The server sends the password salt to the client.&amp;nbsp; The client appends the password to the password salt, hashes the result, and sends the hash to the server. The server compares the hash from the client to the hash in the user list. Now the password never goes over the wire at all.&amp;nbsp; Awesome!&lt;/p&gt;&lt;b&gt; &lt;p&gt;Unfortunately, this system is worse.&lt;/b&gt; In previous systems the eavesdropper got the password; in this system the eavesdropper gets the salted hash.&amp;nbsp; The eavesdropper can then write their own client which sends that username and salted hash to the server.&lt;/p&gt; &lt;p&gt;And the "steal the password list" attack just came back; now an attacker who gets the password list gets all the salted hashes, and can use them to impersonate the user. Sure, the attacker will still find it hard to deduce the original password from the salted hash, but he doesn't need to deduce the password anymore. (Unless of course the attacker is attempting to deduce your password on one system so that he can use it to attack another system that you use. This is why it's a bad idea to use the same password for two different systems.)&lt;/p&gt; &lt;p&gt;Essentially we've turned the salted hash into a "password equivalent". Can we fix this up?&lt;/p&gt;&lt;/font&gt;&lt;b&gt;&lt;font color="#333399" size="2"&gt; &lt;p&gt;System #5&lt;/p&gt;&lt;/b&gt;&lt;/font&gt;&lt;font color="#800080" size="2"&gt; &lt;p&gt;How about this?&lt;/p&gt; &lt;p&gt;The client sends the username to the server. The server creates a&lt;/font&gt;&lt;i&gt;&lt;font face="Times New Roman"&gt; &lt;/font&gt;&lt;font color="#800080" size="2"&gt;second&lt;/i&gt; random salt which is NOT stored in the user list.&amp;nbsp; This random salt is used&lt;/font&gt;&lt;i&gt;&lt;font face="Times New Roman"&gt; &lt;/font&gt;&lt;font color="#800080" size="2"&gt;only once&lt;/i&gt; -- we either make it so big that odds of generating it again are low, or keep a list of previously used random salts and pick a new one if we have a collision. We'll call the random salt "the challenge" for reasons which will become apparent in a minute.&lt;/p&gt; &lt;p&gt;The server sends the user's&amp;nbsp;password salt and the challenge to the client. The client appends the password salt to the password and hashes the salted password.&amp;nbsp; It converts the salted hash to a string, appends the&amp;nbsp;string&amp;nbsp;to the challenge, and hashes the resulting&amp;nbsp;string to form the "response" hash.&amp;nbsp; The response is sent across the wire.&lt;/p&gt; &lt;p&gt;The server then does the same thing – converts the stored salted password hash to a&amp;nbsp;string, appends it to the challenge, and hashes the resulting string.&amp;nbsp; If the response from the client is equal to the value the server just computed, then the client must have computed the same salted hash, and therefore knows the password.&lt;/p&gt; &lt;p&gt;Now what does the eavesdropper know?&amp;nbsp; The eavesdropper knows the username, the password salt, the challenge and the response.&amp;nbsp; The eavesdropper has enough information to launch an offline dictionary attack against that user. But since the random challenge is never going to be used again, the fact that the attacker knows a valid challenge/response pair is essentially irrelevant.&lt;/p&gt; &lt;p&gt;This system has the downside that an attacker who gets the password file has obtained password equivalents, so no dictionary attack is necessary.&amp;nbsp;(Unless of course the attacker is trying to determine a user's password in order to try it against the user's account on a different system!) &lt;/p&gt; &lt;p&gt;Fortunately, these weaknesses can be mitigated somewhat by changing your password frequently, not using the same passwords for different accounts, never using common dictionary words as passwords, and making passwords long -- passphrases are better than passwords. &lt;/p&gt; &lt;p&gt;***********&lt;/p&gt; &lt;p&gt;This general challenge-response pattern is quite common in authentication systems that rely upon shared secrets, because&lt;/font&gt;&lt;i&gt;&lt;font face="Times New Roman"&gt; &lt;/font&gt;&lt;font color="#800080" size="2"&gt;at no point is the original secret password ever actually stored or transmitted!&lt;/i&gt;&amp;nbsp; With such a system,&amp;nbsp;a machine that&amp;nbsp;does not know your secret can &lt;i&gt;verify that you do know it&lt;/i&gt; -- almost seems magical, doesn’t it?&amp;nbsp;Of course, now that you know how it works, it's not quite so magical -- the salted hash &lt;em&gt;is&lt;/em&gt; essentially the shared secret, and it is stored and transmitted.&lt;/p&gt; &lt;p&gt;Clearly we could go on, adding more and more layers of encryption to this system to further mitigate these vulnerabilities, but I'm going to stop here. Readers interested in ways to solve problems such as mutual authentication (where the server authenticates the client AND the client verifies that it is talking to the right server) or other heavy-duty authentication tasks should read this charming dialogue on the design of the Kerberos authentication system: &lt;/font&gt;&lt;a href="http://web.mit.edu/kerberos/www/dialogue.html"&gt;&lt;u&gt;&lt;font color="#0000ff" size="2"&gt;http://web.mit.edu/kerberos/www/dialogue.html&lt;/u&gt;&lt;/font&gt;&lt;/a&gt;&lt;/p&gt;&lt;font color="#800080" size="2"&gt; &lt;p&gt;The foregoing is of course just a sketch with lots of details glossed over and greatly simplified for didactic purposes. Real&amp;nbsp; professional-grade authentication systems do not work exactly like any of my sketches, though several are quite similar. &lt;/p&gt; &lt;p&gt;Unix boxes&amp;nbsp;used to typically use a&amp;nbsp;12 bit salt and hash it with a 56 bit password&amp;nbsp;using&amp;nbsp;a DES-based hash, for instance. That's pretty weak! A 12 bit salt only makes construction of a dictionary take 4096 times longer -- one dictionary for each possible salt.&amp;nbsp; In modern systems the more secure MD5 hash is often used now, which supports arbitrarily large salts.&amp;nbsp;Unix boxes also used to keep the user list in the clear, so that anyone could read the salted hashes of the passwords; nowadays the encrypted passwords are kept in a file that can only be read by the operating system itself -- defense in depth!&lt;/p&gt; &lt;p&gt;NT by contrast uses&amp;nbsp;an&amp;nbsp;unsalted 128 bit MD5 hash to store&amp;nbsp;the&amp;nbsp;password equivalent, so it is susceptible to dictionary attacks should the password file be stolen.&amp;nbsp;&amp;nbsp;NTLMv2 is an authentication system based on some of the challenge-response ideas from System #5. It hashes the password, user name, domain, and current time in a fairly complex way; I'll spare you the details. And of course, many NT and unix boxes use Kerberos-based authentication these days.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/font&gt;&lt;/font&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=368569" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Salt/default.aspx">Salt</category></item><item><title>You Want Salt With That? Part Three: Salt The Hash</title><link>http://blogs.msdn.com/ericlippert/archive/2005/02/03/you-want-salt-with-that-part-three-salt-the-hash.aspx</link><pubDate>Thu, 03 Feb 2005 14:53:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:366274</guid><dc:creator>Eric Lippert</dc:creator><slash:comments>21</slash:comments><comments>http://blogs.msdn.com/ericlippert/comments/366274.aspx</comments><wfw:commentRss>http://blogs.msdn.com/ericlippert/commentrss.aspx?PostID=366274</wfw:commentRss><description>&lt;font face="Lucida Sans Unicode" color="purple" size="2"&gt; &lt;p&gt;Last time we were considering what happens if an attacker gets access to your server's password file. If the passwords themselves are stored in the file, then the attacker's work is done. If they're hashed and then stored, and the hash algorithm is strong, then there's not much to do other than to hash every string and look through the password file for that hash.&amp;nbsp;If there's a match, then you've discovered the user's password.&lt;/p&gt; &lt;p&gt;You don't have to look through the vast space of strings in alphabetical order of course.&amp;nbsp;An attacker will start with a dictionary of likely password strings. We want to find some way to make that attacker work harder.&amp;nbsp;Setting a policy which disallows common dictionary words as passwords would be a good idea.&amp;nbsp;Another technique is to spice up the hashes a bit with some salt.&lt;/p&gt; &lt;p&gt;&lt;font color="#000080"&gt;&lt;strong&gt;System #3&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt; &lt;p&gt;For every user name we generate a random unique string of some fixed length.&amp;nbsp; That string is called the “salt”.&amp;nbsp; We now store the username, the salt&amp;nbsp;and the hash of the string formed by concatenating the user’s password to the salt. If user Alpha's password is "bigsecret" and the salt is "Q3vd" then we'll hash "Q3vdbigsecret".&lt;/p&gt; &lt;p&gt;Since every user has their own unique random salt, two users who happen to have the same password get different salted hashes.&amp;nbsp; And the dictionary attack is foiled; the attacker cannot compute the hashes of every word in a dictionary once and then check every hash in the table for matches anymore.&amp;nbsp; Rather, the attacker is going to have to re-hash the entire dictionary anew for every salt.&amp;nbsp; A determined attacker who has compromised the server will have to mount an entire new dictionary attack against every user’s salted hash, rather than being able to quickly scan the list for known hashes.&lt;/p&gt; &lt;p&gt;Salting essentially makes it less feasible to attack every user at once when the password file is compromised; the attacker must start a whole new attack for each user.&amp;nbsp; Still, given enough time and weak passwords, an attacker can recover passwords.&lt;/p&gt; &lt;p&gt;In this system&amp;nbsp;the client sends the username and password to the server, the server appends the password to the salt, hashes the result, and compares the result to the salted hash in the table.&amp;nbsp; &lt;/p&gt; &lt;p&gt;This answers the original question posed by the JOS poster; the salt can be public because it is just a random string. Ideally, both the salt and the salted hash would be kept private so that an attacker would not be able to mount a dictionary attack against that salt.&amp;nbsp; But there is no way to deduce any information whatsoever just from the salt.&lt;/p&gt; &lt;p&gt;And of course, it's better to not get into this situation in the first place -- don't allow your password list to be stolen!&amp;nbsp;But it's a good idea for a security system to not rely on other security systems for its own security. We call this idea&amp;nbsp;"defense in depth".&amp;nbsp;You want to make the attacker have to do many impossible things to compromise your security, so that if just one of those impossible things turns out to be possible after all, you're not sunk.&amp;nbsp;&lt;/p&gt; &lt;p&gt;But what about the fact that the password goes over the wire in the clear, where anyone can eavesdrop? That's now the weak point of this system. Can we do something about that? Tune in next time and we'll see what we can come up with.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;/font&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=366274" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.msdn.com/ericlippert/archive/tags/Salt/default.aspx">Salt</category></item></channel></rss>