Welcome to MSDN Blogs Sign in | Join | Help

Security Development Lifecycle Webcast

On June 20th, we will be putting on a webcast entitled "The Microsoft Security Development Lifecycle (SDL) - Continuous Improvement and Demonstrated Results". The Security Development Lifecycle is a process that is constantly evolving and has two main goals: reducing coding and design defects, and reduce the severity of defects that are remaining. Security expert Michael Howard has written a great MSPress book and MSDN article on the subject if you are interested. Here is the abstract for the webcast:

"Microsoft's SDL reflects the knowledge and best practices learned from focused security efforts across all phases of the software development lifecycle and is a mechanism to ensure continuous improvement and demonstrated results.  This session provides an overview of what the SDL means for you and your customers, and explains what's new in the SDL. In addition, the session details Microsoft's commitment to helping customers emulate our processes and build more secure software, including the resources we have available today."

Sign up for the webcast here!

 

8 Simple Rules For Developing More Secure Code

While surfing the Web, I came across the following article written by Michael Howard. The article really resonated for me because it covered the following points:

  • Using analysis tools and experts to review your code (which can be accomplished with tools such as FxCop, AppVerifier and PREfast)
  • Reducing risk using fuzzing and threat modeling  (the ACE team has written a great threat modeling tool that I demoed at the Toronto ISC2 conference recently)
  • Keeping bad input out of your applications
  • Learning all you can about security concepts

It's a good read. Check out the article here:
http://msdn.microsoft.com/msdnmag/issues/06/11/SecureHabits/default.aspx

Are you interested in writing a post on this blog? Contact me here and I'd be glad to review and put up your security oriented article. Cheers!

Developer Windows Vista Security Webcast in May

As you can tell, there is a lot of activity going on with regards to Windows Vista. On May 23rd, we will be running a webcast entitled "Writing Secure Applications for Windows Vista". Here is an abstract of the presentation:

Have you tested your application on Windows Vista? If not, it’s important that you do as it will impact the experience your users will have with the software you have developed. This is especially the case if your application writes to the registry or requires elevated privileges.

The primary objective of this session is to provide developers with the necessary knowledge to successfully write secure application on Windows Vista and get familiarized with Vista’s new security model and features such as Least-privileged User Accounts (LUA), virtualization, and the User Account Control (UAC).  This session will be of interest to all
Windows developers.

Value proposition:
Windows Vista incorporates many new and innovative security features. This session will provide the attendees with the following information:

  • How Vista’s security enhancements may affect their application development environment 
  • How to successfully write Windows Vista applications leveraging features such as UAC
  • The use of tools such as FxCop and PreFAST to identify compatible issues in existing applications or in the development process. 

Call to Action:

  • Start developing secure applications on Windows Vista
  • Use tools like FxCop to find compatible issues with existing applications or new applications in development
  • Take advantage of the new security tidbits added to Windows Vista

To sign up for the event, click on this link: http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032336165&EventCategory=4&culture=en-CA&CountryCode=CA

[Guest Blog] User Account Control for Developers

Kenny Kerr is our guest blogger this month. Here is his bio: Kenny Kerr is a founding employee and Chief Software Architect at PlateSpin Ltd. where he designs and builds new products and helps drive the technical direction for PlateSpin’s market-leading product family. Prior to PlateSpin, Kenny has worked for leading software companies in Africa, the United States, and Canada. With a specialty in commercial software development, he focuses on designing distributed systems, open APIs, performance tuning, Windows systems programming, and most notably secure design and programming practices around C++.

---

Since the release of Windows 2000, the developers working on Windows have been trying to create an environment where users can work safely and securely. Windows 2000 introduced techniques for creating restricted tokens that can effectively limit the permissions and privileges afforded to an application. Windows XP introduced further improvements but it has simply not been pervasive enough to make any real difference for the average user... until now. Whatever your initial reaction, User Account Control (UAC) is here to stay and really isn’t as bad as critics make it out to be. As developers we have a responsibility to embrace it so that the applications we develop don’t annoy and desensitize our users with needless prompts. In this article we are taking a practical look at UAC and specifically what can be done programmatically with respect to elevation and integrity control.

What is security context?

Security context refers to those things that define and constrain what a process or thread can do in terms of permissions and privileges. A security context on Windows is defined in terms of a logon session and these are manipulated via tokens. As its name suggests, a logon session represents a specific session on a single computer for a given user. Programmers interact with logon sessions by means of tokens. Any number of tokens can be created that refer to the same logon session. These tokens can offer different sets of permissions and privileges based on a subset of those provided by the logon session. This is really the key to how UAC works or at least a big part of it.

So how does UAC work?

On Windows Vista there are two predominant types of user accounts, standard users and administrators. The first user account that you can create will be an administrator at least initially and any subsequent user accounts will be standard users by default. Standard user accounts are for those people who you do not trust with complete control over the computer. Administrator accounts are for those users who also enjoy complete control over the computer. Unlike previous versions of Windows, you don’t have to logon as a standard user to protect yourself from malicious code that may find its way to your computer. The logon sessions created for standard users and administrators are equally capable of protecting from such threats.

When a standard user logs on to a computer a new logon session is created and they are presented with a shell application such as Windows Explorer that was created by the system and associated with the user’s newly created logon session by means of a token. This effectively limits what the user can do since Windows Explorer can only run those applications and access those resources that the user’s logon session permits based on the permissions and privileges specified by the token.

When an administrator logs on to a computer things are a little different and this is where Windows Vista differs dramatically from previous versions. Although the system creates a new logon session, it creates not one but two different tokens representing the same logon session. The first token grants all the permissions and privileges afforded to the administrator while the second token is a restricted token, sometimes called a filtered token, offering far fewer permissions and privileges. This restricted token offers practically the same capabilities and constraints as would be granted to a standard user. The system then creates the shell application using the restricted token. This means that although the user is logged on as an administrator, applications are by default run with limited permissions and privileges.

When the administrator needs to perform some task that requires additional permissions or privileges not granted to the restricted token, he or she can elect to run an application using the full security context provided by the unrestricted token. What protects the administrator from malicious code is that this elevation to the unrestricted token is only allowed after the administrator has confirmed the desire to use the unrestricted token by means of a secure prompt provided by the system. Malicious code cannot suppress this prompt and thereby gain complete control over the computer without the user’s knowledge. As I hinted at before, restricted tokens are not new Windows Vista but it is in Windows Vista that they are finally being used in an integrated way in the shell to provide a more secure environment for users to work (and play).

Restricted tokens

Although you will typically not have to create restricted tokens yourself, it is useful to understand how it’s done so that you have a better idea of what is being done on your behalf and so that you can have more insight into the environment in which your application will run. As a developer you may also find yourself needing to create an even more restrictive environment than what is provided by UAC in which case knowing how to create restricted tokens is a must. The aptly named CreateRestrictedToken function creates a new token that is a duplicate of an existing token with certain restrictions. This function can restrict the toke in a number of ways:

• By specifying deny-only security identifiers (SIDs) that can only be used to deny access to securable resources.

• By specifying restricting SIDs that will be used as an additional access check.

• By deleting privileges.

The restricted token used by UAC is created by adding deny-only SIDs and deleting privileges. Restricted SIDs are not used. Let’s walk through a simple example. The first thing we need is a token to duplicate and restrict. Let’s grab the process token:

CHandle processToken;

VERIFY(::OpenProcessToken(::GetCurrentProcess(),

TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY,

&processToken.m_h));

Next we need an array of SIDs to disable. This ensures that they can never be used to allow access. The following code uses my handy WellKnownSid class to construct the SID for the built-in Administrators group. The WellKnownSid class is available with the download for this article.

WellKnownSid administratorsSid = WellKnownSid::Administrators();
SID_AND_ATTRIBUTES sidsToDisable[] =
{
&administratorsSid, 0
// add additional SIDs to disable here
};

Next we need an array of privileges to delete. We first need to look up the privilege’s LUID value:

LUID shutdownPrivilege = { 0 };
VERIFY(::LookupPrivilegeValue(0, // local system
SE_SHUTDOWN_NAME,
&shutdownPrivilege));

LUID_AND_ATTRIBUTES privilegesToDelete[] =
{
shutdownPrivilege, 0
// add additional privileges to delete here
};

Finally, we can call CreateRestrictedToken to create the restricted token:

CHandle restrictedToken;
VERIFY(::CreateRestrictedToken(processToken,
0, // flags
_countof(sidsToDisable),
sidsToDisable,
_countof(privilegesToDelete),
privilegesToDelete,
0, // number of SIDs to restrict,
0, // no SIDs to restrict,
&restrictedToken.m_h));

The resulting token’s group SIDs will have an entry for the built-in Administrators group with the SE_GROUP_USE_FOR_DENY_ONLY flag making sure that the SID is used to deny access but not allow access. The token will also be stripped of the SeShutdownPrivilege privilege ensuring that the token cannot be used to restart, sleep, or shutdown the computer. If this sounds interesting you can try a quick experiment. Copy the code above to a console application and then add the following call to the CreateProcessAsUser function, updating the path to the Windows Explorer executable as appropriate:

STARTUPINFO startupInfo = { sizeof (STARTUPINFO) };
ProcessInfo processInfo;
VERIFY(::CreateProcessAsUser(restrictedToken,
L"C:\\Windows\\Explorer.exe",
0, // cmd line
0, // process attributes
0, // thread attributes
FALSE, // don't inherit handles
0, // flags
0, // inherit environment
0, // inherit current directory
&startupInfo,
&processInfo));

Now kill any existing Explorer.exe process on your computer and run the code. You should notice that you can no longer use Explorer to restart, sleep, or shutdown the computer. These options in the Start menu should be disabled.

Finally, there is a function called IsTokenRestricted. It does not however tell you whether the token was created using the CreateRestrictedToken function but merely reports on whether the token contains restricted SIDs. So unless you’re using restricted SIDs it is not a very useful function.

Integrity levels

One aspect of UAC that gets very little attention is a concept called Mandatory Integrity Control. This is a new authorization feature added to processes and security descriptors. Securable resources can specify an integrity level in their security descriptors. Each process on the system is also marked with an integrity level which is then validated against the integrity level of the resource as an added authorization step. Despite its relative simplicity, it is a surprisingly useful feature as it allows you to very simply and effectively partition what a particular process can access.

Imagine you are developing an application that must routinely deal with data from untrusted sources such as the Internet. Since it may be possible for malicious code to circumvent any steps you may have taken to protect the computer, it is helpful to add a certain amount of "defense in depth" as an added layer of protection. One extremely effective solution was described in the previous section using restricted tokens. It can however be complicated to figure out exactly what SIDs to allow and what SIDs to deny access to certain resources and specifically what permissions to grant each identity considering that the application itself still needs certain permissions to function. This is where integrity levels come in. Integrity levels are primarily used to prevent write access while allowing read and execute access. By allowing read and execute access you allow applications to continue to perform the majority of their functions but preventing write access limits the harm they can cause by overwriting system files or tainting the user’s search paths as an example. This is exactly what Internet Explorer 7 does. It runs portions of the browser in a separate process with low integrity and there are only a handful of file system locations that provide write access to low integrity applications.

There are four integrity levels available to user-mode processes:

• Low

• Medium

• High

• System

Standard user tokens as well as restricted (non-elevated) administrator tokens have an integrity level of Medium. Unrestricted (elevated) administrator tokens have an integrity level of High. Processes running under the Local System account have an integrity level of System. The Internet Explorer process token has an integrity level of Low. A simple way to see the integrity levels for various processes is to get the latest version of Process Explorer which includes an optional column to display the integrity level of each process.

A child process will by default inherit the integrity level of the parent. You can change the integrity level when a process is created but not once it has been created. Further, you cannot raise the integrity level of a child process to anything higher than that of the parent. This avoids code with lower integrity from gaining higher integrity. Let’s first take a look at how to query and set the integrity level for a process and then we’ll examine how to set the integrity level for securable resources.

Process integrity levels

You can determine the integrity level for a process by examining the process token. The GetTokenInformation function returns different classes of information. For example, to determine the user account represented by the token you specify the TokenUser class. GetTokenInformation will then populate a TOKEN_USER structure based on the information in the token. Similarly the TokenIntegrityLevel class can be specified to query the integrity level of the process and a TOKEN_MANDATORY_LABEL structure will be produced. Most of the structures populated by GetTokenInformation are variable length structures and since only GetTokenInformation knows how much space is required you need to follow a rigid pattern for calling this function. Since most of the low-level security functions use LocalAlloc and LocalFree to allocate and release memory, I use a LocalMemory class template along with a GetTokenInformation function template to simplify matters dramatically. You can find these templates in the download that accompanies this article. Here we will simply focus on the subject at hand:

CHandle processToken;
VERIFY(::OpenProcessToken(::GetCurrentProcess(),
TOKEN_QUERY,
&processToken.m_h));
LocalMemory<PTOKEN_MANDATORY_LABEL>info;
COM_VERIFY(GetTokenInformation(processToken,
TokenIntegrityLevel,
info));
SID* sid = static_cast<SID*>(info->Label.Sid);
DWORD rid = sid->SubAuthority[0];
switch (rid)
{
case SECURITY_MANDATORY_LOW_RID:
{
// Low integrity process
break;
}

case SECURITY_MANDATORY_MEDIUM_RID:
{
// Medium integrity process
break;
}

case SECURITY_MANDATORY_HIGH_RID:
{
// High integrity process
break;
}

case SECURITY_MANDATORY_SYSTEM_RID:
{
// System integrity level
break;
}
default:
{
ASSERT(false);
}
}

Here OpenProcessToken is used again to get the process token to query. My GetTokenInformation function template is then called with the appropriate information class and LocalMemory class template specifying the information type. The populated TOKEN_MANDATORY_LABEL structure contains a SID that represents the integrity level. Dissecting it will give you the relative identifier (RID) representing the integrity level that you program against.

To set the integrity level for a child process is pretty straightforward. Start by creating a duplicate of the parent process token. Then simply set the integrity level using the same information class and data structure used to query the integrity level in the previous example. The SetTokenInformation function comes in handy for this. Finally you can call CreateProcessAsUser to create the child process using the modified token. Here’s an example:

CHandle processToken;
VERIFY(::OpenProcessToken(::GetCurrentProcess(),
TOKEN_DUPLICATE,
&processToken.m_h));
CHandle duplicateToken;
VERIFY(::DuplicateTokenEx(processToken,
MAXIMUM_ALLOWED,
0, // token attributes
SecurityAnonymous,
TokenPrimary,
&duplicateToken.m_h));
WellKnownSid integrityLevelSid(WellKnownSid::MandatoryLabelAuthority,
SECURITY_MANDATORY_LOW_RID);
TOKEN_MANDATORY_LABEL tokenIntegrityLevel = { 0 };
tokenIntegrityLevel.Label.Attributes = SE_GROUP_INTEGRITY;
tokenIntegrityLevel.Label.Sid = &integrityLevelSid;
VERIFY(::SetTokenInformation(duplicateToken,
TokenIntegrityLevel,
&tokenIntegrityLevel,
sizeof (TOKEN_MANDATORY_LABEL) + ::GetLengthSid(&integrityLevelSid)));
STARTUPINFO startupInfo = { sizeof (STARTUPINFO) };
ProcessInfo processInfo;
VERIFY(::CreateProcessAsUser(duplicateToken,
L"C:\\Windows\\Notepad.exe",
0, // cmd line
0, // process attributes
0, // thread attributes
FALSE, // don't inherit handles
0, // flags
0, // inherit environment
0, // inherit current directory
&startupInfo,
&processInfo));

This example launches Notepad. Give it a try. You should notice that although Notepad can open text files in most locations, it cannot save to any location that is not marked with a low integrity level. Finally, you can get a display name for integrity levels using the LookupAccountSid function, but they’re not all that user friendly so you’re better off using a string table with values like "Low", "Medium", "High", and "System". The token created by the system for standard users has an integrity level of Medium. The restricted, or filtered, token created by the system for administrators also has an integrity level of Medium, but the unrestricted administrator token has an integrity level of High. Now let’s examine how to set the integrity level for a particular resource.

Resource integrity levels

The integrity level for a resource is stored in a special access control entry (ACE) in the system access control list (SACL) of the resource’s security descriptor. The simplest way to set or update this value for system resources is using the SetNamedSecurityInfo function. AddMandatoryAce is a new function provided by Windows Vista to add the special ACE, known as a mandatory ACE, to an ACL. Remember, security is all about confusing people with acronyms…

Seriously, the code is quite simple if you’re familiar with programming security descriptors. Start off by preparing an ACL pointing to a buffer that is just large enough to hold a single ACE. This is achieved using the InitializeAcl function. Next the SID representing the integrity level is created and added to the ACL using the AddMandatoryAce function. Finally the integrity level is updated using the SetNamedSecurityInfo function. Notice the new LABEL_SECURITY_INFORMATION flag being used in the sample below:

LocalMemory<PACL> acl;
const DWORD bufferSize = 64;
COM_VERIFY(acl.Allocate(bufferSize));
VERIFY(::InitializeAcl(acl.m_p,
bufferSize,
ACL_REVISION));
WellKnownSid sid(WellKnownSid::MandatoryLabelAuthority,
SECURITY_MANDATORY_LOW_RID);
COM_VERIFY(Kerr::AddMandatoryAce(acl.m_p,
&sid));
CString path = L"C:\\SampleFolder";
DWORD result = ::SetNamedSecurityInfo(const_cast<PWSTR>(path.GetString()),
SE_FILE_OBJECT,
LABEL_SECURITY_INFORMATION,
0, // owner
0, // group
0, // dacl
acl.m_p); // sacl
ASSERT(ERROR_SUCCESS == result);

Retrieving the integrity level of a resource is equally simple provided you realize that most resources won’t have an integrity level set explicitly. Rather the system interprets the absence of an integrity label as if the resource were marked with "Medium" integrity. Start by calling GetNamedSecurityInfo with the same security information flag namely LABEL_SECURITY_INFORMATION. If a valid ACL pointer is returned and contains an ACE then you know the integrity level is set explicitly. Now simply call the GetAce function to retrieve a pointer to the ACE storing the integrity level SID and read the RID value to determine the integrity level. Here is an example:

CString path = L"C:\\SampleFolder";
LocalMemory<PSECURITY_DESCRIPTOR>descriptor;
PACL acl = 0;
DWORD result = ::GetNamedSecurityInfo(const_cast<PWSTR>(path.GetString()),
SE_FILE_OBJECT,
LABEL_SECURITY_INFORMATION,
0,
0,
0,
&acl,
&descriptor.m_p);
ASSERT(ERROR_SUCCESS == result);
DWORD integrityLevel = SECURITY_MANDATORY_MEDIUM_RID;
if (0 != acl && 0 < acl->AceCount)
{
ASSERT(1 == acl->AceCount);
SYSTEM_MANDATORY_LABEL_ACE* ace = 0;
VERIFY(::GetAce(acl,
0,
reinterpret_cast<void**>(&ace)));
ASSERT(0 != ace);
SID* sid = reinterpret_cast<SID*>(&ace->SidStart);
integrityLevel = sid->SubAuthority[0];
}

ASSERT(SECURITY_MANDATORY_LOW_RID == integrityLevel);

Run as administrator

So far we’ve looked at some of the individual building blocks that make up UAC such as restricted tokens and integrity levels. Let’s now take a look at what it means to "Run as administrator" and how this can be done programmatically. You have probably noticed that you can right-click an application or shortcut and select a context menu option entitled "Run as administrator". This is available for both standard users and administrators. The concept of running as an administrator is more commonly referred to simply as elevation or creating an elevated process. Standard users are prompted for administrator credentials while administrators are simply prompted for permission to elevate. Either way the end result is a new process running with an unrestricted administrator token and all the permissions and privileges it affords.

The process of elevation is a bit complicated but fortunately much of the complexity is hidden behind an updated ShellExecute(Ex) function. ShellExecute on Windows Vista makes use of the new Application Information (appinfo) service to perform elevation through an undocumented COM interface. ShellExecute first calls CreateProcess to attempt to create the new process. CreateProcess does all the work of checking application compatibility settings, application manifests, runtime loaders, etc. If it determines that the application requires elevation but the calling process is not elevated then CreateProcess fails with ERROR_ELEVATION_REQUIRED. ShellExecute then calls the Application Information service to handle the elevation prompt and creation of the elevated process since the calling process obviously doesn’t have the necessary permissions to perform such a task. The Application Information service ultimately calls CreateProcessAsUser with an unrestricted administrator token.

If on the other hand you want to create an elevated process regardless of what application information is available then you can specify the little-known "runas" verb with ShellExecute. This has the effect of requesting elevation regardless of what an application’s manifest and compatibility information might prescribe. The runas verb is not actually new to Windows Vista. It was available on Windows XP and Windows 2003 and was often used to create a restricted token directly from the shell. This behavior has however changed. Here is a simple example:

::ShellExecute(0, // owner window
L"runas",
L"C:\\Windows\\Notepad.exe",
0, // params
0, // directory
SW_SHOWNORMAL);

Considering how much is going on behind the scenes, aren’t you glad this is all the code you need to write? Although creating a new elevated process is reasonable, it’s not always the most appropriate solution if you only need to elevate temporarily. Enter elevated COM objects.

Creating an elevated COM object

If you invested heavily in the COM era you’ll know that COM supports creating COM servers hosted in a surrogate process. Well this technique has been augmented to allow COM servers to be created in an elevated surrogate process. This is extremely useful since you can simply create the COM object on the fly in your application without having to create a whole new process directly. The hardest part about using this technique is registering the COM server correctly to indicate that it should be loaded in a surrogate process and support elevation since the COM object needs to specifically declare its cooperation.

This first thing to do is update the COM registration to declare that your library (DLL) server can be run in a surrogate process. All you need to do is add the "DllSurrogate" named value under your server’s AppID registry key. In ATL you simply update the project’s main RGS file to look something like this:

HKCR
{
NoRemove AppID
{
'%APPID%' = s 'SampleServer'
{
val DllSurrogate = s ''
}
'SampleServer.DLL'
{
val AppID = s '%APPID%'
}
}
}

An empty value for DllSurrogate indicates that the system-supplied surrogate is to be used. The COM client can now specify the CLSCTX_LOCAL_SERVER execution context to create the COM server in the surrogate process:

CComPtr<ISampleServer>server;
COM_VERIFY(server.CoCreateInstance(__uuidof(SampleServer),
0,
CLSCTX_LOCAL_SERVER));

The next step is to enable elevated launch of the COM class. This involves adding entries to the COM class registration script. An elevation key is added to indicate that elevation is supported for this particular COM class and a "LocalizedString" named value is also required and provides the display name used by the UAC prompt. An ATL COM class registration script should look something like this:

HKCR
{
SampleServer.SampleServer.1 = s 'SampleServer Class'
{
CLSID = s '{91C5423A-CF90-4E62-93AD-E5B922AE8681}'
}
SampleServer.SampleServer = s 'SampleServer Class'
{
CLSID = s '{91C5423A-CF90-4E62-93AD-E5B922AE8681}'
CurVer = s 'SampleServer.SampleServer.1'
}
NoRemove CLSID
{
ForceRemove {91C5423A-CF90-4E62-93AD-E5B922AE8681} = s 'SampleServer Class'
{
ProgID = s 'SampleServer.SampleServer.1'
VersionIndependentProgID = s 'SampleServer.SampleServer'
InprocServer32 = s '%MODULE%'
{
val ThreadingModel = s 'Neutral'
}
val AppID = s '%APPID%'
'TypeLib' = s '{A43B074B-0452-4FF4-8308-6B0BF641C3AE}'
Elevation
{
val Enabled = d 1
}
val LocalizedString = s '@%MODULE%,-101'
}
}
}

Don’t forget to add a string to your string table for the localized name. The COM client can now launch the elevated COM server. As with CreateProcess, the CoCreateInstance function won’t create an elevated COM object directly. Instead you need to use the COM elevation moniker. This is most easily achieved using the CoGetObject function to build the moniker and return a proxy to the object that is ultimately created:

template <typename T>
HRESULT CreateElevatedInstance(HWND window,
REFCLSID classId,
T** object)
{
BIND_OPTS3 bindOptions;
::ZeroMemory(&bindOptions, sizeof (BIND_OPTS3));
bindOptions.cbStruct = sizeof (BIND_OPTS3);
bindOptions.hwnd = window;
bindOptions.dwClassContext = CLSCTX_LOCAL_SERVER;
CString string;
const int guidLength = 39;
COM_VERIFY(::StringFromGUID2(classId,
string.GetBufferSetLength(guidLength),
guidLength));
string.ReleaseBuffer();
string.Insert(0, L"Elevation:Administrator!new:");
return ::CoGetObject(string,
&bindOptions,
__uuidof(T),
reinterpret_cast<void**>(object));
}

Using the function template is just as simple as calling CoCreateInstance:

CComPtr<ISampleServer>server;
COM_VERIFY(CreateElevatedInstance(0, // window
__uuidof(SampleServer),
&server);

As with ShellExecute, the window handle is used by UAC to determine whether the prompt will steal the focus or whether it will be waiting for the user in the background.

Using application manifests

Remember when I said that CreateProcess checks application compatibility settings and application manifests among other things? As it turns out, Windows Vista goes to great lengths to ensure that legacy 32-bit applications run properly. This involves a tremendous amount of plumbing to virtualize areas of the file system and registry that applications traditionally had full access to but no longer do under the more restrictive environment imposed by UAC. As impressive as all this virtualization is, the key is to avoid it if at all possible. It’s meant for legacy applications. If you’re writing an application today make sure to provide an application manifest which is the surest way to make sure that virtualization is not applied to your application. Indeed Microsoft is planning on removing the virtualization capabilities in a future version of Windows.

The application manifest schemas have received an upgrade in Windows Vista to allow them to express the application’s requested security context. What makes it a little more complicated is that Visual C++ by default automatically generates an application manifest. This is actually a very good thing. The linker is keenly aware of the dependencies of your application and the manifest is used to define dependencies on side-by-side assemblies. Fortunately it also provides an option for merging in additional manifest files into the manifest that is ultimately embedded into the application executable. The Visual C++ project’s "Additional Manifest Files" setting is just the thing. Here’s a simple manifest file that declares a dependency on Common Controls 6.0 and specifies a desired security context:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<v3:trustInfo xmlns:v3="urn:schemas-microsoft-com:asm.v3">
<v3:security>
<v3:requestedPrivileges>
<!-- level can be "asInvoker", "highestAvailable", or "requireAdministrator" -->
<v3:requestedExecutionLevel level="highestAvailable" />
</v3:requestedPrivileges>
</v3:security>
</v3:trustInfo>
</assembly>

The requested execution level can specify one of three values. "asInvoker" is the default and a new process will simply inherit the token of the parent process. "highestAvailable" indicates that the application is requesting the most unrestictive security context available to the user. For standard users this is the same as "asInvoker" but for administrators this is a demand for the unrestricted token. "requireAdministrator" indicates that a unrestricted administrator token is needed. Standard users will be prompted for administrator credentials and administrators will be prompted for consent to elevate.

Remember, CreateProcess will check the manifest and fail to create the process if the requested execution level does not match that of the parent process. Only ShellExecute makes use of the Application Information service to perform elevation.

Am I already elevated?

Finally, if all you need is to determine whether or not you are currently elevated you can simply call the IsUserAnAdmin function. If you need more precision you can also use GetTokenInformation but in most cases that is overkill.

Conclusion

That’s it for UAC. I hope you’ve found this helpful. Very little of what I’ve described is currently documented. Hopefully that will change. I should add that all the samples I present typically use assertions and similar macros to check for errors. I do this to identify where error handling is necessary. If you use some of the code in your own applications, be sure to replace these macros with whatever error handling strategy you use, whether its exceptions, HRESULTs or something else.

IT Professional Security Webcasts

Rodney Buike, my counterpart on the IT Pro team has set up a security webcast series which may be interesting to you. Here is a description of the series and the events:

With every new OS release security is improved and refined and with Windows Vista this is still the case. There are a number of new and improved security tools and features built into Windows Vista, and a number of new tools and resources to integrate Vista into your existing environment. Learning what these features are, how to plan for them, deploy them and manage them along with what resources are available to help is crucial to a successful deployment.

What’s New in Vista Security - April 25th 2007
With all the new eye candy in Vista, the security features often get overlooked.  The first session will look at the new features, what they are, where they would be used and most importantly why you should consider implementing them.  At the end of this session you should have a good understanding of some kernel level changes and features such as User Access Control, upgrades to the Windows Vista Firewall and Security Center, BitLocker and IE7 and be ready to start implementing a secure Vista deployment.
http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032336945&Culture=en-CA

Manage Vista Security With Group Policy - May 9th 2007
Managing Vista via Group Policy has been improved.  With over 2400 GPO settings you have more control than ever before and tools like the GPO Accelerator can help speed the implementation of GPOs over your Vista computers and ease management of BitLocker on mobile PCs.  This session will start by giving you a refresh of GPO and OU structures and get you up to speed on the new GPO settings, the GPO Accelerator and other resources and how they can be used to lockdown and secure your environment.
http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032336947&Culture=en-CA

Manage Advanced Security Features - May 23rd 2007
On top of the new GPO settings there are some new, more advanced, security features in Vista.  BitLocker is one of the popular features and we will take a deep dive into BitLocker covering TPM, key backup, management via group policy and configuration will be covered in this session.  We will also take a look at improvements to the Encrypted File System (EFS) and Rights Management Services (RMS).
http://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032336949&Culture=en-CA

We hope you can attend...cheers!

ASP.NET AJAX Security Webcast

Be sure to check out our latest security webcast this Wednesday. Here is the abstract: ASP.NET AJAX is a powerful framework for creating interactive and highly-personalized Web experiences that work across all the most popular browsers. Like any other frameworks, there are security considerations you need to take into account. In this session, you will learn the core security concepts and principles surrounding the ASP.NET AJAX framework and learn how to implement them in your existing applications.

Here is the link to register for the webcast:
http://msevents.microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032329023&EventCategory=4&culture=en-CA&CountryCode=CA

Hope to see you there!

Posted by jldavid | 0 Comments

Post Webcast: Is Your App Secure?

Unfortunately, right at the very end of today's Webcast we experience a small technical difficulty with the on-line evaluation form.  If you were not able to fill out the evaluation and you attended today's session can you please do so now, here.

The moral of today's Webcast was to show that there are many readily available tools you can use to quickly test for potential security vulnerabilities in an application that you contracted out to be developed. By no means are we suggesting these simple techniques is all you have to do to validate a claim made by a vendor that their application is secure. 

But rather, the goal was to show that there a lot of tools you can use to do some preliminary security test and not take security for granted.  Most likely, if you find security vulnerabilities by using these tools then you probably found low-hanging fruit.  And if you can these low-hanging fruit then you can bet there are much more subtle and series security vulnerabilities.

Here is a list of the tools we showed today and where you can find them:


AccessEnum www.sysinternals.com Reports on ACL
SubinACL Windows 2003 Resource Kit Powerful ACL Manager
Filemon www.sysinternals.com Monitor File system calls
Regmon www.sysinternals.com Monitor Registry Calls
Process Explorer www.sysinternals.com Task Man on steroids
SQL Profiler Optional with Microsoft SQL Server Monitors SQL Statements
Fiddler www.fiddlertool.com Modify http data

Within the next couple of days a recording of today's Webcast and to register for upcoming monthly security talks can be found at:

http://msdn.microsoft.com/canada/securitylockdown/...

Today is my last day at Microsoft Canada and you will be in good hands with Jean-Luc David and the Security Team.

Happy Security Hunting!

Posted by dansellers | 1 Comments

[Guest Blogger] Kevin Lam Thoughts on Code Scanning Tools

Kevin Lam (Redmond, Washington)

[Guest Blogger] Thoughts on Code Scanning Tools

Information managers, developers and testers commonly make the mistake of seeing code scanning tools as replacement for security QA processes. As a result they get a false sense of security about their software development lifecycle. Rather than using code scanning tools as a QA team replacement, think of code scanning tools an enforcement mechanism to help ensure that developers are following best practices and more importantly application security development policies.

Secondly tools need to be tightly integrated into a SDLC and not done as a one-off exercise. I visit a lot of customers each year to train them on developing applications securely and often ask them about their development processes and where tools fit into those processes. A common, almost consistent, response I hear is “developers run tools if they know they exist and if they remember.” Ouch. One way in which I’ve helped customers in the past is to integrated tools as a direct gate within their SDLC. Failure to complete this step affects the developer’s ability to proceed forward. As I always say, there’s a difference between what you say you do, and what you actually do.

Another common request from customers I get is for me suggest to them which is the ‘best’ tool. My response: potato. There is no best tool per se, but rather there is a best tool that meets their code scanning requirements. In order for a tool to be identified, I help my customers define those requirements first – otherwise they’ve just purchased or downloaded a tool that they have no idea whether or not is adding value or not.

Have fun scanning!


Kevin Lam
Senior Security Technologist
Microsoft ACE Security Services

Kevin Lam

Kevin Lam is a Senior Security Strategist at Microsoft with over 7 years experience in information security. At Microsoft he is responsible for conducting security assessments (security code review, penetration testing and architectural review) for high valued targets such as XBOX Live, Windows, .NET Framework, MSN Money and critical business services. Kevin is also responsible for driving security strategy and policy changes across Microsoft company-wide and works closely with senior management. He recently published a book for Microsoft Press titled “Assessing Network Security” (ISBN: 0-7356-2033-4) that has received excellent reviews industry-wide, and has also been published in literature such as TechNet magazine. He is a frequent speaker and has participated on several expert security panel discussions.

MSDN Canada: Security Virtual Conference Recording

As promised, here is the recording of MSDN Canada Writing Secure Code Fundamentals Virtual Conference. 

Enjoy the recording and I hope to see you at our next online Security sessions on October 18th, 2006.  This will be the first of eight, one hour monthly security sessions.  I am excited about the next session as it will provide you the knowledge and a demonstration of various tools that one can use to do preliminary testing to verify if an application written by an outside firm is in fact secure. 

When you ask someone if their application is secure, the answer is always yes.  Seriously, do you really think any one will say no?  Of course not as they just lost that sale and most likely future revenue.  So what is the incentive to say either "no" or "I do not know"?  Therefore, how do you really know if any application is secure if you are not going to do some preliminary security testing. 

Don't get trapped into what you want to hear whether it is true or not.  This just leads to a false sense of security and you might as well continue sticking your head in the sand.

Below is the thought process that occurs when you ask someone if their application is secure:

public static void main()

{

Console.WriteLine("Is App Secure: 1=Yes 2=No 3=Not Sure");
Console.Write("Please enter your selection: ");

string s = Console.ReadLine();

int n = int.Parse(s);
int revenue= 0;

switch(n)
{

case 1:
revenue+= 25,000;
break;

case 2:
revenue+= 0; //oh wait no revenue...just kidding...
goto case 1; //therefore say yes

case 3:
revenue+= 0; //oh wait no revenue...just kidding...
goto case 1; //therefore say yes

default:
revenue+=0; //go for the revenue
goto case 1; //this is the answer everyone wants to hear break;

}

if (revenue!= 0)
Console.WriteLine("Thank you for your business and of course the {0} dollars. Oh and you can Trust Me too!!",revenue);

}

}

You can register for the October 18th on-line event here.

Introduction to AJAX Security

As I start investigating the use of AJAX technology for new or existing Web Applications there are some major concern around Security that arises. The good news is—for the most part--securing AJAX enabled Web Applications is very similar to securing traditional Web Applications except there are a lot more moving parts.  This, I hope, will be the first in a series of blogs on AJAX Security.

So what are some of the major security concerns around AJAX?

Lack of Best Practices

If you are building a traditional ASP.NET 2.0 there are numerous best practices on creating a Secure Web Application. However, as you start digging into developing an AJAX enabled Web Application you will not find a shortage of information. There are numerous articles, sample code and videos on AJAX. These samples are meant to demonstrate a specific feature or set of features available for the novice and thus these examples do not cover security. With AJAX still being a relatively new technology many developers will cut and paste sample code into their application.  Without understanding potential security vulnerabilities of the sample code then the chances of creating security exploits are a real concern. As the saying goes “One person feature is another person exploit”. Just because there are samples code out there to demonstrate a feature you really have to decide if you want to use that feature and if so how do you secure it against potential threats it may bring to the application.  For example, there some sample code that shows how to use the autocompletetextbox.  In this scenario, as you start typing characters in the textbox, JavaScript is executing in the background and making a call to a Web Service that is retrieving information from a database to autocomplete the entry in the textbox.  Very cool indeed, however, as an attacker all I need to do is to write a script, randomly generate some characters into the autocompletetextbox and loop through this about 1000 times.  Boom!  I just created a denial of service attack by bringing your database to it knees.  The problem here is the sample never mentioned you should cache the results from the Web Service.

XMLHTTPRequest

The core of AJAX is the power of the XMLHTTPRequest object. This is what provides the client the ability to send JavaScript request to a Server and in return receive JavaScript responses that can be evaluated on the client. Furthermore, XMLHTTPRequest provides JavaScript with the ability to execute independent of the user. Therefore, JavaScript request can be launched on timer controls, keystroke etc. This will lead to more request to the server and each of these requests are AJAX endpoints.

If you are not using SSL for all of your pages then there is a lot more information being send across the wire in clear text. Thus, if a hacker was probing your AJAX Web Application then the end user would be able to discern function names, variables, parameters, return type, and data types. These additional endpoints increases the attack surface of an application. Furthermore, with AJAX it is possible to distribute a significant amount of the code on the client and not just the Server anymore. This allows the developer to embed more code on the client side including the ability to create richer client side controls. The power of the JavaScript can lead to Cross Site Scripting attacks that has the ability to prorogate like a worm.  Let examine some of these security concerns in greater details.

Client Side Controls

The goal of AJAX is to build richer browser based application and one great way of doing so is by moving some of the server side controls to the client. Not only does this increase the attack surface on a insecure environment but some of these controls are being advertised as providing security. Case in point are the client side controls for input validations. There is no such thing as security on the client. Client side validation controls are meant to provide better performance and responsiveness when the honest end-user makes a mistake.

Providing the client with a richer interface or more functionality does not change the fact the client is still considered insecure. Once you release the application in production you have no control over the client or how it is being used or who is using it, thus it cannot belong to Security sub-system like your Servers do. You must always rely on doing validation on the Server before any input is passed into a trusted resource such as a database. All input must be considered evil until proven otherwise. Personally, I think the client side validation controls need to be accompanied with big red neon lights saying this will help with performance and not security.

  • Client Side Validation!=Security
  • Client Side Validation=Performance

If you are relying on client side validation then all the hacker has to do is disable JavaScript in the browser and a more sophisticated hacker will create their own client that mimic yours but without any of the validation.

JavaScript Web Service Proxies

AJAX for ASP.Net 2.0 provides the ability to generate JavaScript proxies which provides the client with the ability to use JavaScript to call Web Services. The initial design of many Web Services was to accommodate a B2B environment in which the authentication, authorization and input validation is done for the most part on the middle-tier systems. Now with the client calling the Web Services directly then this may by-pass the middle tier security layer. Furthermore, I have not seen anything in the client side proxy that use WS Security such as User Name or security tokens as you can be done with Server side proxies. Therefore, having a client calling the Web Service directly without totally verifying the security requirements of the application may provide hackers with an endpoint that has direct access to trusted resources. Furthermore, if this Web Service calls the database and no input validation is being done on the Server then you are opening yourself up to SQL Injection attacks.

Cross Site Scripting (XSS) Attacks

XSS is now on steroids as the attack can occur behind the scene without your knowledge. With the traditional Web Applications there was at least some kind of visual cues. With AJAX it is possible to send some value via an input parameter to the Server and the response from the Web Server can contain JavaScript snippet where the client can evaluate the code by using the eval() function. 

It seems there are still a lot of developers are still using a deny listing technique of looking for dangerous characters such as script but what if the hacker does not use script but rather they use eval() or use something like the <img> tag with a source attribute equal to javascript:txt.

<img src="javascript:txt='function someattack()...'/>

This is just another example of canonical attack. Therefore, if you are going to prevent XSS attacks by looking for the word “script” then a hacker will have you in their sights with eval() or other ways of representing the same characters or function.

Even more dangerous is the ability for JavaScript to work independent of user thus making it possible for XSS to propagate itself like a worm. The prime example is what occurred to MySpace.com. I am not condoning what was done here but rather providing you with a link that provides a technical description of how Cross Site Scripting attacks has increased in severity. Actually, worse of all here is another example of using Deny or Black listing for input validation against unwanted characters. Every time we hear of attacks in which some form of input validation was circumvented it is always because of Black or Deny Listing.  We have to start using White or Accepting Listing when making decision on what is considered to be acceptable characters. Always fail on the side of caution.

Increased Attack Surface

With AJAX there is a perceived performance increase by making more frequent but smaller requests back to the server independent of the user. Furthermore, AJAX is not just about the Server but it has equal focus on the client. Therefore, the application complexity and code base will now shift from the Server to the client. This will increase the attack surface on the client which is next to impossible to protect as it lies outside of any trusted subsystem.

It is easier to secure something you can see like the query string being passed in the URL. But what happens when you cannot see the URL and query string as is the case with AJAX since many of the request are occurring in the background. Unfortunately, developers may forget to protect the numerous additional end points.

Let me leave you with this thought:

"AJAX allows for JavaScript to be able to connect to the Web Server independent of the user. Extremely powerful for creating Web Applications. Since AJAX provides us with the power to make the client perform tasks that was once only available on the Server, then it is equally important to realize that a hacker can take advantage of this capability. More than ever it is critical to perform threat modeling to thoroughly understand all the end-points and all input being passed to the Server."

Posted by dansellers | 6 Comments
Filed under:

Post Security Virtual Conference Recap--Writing Secure Code Fundementals

Wow! It was great to see such a high attendance and have it be sustained through three sessions and four hours in total.

The three sessions were:

In this blog post I am going to recap and summarize some of the key points that we talked about today.  Over the next few days I will create additional blogs that will cover areas that needs to be drilled into deeper based upon today questions and feedback such as AJAX, Code Analysis tools and where you can download a recording of today's virtual conference.

If you have not yet, please fill out the on-line evaluation for those that attended today's session.  This is our first ever Security virtual conference and we want to make it better in the future.

You can also register for upcoming monthly (1 hour) security chalk talks at http://msdn.microsoft.com/canada/securitylockdown/...

Hacking Revealed

The first session today was examining and demonstrating the most common attacks that we are faced with today.  Examples included:

  • XSS
  • SQL Injection
  • BufferOverrun
  • Canonicalization Issues

The most common attack today and will only likely increase in the near future with AJAX is Cross Site Scripting (XSS).  For traditional web applications this is already a big enough threat and will become even more potent with AJAX.  Stay tuned as I will be posting over the next few days on AJAX Security.

XSS occurs when the user of the Web Application is able to insert input that will ultimately be posted or echoed back to the Web Page.  In the example I showed how a name and credit number value were required input and before proceeding with this fictitious application, the inputs had to be confirmed.  The problem here was the values entered for both the User Name and Credit Number were not sanitized before being echo back to the Web page in a span tag.  Therefore, an attacker instead of entering in a valid User Name could probe the site for XSS vulnerabilities by entering html or JavaScript such as <b>name</b> or <script>alert('you are being hacked')</script>.  This was an example of non-persistent XSS scripting and leave some lead to defacing a site or stealing cookies, but first you would need to convince someone to click on a link such as false promise to win a prize in an email etc.  Sort of a phishing attack. 

The more dangerous of XSS is when it is persistent.  This occurs when the value the hackers enters is saved into the backend resource such as a database. Therefore, if the input is not being validated and value being entered such as responses to questions like "Please give us your opinion on this product etc" is stored into a database and the value from this database field is read back into another Web Page.  Therefore, the script is stored as ACSII in the database and is harmless to the database.  But when a user clicks on a webpage that queries the database and retrieves the value then it becomes dangerous. As the browser is parsing the html and when it encounters the <script> or <img src=javascript:txt> tag in the database it will start firing off the javascript. Therefore, this type of attack will not affect just one user sessions but all users that happen to click on that webpage.

The second most common attack was SQL Injection.  Similar to XSS this is where the user input is passed back to the database engine for processing.  Therefore, if an input requires a datatime to do a search in a database then a valid datatime can be appended with additional SQL syntax.  This becomes dangerous when the input value entered is appended to the database query with out any validation. 

The third most common attack was bufferoverrun.  This time the value entered by the end-user is passed onto the stack. If the input is greater than what then spaced stored on the attack and the function writing to the stack is a low-level language such as C and C++ then it is possible to overwrite the EIP or return address.  Therefore, a hacker can craft up shell code and pass that in as input and have the EIP set to call the hacker malicious code.  This becomes the most dangerous type of attacks as it could potentially allow users to run shell code that will format the harddrive, shutdown the firewall, create user accounts etc.

Finally, the last major example was canonical issue attacks.  Basically there are multiple ways of representation characters in our applications.  Therefore, if we are making decision by looking for a match of one or more characters in our code, then the attacker can bypass or deceive the decision making process by representing the characters in different a format such as hex values, double encoding or Unicode.

Mitigate and Detection

Therefore, when it comes to the mitigating and detecting these common types of attacks there are two major take-away.

  • Never trust User Input
  • Run under least privilege

Therefore, to prevent all the attacks from above, in your code you need various ways to validate the input and the validation needs to be done on server and not just the client. 

  • Client Side validation!=Security
  • Client Side validation=performance

XSS can be prevented by a few techniques:

  • ValidateRequest="true" in the page directive on ASP.NET 1.1 and 2.0 Applications--default setting
  • HtmlEncode or URLEncode with either the Server.HttpUtility from the framework or the Anti-XSS library

For SQL Injection Attacks the recommendations were:

  • Parameterize Queries, and
  • Filtering of Data via Regular, and
  • Running under least privilege database account

Buffer Overrun

  • Perform a null check and strlen on the input value -1 (the -1 accounts for the null value), and
  • Run as least privilege account

Canonical Issues Defenses

  • White Listing or Acceptance Listing--fail on the side of caution by filtering on characters accepted. This way the list is shorter, performs faster and does not have to be continually updated for every possible way a character can be represented like that used in Black or Deny Listing, and
  • Use Regular Expression to filter for validate data such as only long file names.

Therefore, the morale of the story is to use multiple input validation techniques and never rely on just one as someone will find away around it.  Finally, ensure your applications are running as least privilege therefore, the more harmful SQL Injection and BufferOverrun would fail due to a lack of permissions.

Use both a combination of code scanning tools and manual approach to find code vulnerabilities.  There is no perfect code scanning tools and I like the saying Kevin Lam pointed out in today's presentation.  Tools can not replace Humans and Humans can not replace tools.  Regardless on what a code scanning tool vendor may tell you, there are no silver bullet, no simple solution.  There will be a future blog on code scanning tools.

As Michael Howard and David LeBlanc points out in Writing Secure Code Edition 2, these security practices are like seat belts.  Just because you use a seat belt you cannot drive at 200 km and expect to be safe in an accident. 

Threat Modeling

Finally, the day wrapped up by looking at the new threat modeling tool by Microsoft ACE Team and how it can aid in documenting your applications and the potentials threats that may exists. Proper countermeasures can only be implemented when you truly understand the threats an application may have.  There is no silver bullet countermeasure for all threats an application may face.

The threat modeling tool can be downloaded here and read the threatmodeling tool blog for additional information and videos.

Finally, the goal of today's virtual conference was to place the emphasize on writing secure code and that security is about acceptable risk through mitigation.  There are no silver bullets and there is no such thing as 100% secure. 

I leave you with this one last thought:

"At least when you physically secure a building you can usually see an attack, but on the Internet what you cannot see will HURT you. Securing applications is harder than physical security because you can not see the attack, how it is being done or when it is happening.  You have no security tapes to review and to learn that an attacked even occured or what you can do to mitigate the attack in the future."

Posted by dansellers | 2 Comments
Filed under:

An Application or Device is Only as Secure as it was Tested Against

It still amazing in this day and age how many Security Professionals, Developers and Architect still believe in the Silver Bullet and automatically accept an Application is Secure becomes someone says it is.  The quick and easy way out does not work when it comes to Security.

I never believe anything is 100% Secure.  There is nothing in this world that is perfect.  Applications can only be deemed safe if proper Security testing was conducted and then again it can only be deemed safe for what it was tested against.  You can never consider yourself deem safe for the unknown.

I thought the Myth Busters from the Discovery channel did an excellent of pointing out how anything including bio-metrics security mechanisms are also fallible. 

This is an excellent video!! http://www.youtube.com/watch?v=oXyFmieZjiE

Posted by dansellers | 0 Comments
Filed under:

[Guest Blogger] Dana Epp on Security Myth: Only Large Teams Can Write Secure Code

Dana Epp (Chilliwack B.C.)

[Guest Bloggers] Security Myth: Only Large Teams Can Write Secure Code

If you ask me, one of the biggest fallacies of writing secure code is that you can only accomplish it when you work in large teams and have bigger budgets.  There is a disconnect between the theory of secure programming, and the practice as smaller ISVs believe they simply don’t have the resources to meet the objectives required for safer software.

What is interesting is that a lot of businesses are put at more risk because of this. Many buy tools from these small ISVs, since the ISV typically focuses on small verticals the big boys aren’t after.  But if the same defensive coding strategies aren’t applied, the business is at more potential risk, and typically doesn’t even know it.

Recently I was brought into an environment to audit some code in business workflow that caused a major failure in a manufacturing facility by exposed privileged information publicly and shutting down a key system. They had built a web service to expose status and engineering change orders of just-in-time manufacturing for their customers. I can’t really go into much more detail, but to state that poor coding practices in how to handle failure code paths resulted in private information to get plastered on the public facing website and an exception thrown that wasn’t caught properly, causing the whole thing to tumble down. The problem was pinpointed to a 3rd party library that simply wasn’t written properly to handle tainted input from an untrusted source, which in this case was completely accidental.

After discussing this with the ISV and making suggestions on how to fix it, I was presented with the argument that they can’t afford the time or tools to do this. They said they didn’t have the resources needed, and that ticked me off. I felt it was a cop out. So I decided I would do something about it.

I knew I had a project coming up that I wanted to do, and felt it would be the perfect time to highlight how some front loading of design decisions and the selection of the proper tools could go a long way for a small ISV in building better software.  From mindmapping features to threat modeling functionality, I wanted to show the end to end process of building software. Well, at least how we do it around here. Every software company will have their own methods to do this.

So last month I did just that. In 30 days I went from the idea of a product to the reality in 30 days. With just ONE person…. aka me. Now this wasn’t to impress anyone with my ability to write code. It was to impress upon the readers that it was indeed possible to do it with a small team. Can’t get any smaller than one guy. And I blogged and screencasted the process as I went along.

If you are interested in sharing in my experience, feel free to check out the Project Anvil blog at http://www.scorpionsoft.com/anvil/.  I highly recommend you read it from the first post at the end of July and read along as I built Anvil. It was quite an experience. And the product is now being dogfooded in house in a set of betas we hope to open to the public next month.

So don’t let the excuse of limited time and budgets dissuade you from writing secure code. It is possible. But like anything, you need to think objectively before hand and build it into your development process from the get go. Not sure how to do that? May I recommend that you pick up the book “The Security Development Lifecycle” written by Michael Howard and Steve Lipner (ISBN: 0735622140)? It will go a long way to show how Microsoft does it, and will allow you to adopt what you think makes sense in your own dev process.

Dana Epp
Microsoft Security MVP

Dana Epp

Dana Epp, Scorpion Software Corp’s founder and CEO, researches software security and sets the vision in the convergence of information security principles and practices with digital information asset protection for small business. As a computer security software architect, Mr. Epp has spent the last 15 years focusing on computer programming with a particular emphasis on security engineering to offer a safer computing environment for business. His latest research has been on risk-based authentication, focusing on strong two-factor authentication (2FA) for small business.

Posted by dansellers | 1 Comments
Filed under:

[Guest Blogger] Tatiana Zamachnaia on Security Paranoia Revisited: Do Not Trust Even Gurus

Tatiana Zamachnaia (Ottawa)

[Guest Bloggers] Security Paranoia Revisited: Do Not Trust Even Gurus

My latest consulting gig called for a reporting solution. I tried the GridView and other ASP.NET 2.0 controls but this solution needed a custom ASP.NET Server Control that would be extremely light weight in nature. The custom control needed to be similar to the repeater with extra features and functionality such as the ability to do paging on demand.

I went online to take a look at what the best of the best recommend. I run into the Pager control by one of the best .NET researchers.

I downloaded the code and tested it and it was a good match. The license allowed incorporating it in the project and I was really happy about this little pager control.

Never on earth I would question author’s expertise. His prestige is high and his leadership in ASP.NET is unquestionable. I’ve never seen any article from him that wouldn’t offer valuable stuff. I am just raving about his work, to everybody: my students, .NET friends, developers. However, when I test, I test. After I was satisfied with the functionality, I wanted to break the thing. The very first thing I did is I used my friend View State Decoder by Fritz Onion.

Lo and behold! I could see the connection string staring at me (which of course I suspected when I looked at the code, but again, I though that this couldn't happen to the guru’s component).

Unfortunately, I thought that there would be issues with the original design if I tried to fix it (of course, the first thing I thought of is to encrypt the connection string).

This issue was discovered in the beginning of January and sent to the Microsoft. I got the response that it was resent and things will be taken care of.

It looks like an article is still dated and has not been updated. Or at least from what I can see.

My concern is that many developers might be using this control without questioning security. Again, prestige of the author of the control is extremely high, and I really admire what he does. So does everybody. I am afraid developers would just blindly grab the control as it is.

During my security seminar in Ottawa I showed .NET Developers a view state piece by viewing the page source. I sounded enthusiastic when I was commenting on the garbagey look of it. So, when I asked whether it is encrypted, most of the people said: yes. So, you get idea about how many people think they are safe. (For reference: it is encoded, but not encrypted).

Morale: Do Not Trust Anything (Or Anybody) Unless Proved Harmless

Tatiana Zamachnaia

Tatiana Zamachnaia is an independent consultant who specializes in ASP.NET architecture and has a passion for ASP.NET security.  She has been working with .NET since early beta and became interested in ASP.NET security in late 2003. Tatiana is a .NET evangelist and has mentored .NET developers and taught .NET in academic settings. Tatiana aspires to public speaking on the subject of security and had started regionally by making presentations in Ottawa area.

Posted by dansellers | 1 Comments
Filed under:

Signing Modules in SQL Server 2005 with Certificates

The one topic that I get asked to talk about frequently is Encrypting Data with SQL Server 2005.  Personally, I am very impressed with the build-in encryption support provided in SQL Server 2005, but one of my favorite and what appears to be a subtle Security enhancement in SQL Server 2005 is the ability to sign Modules such as Stored Procedures, Functions or Triggers with Certificates.

The first thing you are probably wonder is why would I want to sign a Stored Procedures?

By signing a Module with a certificate, the certificate is then granted the relevant permission and goes beyond what can be achieved with the "Execute As" feature, especially from an auditing perspective. 

When you perform tracing, the auditing table will record the "Execute As User" that performed the operation of the Stored Procedure (the user account in which the stored procedure is executing under) but does not show who the actual calling user was.  Now, there is a additional column in the auditing table that will record the original login that caused the actions to occur, however, in the trace records it will only show that Execute As User performed all the operations and not the original caller.

Thus the moral of the story is we use the Sign Module approach in SQL Server 2005 this will allow us to capture the original caller that caused the action to occur in the Stored Procedure.

So how do I set this up?

Let say we have an End User calling a Stored Procedure called Proc1 that will perform some kind of action on Table1.  The End User does not have permission on the Table 1, only the Proc1 does, however, the End User has been granted Execute permission.

Now we can sign Proc1 with a certificate called Cert1.  We then create a User called CertUser which is mapped to the Cert1.  Then we grant the necessary permission on Table1 to CertUser.

What is going on under the Hood of SQL Server 2005?

When a SQL Server 2005 User calls a Module the User Token--similar to a token in Windows will be passed to the Module.  The Token will contain both the primary id--identifies the calling user--and the secondary's id--the SQL Server 2005 roles the user belongs to.  If the Module has been signed, SQL Server 2005 will add the User Account which has been mapped to the Certificate--that was used to sign the Module--to the secondary id of the calling user.

Therefore, in our example, when EndUser calls SP1, SP1 will verify the signature of Cert1 and add CertUser--the user that was mapped to the Certificate--to the secondary id of the EndUser token.  Now EndUser can have access to the Table1 via the signed Module "Proc1" and in tracing we can capture the "Calling User"--End User--and not just the "Executing As User" only.

Posted by dansellers | 2 Comments
Filed under:
More Posts Next page »
 
Page view tracker