2008-10-22
Impacta Company Blog is Launched!
This blog (www.buildingsecurecode.com) will definitely continue on with emphasis on providing expert, and pragmatic tips to developers/testers for building secure code, whereas the company blog will be more for discussing online risk topics and innovations. Check it out when you get a chance!
--Kevin
2008-10-02
Has It Really Been a Year?
Even if you are already a security professional, a year's worth of non-stop developing a security product on some awesome Microsoft technologies can teach you a lot, so I am eager to starting sharing again!
--Kevin
2007-09-21
Have You Checked Out Microsoft's Guidance Explorer Lately?
J.D. Meier and the rest of the Patterns & Practices team over at Microsoft are at it again (when did they stop?). If you haven't checked out Guidance Explorer Web Edition, you should and bookmark it now! Here's the link:
I knew about this site way back when I was at Microsoft, but they've made significant improvements since then. It gives you instant access to all the patterns and practices developed at Microsoft and it's a great tool to find out the best ways to identify, mitigate and learn about common coding mistakes that can leave you exposed to malicious hackers. Checklists, methodologies, all there.
For instance, want to learn how to defend your application from SQL injection attacks, type "sql injection" in the search box. Cross site scripting (XSS)? Type "XSS" into the search box and you get everything you need to know from a variety of angles like input validation, authentication etc.
Enjoy,
--Kevin
2007-09-18
Prioritizing Security Assessments in 20 Minutes or Less!
Imagine you’re the CSO of some organization, or work for the CSO of your organization and you’ve been asked to come up with a prioritized list of systems/applications that need to be assessed this year and justify why need to be assessed. How do you start? Let me show you.
Your first thoughts might be consulting firms. Couldn’t they help prioritize security assessments? Consulting companies certainly can (they can do anything when the price is right: conduct a full inside and out regulatory compliance check of your IT operations, mow the lawn, paint the side of the building …), but there are several reasons why creating the prioritization yourself is better. First consultants by definition are “outsiders” to your company and won’t have the same understanding and appreciation of systems/applications/data or their criticality and interdependencies as you will. Second, even if consultants could build up that knowledge about your company (unless you don’t mind) it would be on your dime and you would essentially be paying them to learn about your company instead of helping your company. Finally, most vendors will place the assessment projects that will result in the most potential hours for them at the front of the “priority listing” which often helps their bottom line (revenue) and if you’re lucky maybe even yours (reducing critical risks to your business).
So now that using consultants are out the door, what about using tools and surveys to come up with a prioritization? These can definitely help, but here are reasons why they may not be for you:
- Threat Modeling Tools. Threat modeling helps you understand threats to a system and the prioritization of those threats. You could reasonably base your assessment prioritization on the systems/applications/data that yield the most high risks and threats, but in order to do so you need to have someone who understands the threat modeling process to create the models (more consulting hours) and you need to invest significant time to complete the threat models (even more consulting hours) for every system/application in order to make that prioritization. If you’ve got budget/time/inclination, by all means go the expensive threat modeling services route, but if you don’t read on!
- Surveys. Most surveys work by asking questions along the lines of “does this risk/threat/hazard apply to you?” In other words you’re basically being asked “is this a bad thing for you” and you need to answer yes or no. Each “bad thing” is given a weight, and at the end if the survey all the “bad things” are tallied up and the system/application with the greatest weight is given the highest priority. The one with the second highest weight is given second priority, so on and so on. One problem. You're trying to quantify the bad and I talk about the perils of doing this in my blog about Input Validation.
Now we’re left the best, I think, prioritization system of them all: you. In this article, I’ll show you my own technique that you can use to quickly and systematically determine the priority of security assessments based simply on what you know about your organization (business objectives, processes, data, etc.) not the unknowns (threats, vulnerabilities) and with little to no in-depth security expertise required.
Prioritizing Security Assessments
Our objective is to be able to come up with a prioritized list of security assessments to conduct (what), show how they align closely with the prioritization of overall business objectives (why) and easily explain to the person you’re asking budget from how you came to that list.
This method takes only known data about your organization and utilizes the following to prioritize security assessments:
- Explicit Dependencies. Aspects of your organization that without them your organization does not function at all – caput, nada, lights out, etc.
- Implicit Dependencies. Aspects of your organization that without them your organization still continues, but is degraded in some way.
While it sounds super complex and one beast of a method to execute it’s really not. To get started, all we need to do is start enumerating the following:
- Your organization’s business objectives
- Applications and Systems
- Data and Information
Step 1 (Minute 0-5): Enumerate Your Business Objectives
In this step simply write down your organization’s business objectives. Your organization will probably have multiple ones like increase revenue through direct sales, become industry leader, etc. Doesn’t matter, just write them down.
Next, rank those business objectives as high, medium and low. It’s up to you to determine what constitutes high, medium or low in the context of your organization (since you know it the best). Some of my customers like to rank business objectives in terms of the amount of revenue that objective represents to the organization but that might not fit your scenario. Here’s the standard ranking that I like to use:
- HIGH – Business objectives that are critical to your organization.
- MEDIUM – Business objectives that are important to your organization.
- LOW – Business objectives that are minimally important in the context of your organization.
Step 2 (Minutes 5-10): Enumerate Systems and Applications (Explicit Dependencies)
After you’ve written down your business objectives and ranked them, write down the systems and applications that fulfill those business objectives. These are what I call explicit dependencies because without these systems and applications your organization stops. For instance, if one of your objectives was to increase direct online sales, an application or system that might fulfill that objective is your procurement web application or database to track sales and collects payments.
- HIGH – Explicit dependencies that are critical to the business objective they fulfill.
- MEDIUM – Explicit dependencies that are important to the business objective they fulfill.
- LOW – Explicit dependencies that are minimally important to the business objective they fulfill.
After you’ve finished with systems and applications, now write down the data used by those systems and applications that fulfill the business objectives that you noted in Step 1. These are what I call implicit dependencies because in the absence of them your business still runs, but maybe in a degraded state. It can be data your business generates (accounting records for instance) or data that is given to your business (credit cards for instance). Any data your organization uses, creates or reads in. You get the idea.
Now rank the data. Again, it is up to you how you classify what constitutes HIGH, MEDIUM and LOW. I like to use this ranking system:
- HIGH – Implicit dependencies that are critical to the explicit dependency that uses it. Sometimes referred to as high business impacta (HBI) data.
- MEDIUM – Implicit dependencies that are important to the explicit dependency that uses it. Sometimes referred to as medium business impacta (MBI) data.
- LOW – Explicit dependencies that are minimally important to the explicit dependency that uses it. Sometimes referred to as low business impacta (LBI) data.
The final step now is to tie all that data together and come out with a security assessment prioritization. First step is to take your business objective rankings and order them according to rank. So you should have a HIGH bucket, MEDIUM bucket and a LOW bucket.
Now for each bucket, write down the systems/applications (explicit dependencies) that fulfill that business objective. If you have an explicit dependency that fulfills more than one business objective, err on the side of caution and write it down in the bucket with the highest rank. For instance, if you have an application that fulfills both a HIGH business objective and a MEDIUM business objective, then you want to write it down in the HIGH business objective bucket. At this point you have a set of systems/applications that need to be assessed first (the HIGH bucket), second (the MEDIUM bucket) and last (the LOW bucket).
But what about prioritization within buckets? For instance you know that that all the systems/applications in the HIGH bucket need to be reviewed before the MEDIUM bucket, but in what order do you need to review the systems/applications in the HIGH bucket? To do that you can use the following chart:

To use this chart, look at the ranking of the explicit dependency and then take the highest ranking of the implicit dependency (your application may use multiple pieces of data all ranked differently) to determine the assessment priority within the business objective bucket. So for instance, say you had a HIGH business objective, and in it you had two explicit dependencies. One ranked HIGH (Application X) and another ranked MEDIUM (Application Y). Say the highest implicit dependency that Application X uses is LOW, so if you look at ROW 1, COLUMN 3 you'll see that it has a PRIORITY 1 rating. Also say that Application Y's highest implicit dependency rates at MEDIUM as well, then by our chart (ROW 2, COLUMN 2) this application has a PRIORITY 2 rating. So our prioritization looks like this:
"For our high business objectives, Application X should be assessed before Application Y ..."
That’s it! You now have a security assessment prioritization that closely aligns to the prioritization of your organization’s business objectives. So now when you go back to your boss, you can say “here’s a prioritized security assessment for this fiscal year, here’s how they align to our organization’s business objects and here’s why I need the $(some out of this world budget number) budget to pay Impacta LLC to do those assessments for us :P”.
Making This Method Work for You
You’ll notice that my method is biased towards systems and applications than it is towards data. Does this mean that the data (say social security numbers) is less important than systems and applications? Not at all, the chart above just works well for organizations where availability is more important (think about organizations like eBay, Amazon, MSN, UPS etc.). Now if confidentiality and integrity is more important and the data is king in your line of business (perhaps you’re Experian, TransUnion, or the US Social Security Administration office, etc.) just switches data for the explicit dependencies, and systems/applications to implicit dependencies.
Conclusion
In this article I showed you an easy way to create a prioritized listing of security assessments to do based on known and well-understood information about your organization. The resulting prioritization was closely aligned to business objectives and allows you to easily justify and explain how you came to that prioritization. The advantage about this method is that it’s lets you (the real expert of your organization) make the call on what is important and what’s not important, but now in a systematic, consistent and standard way.
Next steps are to actually conduct the security assessments and another advantage of the method we just discussed is that most of the data we collected here is the data needed to easily lead into most security assessments. So not only are we not re-inventing the wheel, we’re also streamlining our overall security assessment efforts.
In a later post, I’ll talk about the differences between common security assessment techniques such as penetration tests (rarely, but sometimes referred to as “ethical hacking”), vulnerability scanning and audits.
Notes From the Author
Feel free to let me know how this method worked for you either by leaving a comment with this article or at info@impactalabs.com. Hey, who knows … with enough interest, maybe I’ll publish a tool that automates this process for you. Enjoy!
--Kevin
2007-08-18
Security Code Scanning with Microsoft PREFast
Probably one of the most useful security tools to come out of Microsoft, yet the least known and adopted is the PREFast tool. PREFast is a static source code security scanner, or in other words, PREFast is a scanning tool that takes source code as input and returns a list of potentially vulnerable code that could create risks to you and your customers. In the case of PREFast it takes in C/C++ source code and analyzes that code for common coding defects. Security defects by the way are one of several types of defects this tool can detect, so with PREFast you get more than just security code scanning. Did I also mention it's free?
I knew that would get your attention and now that I have it, it's important to understand that PREFast won't solve all your security problems, no one or even a series of tools can (I'll talk about PREFast's limitations later). What it will get you is an objective, repeatable, low-cost risk control to enforce a baseline that you can include in your security development practices.
Are there other security code scanners we could use to scan C/C++ code? Sure, but the beauty of Microsoft's PREFast is you get an enterprise-strength security code scanner without the enterprise-strength price.
In the rest of the article, I'll show you how to get PREFast, how to get started with it, and most importantly how to verify that it's working correctly.
Getting Microsoft PREFast Step-By-Step
As useful as PREFast is, it's notoriously one of the hardest tools to find (this probably explains its low rate of adoption). PREFast is not available as a standalone download, and in order to get it you need download it as part of the latest Microsoft Windows Driver Kits (WDKs) which itself involves several steps that sadly deters most users. In this section of this article, I'll show you step-by-step how to get your hands on PREFast.
Before we begin, you'll need a couple things: a DVD burner, a blank DVD-R disk and DVD burning software. Once you have the above ready, follow these steps to get the PREFast tool.
- Step 1: Go to Microsoft Connect website.
- Step 2: Sign in with your Microsoft Live ID account. If you don't have one you can sign up for one here.
- Step 3: Click Available Connections on the left-side navigation bar.
- Step 4: Look for Microsoft Windows Driver Kit (WDK) and Windows Logo Kit (WLK) link. Click Apply if you haven't already done so before.
- Step 5: Fill out the registration screen details and click Continue.
- Step 6: At this stage you should be signed-in and ready to download the appropriate WDK. To start, click the Connect Home link on the upper left side navigation menu.
- Step 7: Click My Participations also on the left side navigation menu. You should see a table to lists your available connections.
- Step 8: Click on the Windows Logo Kit (WLK), Windows Driver Kit (WDK) and Windows Driver Framework (WDF) link.
- Step 9: On the left hand side navigation menu, click Download.
- Step 10: Select the appropriate WDK download for your operating system. For example, if you are using Vista, then select the Windows Driver Kit RTM (Vista).
- Step 11: Click Download, which starts the Microsoft File Transfer Manager, select a place to save the file and click the Transfer button.

- Step 12: With luck, the transfer should start and once that's done you should have one very large ISO (short for disk image of an ISO 9660 filesystem) file. From here you can use any DVD disk burning software to write the ISO filesystem back onto a DVD disk. After that's done, run the install disk on the machine you wish to install PREFast onto.
- Step 13: Install the WDK. PREFast automatically gets installed with the main build environment.

- Step 14: Open up a build environment and verify that PREFast was installed correctly. To do this, press the Start Button, then Programs and look for the Windows Driver Kits folder. Click on this folder, then click on the folder WDK 6000, then click on the folder Build Environments and then click on your target operating system. For instance, if I am developing an application for Vista, then I'll want to click on the Windows Vista and Windows Server Longhorn folder. Finally choose the target build environment and a MS-DOS style command prompt should open. For example, if I want to develop for Windows Vista 32 bit, I would select Windows Vista and Windows Server Longhorn x86 Free Build Environment shortcut.

- Step 1,000,000: We're finally at the last step and that is to verify that PREFast installed and is running correctly. To do this, just type prefast then Enter and you should see something like the following:

Fortunately we only have to do these steps once, and that we have PREFast installed and running, it's time to run it against some actual code.
Using PREFast
Now that we have PREFast installed and running on our system, let's give it a test run with some actual bad code. I've gone ahead and created some example vulnerable code for our discussion here. In the example pack you find an example of a strcpy buffer overrun (lines 13-22) and a format string vulnerability (lines 32-35), a make file and a sources file.
To use PREFast, we need to call on top of our compiler. The reason why this is is because PREFast works by "intercepting" calls to the compiler to determine if the code being compiled contains known defects. To do this simply open a build environment window (see Step 14 above), unpack the example files into a directory and from that directory type:
prefast build -cZ
The argument -cZ tells the build command to delete any previous object files (c) and not to check any dependencies (Z). After you give this command, PREFast kicks off, invokes the build command to start building our examples and after a small amount of time you should see something like this:

To view the results we have two options. View the results through the command line or via a graphical user interface (GUI). To view the results over the command-line, type:
prefast list

To view the results via the GUI, type:
prefast view

From the GUI you can double-click on the defect messages and it'll nicely highlight for you the area of code that generated the error and a little explanation.
At times you might see lots of defects and you can filter out only the ones you care about by pressing the filter button at the top of the GUI box and selecting the appropriate filters to view. After you've selected the desired defects, hit Apply and the GUI will trim the results to only the ones you care about.

That's it. That was the quick-and-dirty-get-you-up-and-running-now-without-having-to-ready-20-pages-of-documentation introduction to using PREFast! For most users this should be more than enough, but you want more Microsoft has published a more detailed step-by-step guide to using PREFast.
Verifying PREFast Scans
There's an old saying in management that goes something like this: if you can't measure it, it never happened. The same goes with code scanning: if you can't verify that the scan ran correctly or at all, it pretty much never happened. I know of one development team that learned this lesson the hard way, actually make that the very hard way. This team was nearing the planned release date of their product and decided to do some last minute due diligence with a security code scanner. Great, and good for them! The team however accidentally ran the code scanner with all checks turned off and so with a false clean bill of health from the scanner the product was released soon after. Not so great. Security researchers, good and bad, jumped all over the product and automated exploits soon followed. Sadly, careers were made (and some ruined) all at the expense of hacked customers.
Situations like these can be easily avoided. One trick that I use is to temporarily sprinkle the code bases that I am scanning with code that I know is:
- Vulnerable and
- Can be easily detected.
If you're one of my customers, you sometimes might hear me refer to it as beacon code, but the idea is if the code scanner, not just PREFast, doesn't pick up these little beacon code snippets then you know that the scanner is not operating properly. If the code scanner picks it up, then you know that scanner is working correctly and you have at least some level of assurance that the tool ran correctly (that sound you're hearing in the distance is the sound of all the security managers around the world like myself cheering).
So what does vulnerable beacon code look like? Here's the code I use when am doing C/C++ security assessment work for my customers. The beacon code is actually an off-by-one buffer overrun (explanation is in the code itself).Add this code to as one of the sources (modify the sources file) to compile during code scan runs. It's important that you only include the beacon code during code scans and remove it right after, because if you leave it there some developer may mistakenly reference that code and now we've increased our risk. Granted off-by-one overruns are generally harder to exploit. That doesn't mean it's impossible by why take chances right? Run prefast again and you should see an error message corresponding to our beacon code pop-up.
And we're done! We've now verified that PREFast is indeed working and scanning the code!
Conclusion
Before we end our discussion of PREFast, it's important to highlight a couple important points about PREFast so that you know exactly what you are and aren't getting with this tool.
- PREFast is not the best code scanning tool. In fact none of the tools available today or in the future are. The question you should be asking is "what are my organization's security requirements, and which tool best meets those requirements?". It's always important to first define those requirements otherwise you have no idea if the tool you're using is adding value or just wasting time. The tool (or tools) that matches those requirements best is the best tool for your organization. PREFast happens to match Microsoft security requirements, but may not necessarily match yours.
- PREFast is just a tool. It can and should be used as part of any security process, but it should not be used as a replacement. I like to think of PREFast as steering wheel and a security process as a car. By itself, the steering wheel doesn't make a car, but without it the car won't function very well either.
- PREFast is just a tool, part 2. PREFast and any other scanning tool can only detect what it's been designed to detect. So even if PREFast is gives you a clean report and you've verified that it's working you code might still be infested with defects. Hint: did you notice that in our PREFast there was no mention of a format string vulnerability? That's why we mitigate this particular risk with other controls such as expert analyst code review, penetration testing, etc. in case this particular control fails or is inadequate.
- PREFast can be used as a good measuring (and beat) stick. If you're building out a security process and you want to first see how well or bad your organization is doing, PREFast is a good way to do that quickly. If you're a little further along and have a security development process and baselines established already, then PREFast is a good way to check and enforce those baselines in an objective, repeatable and efficient way.
- PREFast provides a snapshot at one point in time only. PREFast will give you a snapshot of the security posture of your code base at one point in time. As soon as someone adds or removes code from that code base, those results are obsolete and scans need to be redone. If PREFast or other code scanning tools are included in your code release criteria, make sure you're working off the most accurate and up-to-date data!
With that, happy scanning!
-Kevin
2007-06-12
Keeping Malicious Hackers at Bay: Approaches to Input Validation
In our everyday lives we are constantly validating ‘things’. For instance, before we drink water from a bottle, we make sure that the seal is intact before drinking it. That way we help ensure that by drinking that water we don’t have undesired effects like sickness in our bodies later on. When I go to my favorite Indian restaurant here in the Seattle area, I always verify with the waiter/waitress that my meal is at the lowest level of spice to ensure that it doesn’t have an undesired effect on my body later on (grin). We are constantly validating things in the real-world. Unfortunately in the digital world we aren’t as diligent, and where we are the wrong technique is being employed. As a result malicious hackers are able to do nasty things like steal millions of credit card numbers and compromise our networks.
Performing proper and well-placed input validation are absolutely critical first steps in keeping the bad guys out of your enterprise systems, enterprise networks, and especially away from your organization’s sensitive information. While the idea of validating input itself is intuitive and straight forward, properly implementing an input validation strategy however can be hardly that. Without a sound understanding and strategy to validating input, enterprises can spend resources on control mechanisms that are flawed and create a false sensitive of security (arguably worse than not validating input at all). In this article, I’ll show you different approaches on how to validate inputs.
Approaches to Input Validation
Step back into the real-world for a moment. Say we wanted to make sure that a can of soda (input), like Coke or Pepsi, was safe to drink before consuming it into our bodies (system). What are the some of the cues or indicators that would help ensure that can of soda was not tampered with and indeed safe to drink? For starters, you could inspect the can itself for puncture marks to ensure that the can has not been tampered with after leaving the factory. You could also listen for cues like the crack of the lid and the quick wisp of gas being released when you open the can. Any one of these cues help us verify that the drink is safe to consume, and in the digital world there also exists cues or factors that help us verify that input from potentially untrusted sources are safe to consume into our systems. They include:
- Type. This factor indicates the kinds of input you are expecting from your users. For instance, are you expecting just numbers (0-9) as in the case of credit numbers (i.e. 1234-1234-1234-1234) or letters like the ones used in country abbreviations (i.e. CA or US)?
- Length. This factor indicates the amount of data we are expecting. For instance, if the input we are expecting to get is a credit card number, then we can expect the length to be 16 digits.
- Format. This factor indicates how the data is expected to be arranged. For instance, zip codes in the United States are typically 5 digits so we could use say the expected format is five consecutive digits. Postal codes in Canada however look like this M1P2X3 so we could say the expected format is an uppercase alphabet character followed by a digit, repeated 3 times.
- Range. This factor indicates the upper and/or lower bounds of the input we are expecting. For instance we could say that we expect alphabetic characters, but only vowels.
- Black-List Technique. The black-list technique is sometimes referred to as the Principle of Exclusions and works by first defining a set of unacceptable or bad inputs into a system. It then checks any input into a system to see if it matches any of those unacceptable input patterns defined earlier in the ‘bad’ set. If a match is found, then the input is considered malicious or a possible threat and rejected. If a match is not found, then the input is assumed to be valid and consumed by the system. I placed emphasis on the word assumed on purpose because as we’ll see later in our discussion I’ll show you how an attacker can circumvent the black-list technique and why this technique should be avoided whenever possible.
- White-List Technique. The opposite of the black-listing technique is the white-listing technique. This technique (or sometimes referred to as the Principle of Inclusions) validates inputs into a system by first defining a set of acceptable inputs or expected inputs. It then tries to match any input into that system against the set of acceptable inputs. If a match is found, then the input is valid and the system continues to use or consume that input. Now, if a match is not found, that is the input is not contained in the valid set, then the input must be part of the unacceptable set and therefore is considered a possible threat to the system and rejected.

Choosing the Correct Input Validation Technique
We’ve just discussed the inner workings of the black-list and white-list techniques to validating input. What has eluded our discussion so far is the answer to the question of which of the two input validation techniques should we use? I alluded to the answer before, but in case you missed it in general you should use the white-list technique and avoid the black-list technique whenever possible. Here’s why:Our challenge really is being able to reliably tell if an input into a system is good or bad (an attack to the system). Let’s take a look at the two input validation techniques and see how reliably we can make this conclusion.
We’ll start with the white-list technique. Recall that the white-list technique defines the set of all acceptable inputs to a given system. The set of all acceptable inputs into a system is known and can be concisely defined, that is you could write down everything in this set if you had to. Sure, that set could be very large, but it has a limit and is therefore finite. Since we’re able to map out a complete acceptable set a developer can easily take any input and reliably make the conclusion that if the input does not exist in the acceptable set, it therefore must be part of the unacceptable set and should be rejected. From a scalability perspective, this technique is easy to implement.
This conclusion about the validity of input however cannot be easily or reliably made using the black-list technique. Recall that the black-list technique works in the opposite fashion as the white-list technique, that is it defines the set of all unacceptable inputs (or possible attack inputs) into a given system. The problem here is that we can’t be sure that our unacceptable set is complete because we can’t predict all the possible actions or inputs from an attacker. We could reasonably predict the likely actions, but not all which still leaves us short of a complete set. The unacceptable set is in actuality infinitely large and therefore by definition it is impossible to define all the possible bad inputs into a system. So if a developer tries to make a conclusion about the validity of some input by saying since this input doesn’t exist in the (incomplete) unacceptable set it must be a valid input they’re in hot water. This is because if they (very likely) miss even a single bad input in his or her black-list set then the attacker can mask their attack as a valid input circumventing the security control entirely. I don’t want to mislead and leave you with the impression that the black-list technique is absolutely horrible and should be avoided like the plague, but it’s very difficult to implement correctly. Even if you were able to get your black-list to work in 99% of the cases, if the attacker is able to find the 1% case where it fails, all you’ve really achieved is 100% failure.

Let’s take a look at an example to illustrate these two important properties of the white-list and black-list technique. The source code for the example is available for download at the end of the article. In our example below, we’ve created program that asks the user to enter in a color. If the color entered is a primary color (red, blue or yellow) then the program will indicate that it is a primary color otherwise that it is not a primary color.

Our goal as the attacker is to trick this program to saying that a color we entered in is a primary color when really it isn’t.Using the white-list technique our example .NET (C#) validation code might look like this.
With the white-list technique we defined the colors RED, BLUE, and YELLOW as our acceptable list of inputs. Anything that the user (or attacker) enters that isn’t contained in this list is automatically recognized as non-primary and rejected. Hooray, our program works correctly!

Now let’s see what happens when we modify our program to use the black-list technique. The example validation .NET (C#) code would look something like this.
If an attacker tries to enter in a non-primary color that exists in our black-list, the program correctly recognizes the input as not a primary color. However what happens if the attacker enters in a color that is not in our black-list, but also isn’t a primary color either like ‘puce’? Our program incorrectly concludes that ‘puce’ is a primary color and reports it as one. If this was a real-life scenario with security implications, we’d be sunk so clearly we want to avoid the black-list technique whenever possible.

Exceptions to the Rule: When White-Listing Fails
Earlier I said in general we want to use the white-list technique and avoid the black-list technique; however there will be scenarios where the white-list technique is not sufficient or applicable. This is especially so in situations where input factors such as the type, length, format or ranges are not known ahead of time. For instance, one of our customers that we were helping had a common scenario where users could enter in a description of their entry.
The description would be posted back on a web page and would be susceptible to potential cross-site scripting (XSS) attacks. We don’t know what the user will enter in ahead of time so white-listing is out the door. In this instance we used a concept called defense-in-depth which I’ll write about later to mitigate the overall risk. Briefly, the general idea behind defense-in-depth is you utilize several layers of defense to reduce the probability of some attack from succeeding. For instance, a defense-in-depth approach might be to use input validation as one layer of defense, but also implement another. In our description box scenario we used the ASP.NET page request validation at the server as one layer, and the Microsoft Anti-Cross Site Scripting Library V1.5 that I published when I was at Microsoft as another layer to significantly reduce the probability that a XSS attack would successfully occur.
There are scenarios where black-listing can be used effectively along with the white-list technique. For instance, white-listing can be implemented using regular expressions (I’ll be discussing this in a later article). One downfall of regular expressions can be that they can be slow if the regular expression is not optimized or excessively large which can lead to overall performance degradation. If there are certain inputs that you know should not be accepted by a system (black-list) you can check for those inputs before incurring the cost of the regular expression (white-list).
Conclusion
As layers within the enterprise such as the network and host layer become more and more secure, attackers are switching their focus to the application layer, which as of the time of this article continues to be the most neglected and least secured enterprise layer. Failing to validate input from untrusted sources leaves applications in vulnerable states that allow attackers to do things such as stealing credit card information, compromise networks and bring down critical services. What’s worse, failing to properly validate input from untrusted sources continues to leave applications and enterprise systems in vulnerable states, but also with a false sense of security amongst business owners and customers.In this article I discussed different approaches to validating input from untrusted sources, in particular using the white-list and black-list techniques. Unfortunately, knowing the approaches to input validation is one third of the entire story. Business owners still need to understand approaches to when to validate input and what input to validate which will be the topic of future posts.
Downloads
How to Display the UAC Shield Icon inside .NET
When deploying enterprise applications and desktop systems, information technology (IT) administrators are often presented with the challenge of maintaining computer security while still enabling business productivity (usability) – traditionally two opposing forces. If systems and users were deployed in highly secure locked-down states, productivity would typically suffer because applications would cease to function properly in the absence of administrative privileges. In the other direction, if administrators opted for higher usability by granting end-users administrative privileges, systems became highly exposed to the effects of malware that could perform malicious actions such as stealing personal information and making unauthorized system changes. To make matters worse, IT administrators really didn’t have an easy way to balance the two requirements and often resorted to a one-or-the-other approach.
Enter the Microsoft Windows User Account Control (UAC) feature in Microsoft Windows Vista . With UAC IT administrators can easily deploy applications and service components with limited privileges (security) while still maintaining the ability to perform elevated tasks (usability) whenever needed.
More information about the features and benefits of UAC can be found at http://technet.microsoft.com/en-us/windowsvista/aa906021.aspx.
One of the most visible features with UAC is the introduction of “elevated shield icon” decorated buttons that help users to identify actions and applications that require elevation. Take for example the task of changing the local system time on a Microsoft Windows Vista system which requires administrative privileges. Microsoft Windows Vista now indicates this requirement by displaying an elevated shield icon-decorated button in the date and time adjustment dialog.
This article shows how .NET developers can enable the same visual cues in their own Microsoft Windows Vista forms-based applications.
Decorating Windows Application Form Buttons with the Elevated Shield Icon in .NET
In unmanaged code (C/C++), there are several way that you could decorate a button with the elevated shield icon. The first method is to use the Button_SetElevationRequiredState macro and the second method is to send the BCM_SETSHIELD message to the target button control handle. If you take a look under the hood and install the Microsoft Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Components, inside the file CommCtrl.h at line 7900 you’ll find the follow declaration for the Button_SetElevationRequiredState macro:
#define Button_SetElevationRequiredState(hwnd, fRequired) (LRESULT)SNDMSG((hwnd), BCM_SETSHIELD, 0, (LPARAM)fRequired)
As we can see, the Button_SetElevationRequiredState macro really just calls user32.dll!SendMessage with the BCM_SETSHIELD message. So in the coming example we’ll decorate a button control with an elevated shield icon from within managed code (specifically C#) using only the BCM_SETSHIELD message method. A link to the sample code is provided at the end of this article.

BCM_SETSHIELD Message MethodExposing the nuts and bolts behind the Button_SetElevationRequiredState macro gives us some useful information about how to use the BCM_SETSHIELD method successfully. A couple things need to happen before we can successful decorate our example button:
- The target button control’s handle must be passed as the 1st argument to user32.dll!SendMessage.
- The correct BCM_SETSHIELD value must be passed as the 2nd argument to user32.dll!SendMessage.
- The value 0 must be passed as the 3rd argument to user32.dll!SendMessage.
- A pointer to a Boolean true value must be passed as the 4th argument to user32.dll!SendMessage.
- The target button control’s .FlatStyle member needs to be set to the system style.
- The function user32.dll!SendMessage must be called from within our C# code.
Sounds like a colossal pain to implement, but it’s really not. Click here to see the code that does the above.
Now to decorate our example button control, we simply need to pass button control as the argument and our handy little EnableElevateIcon_BCM_SETSHIELD method takes care of the rest:
Conclusion
In this article we looked at how we could use the BCM_SETSHIELD message along with .NET P/Invokes to programmatically decorate Windows Vista forms application buttons with elevated shield icons.
While visual cues are helpful, developing applications to be UAC compliant however involves much more than just decorating buttons – there’s considerations such as file system virtualization, registry virtualization, over-the-shoulder (OTS) credentials, proper elevation methods and application manifests that developers need to consider. To learn more about these UAC aspects, please refer to the additional resources and references section.
Downloads
Additional Resources/References
- Developer Best Practices and Guidelines for Applications in a Least Privileged Environment
- User Account Control Overview
- Windows Software Development Kit for Windows Vista and .NET Framework 3.0 Runtime Components
- Windows Vista: User Account Control

