Recall that I said that security is a holistic problem. It is not simply a matter of tuning Windows security and code access security; we need to consider how we write code too. Let me take a moment to address the "how" part of programming.
If a programmer writes classes with all public members , this code is at risk. The risk, again, is relative to the exposure to the outside world. For this reason, assigning moderately low-skilled object-oriented programmers to work on critical systems is like playing Russian roulette with a semiautomatic: every round is a loser. Additionally, if the DLLs that make up a system are downloaded to the client's PC, as is the case with smart clients (see Chapter 10) or various forms of .NET Remoting (see Chapter 8), the code can be reverse-engineered and explored. Worse, the code can be incorporated into new applications that subclass your types, bastardizing the original intent. For example, shadowing an existing behavior or overloading a polymorphic behavior can create a new behavior that easily supplants the original behavior. If new behavior, say, sends credit card numbers to folks who don't mind breaking a few laws, you have big problems. (And these are just a few ideas I came up with in a minute or two.)
To prevent a perversion of your code, it is critical that you understand where your code is going and how access to behaviors is provided. Here are a couple of good strategies you can use in any system to help reduce the risk and enhance the benefit of code access security, as well as the plethora of other security strategies available.
With few ingress points via your fa §ade, a careful evaluation of Windows permissions, limited access to binaries, no embedded secrets, and input data carefully filtered with regular expressions, you are ready to take full advantage of code access security. Let's begin with a look at how to manage security policy.