body { margin:0px; padding:0px; background:#f6f6f6; color:#000000; font-size: small; } #outer-wrapper { font:normal normal 100% 'Trebuchet MS',Trebuchet,Verdana,Sans-Serif; } a { color:#DE7008; } a:hover { color:#9E5205; } a img { border-width: 0; } #content-wrapper { padding-top: 0; padding-right: 1em; padding-bottom: 0; padding-left: 1em; } @media all { div#main { float:right; width:66%; padding-top:30px; padding-right:0; padding-bottom:10px; padding-left:1em; border-left:dotted 1px #e0ad12; word-wrap: break-word; /* fix for long text breaking sidebar float in IE */ overflow: hidden; /* fix for long non-text content breaking IE sidebar float */ } div#sidebar { margin-top:20px; margin-right:0px; margin-bottom:0px; margin-left:0; padding:0px; text-align:left; float: left; width: 31%; word-wrap: break-word; /* fix for long text breaking sidebar float in IE */ overflow: hidden; /* fix for long non-text content breaking IE sidebar float */ } } @media handheld { div#main { float:none; width:90%; } div#sidebar { padding-top:30px; padding-right:7%; padding-bottom:10px; padding-left:3%; } } #header { padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; border-bottom:dotted 1px #e0ad12; background:#F5E39e; } h1 a:link { text-decoration:none; color:#F5DEB3 } h1 a:visited { text-decoration:none; color:#F5DEB3 } h1,h2,h3 { margin: 0; } h1 { padding-top:25px; padding-right:0px; padding-bottom:10px; padding-left:5%; color:#F5DEB3; background:#DE7008; font:normal bold 300% Verdana,Sans-Serif; letter-spacing:-2px; } h3.post-title { color:#9E5205; font:normal bold 160% Verdana,Sans-Serif; letter-spacing:-1px; } h3.post-title a, h3.post-title a:visited { color: #9E5205; } h2.date-header { margin-top:10px; margin-right:0px; margin-bottom:0px; margin-left:0px; color:#777777; font: normal bold 105% 'Trebuchet MS',Trebuchet,Verdana,Sans-serif; } h4 { color:#aa0033; } #sidebar h2 { color:#B8A80D; margin:0px; padding:0px; font:normal bold 150% Verdana,Sans-serif; } #sidebar .widget { margin-top:0px; margin-right:0px; margin-bottom:33px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; font-size:95%; } #sidebar ul { list-style-type:none; padding-left: 0; margin-top: 0; } #sidebar li { margin-top:0px; margin-right:0px; margin-bottom:0px; margin-left:0px; padding-top:0px; padding-right:0px; padding-bottom:0px; padding-left:0px; list-style-type:none; font-size:95%; } .description { padding:0px; margin-top:7px; margin-right:12%; margin-bottom:7px; margin-left:5%; color:#9E5205; background:transparent; font:bold 100% Verdana,Sans-Serif; } .post { margin-top:0px; margin-right:0px; margin-bottom:30px; margin-left:0px; } .post strong { color:#000000; font-weight:bold; } pre,code { color:#999999; } strike { color:#999999; } .post-footer { padding:0px; margin:0px; color:#444444; font-size:80%; } .post-footer a { border:none; color:#968a0a; text-decoration:none; } .post-footer a:hover { text-decoration:underline; } #comments { padding:0px; font-size:110%; font-weight:bold; } .comment-author { margin-top: 10px; } .comment-body { font-size:100%; font-weight:normal; color:black; } .comment-footer { padding-bottom:20px; color:#444444; font-size:80%; font-weight:normal; display:inline; margin-right:10px } .deleted-comment { font-style:italic; color:gray; } .comment-link { margin-left:.6em; } .profile-textblock { clear: both; margin-left: 0; } .profile-img { float: left; margin-top: 0; margin-right: 5px; margin-bottom: 5px; margin-left: 0; border: 2px solid #DE7008; } #sidebar a:link { color:#999999; text-decoration:none; } #sidebar a:active { color:#ff0000; text-decoration:none; } #sidebar a:visited { color:sidebarlinkcolor; text-decoration:none; } #sidebar a:hover { color:#B8A80D; text-decoration:none; } .feed-links { clear: both; line-height: 2.5em; } #blog-pager-newer-link { float: left; } #blog-pager-older-link { float: right; } #blog-pager { text-align: center; } .clear { clear: both; } .widget-content { margin-top: 0.5em; } /** Tweaks for layout editor preview */ body#layout #outer-wrapper { margin-top: 0; } body#layout #main, body#layout #sidebar { margin-top: 10px; padding-top: 0; } -->

Sunday, March 30, 2008

Creating DACL

Creating a DACL
Creating a proper discretionary access control list (DACL) is a necessary and important part of application development. Because a NULL DACL permits all types of access to all users, do not use NULL DACLs.
The following example shows how to properly create a DACL. The example contains a function, CreateMyDACL, that uses the security descriptor definition language (SDDL) to define the granted and denied access control in a DACL. To provide different access for your application's objects, modify the CreateMyDACL function as needed.
In the example:
The main function passes an address of a SECURITY_ATTRIBUTES structure to the CreateMyDACL function.
The CreateMyDACL function uses SDDL strings to:
Deny access to guest and anonymous logon users.
Allow read/write/execute access to authenticated users.
Allow full control to administrators. For more information about the SDDL string formats, see Security Descriptor String Format.
The CreateMyDACL function calls the ConvertStringSecurityDescriptorToSecurityDescriptor function to convert the SDDL strings to a security descriptor. The security descriptor is pointed to by the lpSecurityDescriptor member of the SECURITY_ATTRIBUTES structure. CreateMyDACL sends the return value from ConvertStringSecurityDescriptorToSecurityDescriptor to the main function.
The main function uses the updated SECURITY_ATTRIBUTES structure to specify the DACL for a new folder that is created by the CreateDirectory function.
When the main function is finished using the SECURITY_ATTRIBUTES structure, the main function frees the memory allocated for the lpSecurityDescriptor member by calling the LocalFree function.
Note To successfully compile SDDL functions such as ConvertStringSecurityDescriptorToSecurityDescriptor, you must define the _WIN32_WINNT constant as 0x0500 or greater.
Copy Code
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <sddl.h>
#include <stdio.h>
BOOL CreateMyDACL(SECURITY_ATTRIBUTES *);
void main()
{

SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = FALSE;
// Call function to set the DACL. The DACL
// is set in the SECURITY_ATTRIBUTES
// lpSecurityDescriptor member.
if (!CreateMyDACL(&sa))
{
// Error encountered; generate message and exit.
printf("Failed CreateMyDACL\n");
exit(1);
}
// Use the updated SECURITY_ATTRIBUTES to specify
// security attributes for securable objects.
// This example uses security attributes during
// creation of a new directory.
if (0 == CreateDirectory(TEXT("C:\\MyFolder"), &sa))
{
// Error encountered; generate message and exit.
printf("Failed CreateDirectory\n");
exit(1);
}
// Free the memory allocated for the SECURITY_DESCRIPTOR.
if (NULL != LocalFree(sa.lpSecurityDescriptor))
{
// Error encountered; generate message and exit.
printf("Failed LocalFree\n");
exit(1);
}
}
// CreateMyDACL.
// Create a security descriptor that contains the DACL
// you want.
// This function uses SDDL to make Deny and Allow ACEs.
//
// Parameter:
// SECURITY_ATTRIBUTES * pSA
// Pointer to a SECURITY_ATTRIBUTES structure. It is your
// responsibility to properly initialize the
// structure and to free the structure's
// lpSecurityDescriptor member when you have
// finished using it. To free the structure's
// lpSecurityDescriptor member, call the
// LocalFree function.
//
// Return value:
// FALSE if the address to the structure is NULL.
// Otherwise, this function returns the value from the
// ConvertStringSecurityDescriptorToSecurityDescriptor
// function.

BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA)
{

// Define the SDDL for the DACL. This example sets
// the following access:
// Built-in guests are denied all access.
// Anonymous logon is denied all access.
// Authenticated users are allowed
// read/write/execute access.
// Administrators are allowed full control.
// Modify these values as needed to generate the proper
// DACL for your application.
TCHAR * szSD = TEXT("D:"); // Discretionary ACL
TEXT("(D;OICI;GA;;;BG)"); // Deny access to
// built-in guests
TEXT("(D;OICI;GA;;;AN)"); // Deny access to
// anonymous logon
TEXT("(A;OICI;GRGWGX;;;AU)") ;
// Allow read/write/execute
// to authenticated users
TEXT("(A;OICI;GA;;;BA)"); // Allow full control
// to administrators
if (NULL == pSA)
return FALSE;
return ConvertStringSecurityDescriptorToSecurityDescriptor(
szSD,
SDDL_REVISION_1,
&(pSA->lpSecurityDescriptor),
NULL);


}

Origin Article : http://msdn2.microsoft.com/en-us/library/ms717798(VS.85).aspx

Monday, March 17, 2008

[MSDN]Defend Your Code with Top Ten Security Tips Every Developer Must Know

Defend Your Code with Top Ten Security Tips Every Developer Must Know

Michael Howard and Keith Brown

This article assumes you're familiar with C++, C#, and SQL
Level of Difficulty 1 2 3
SUMMARY
There are many ways to get into trouble when it comes to security. You can trust all code that runs on your network, give any user access to important files, and never bother to check that code on your machine has not changed. You can run without virus protection software, not build security into your own code, and give too many privileges to too many accounts. You can even use a number of built-in functions carelessly enough to allow break-ins, and you can leave server ports open and unmonitored. Obviously, the list continues to grow. What are some of the really important issues, the biggest mistakes you should watch out for right now so that you don't compromise your data or your system? Security experts Michael Howard and Keith Brown present 10 tips to keep you out of hot water.
Security is a multidimensional issue. Security risks can come from anywhere. You could write bad error handling code or be too generous with permissions. You could forget what services are running on your server. You could accept all user input. And the list goes on. To give you a head start on protecting your machines, your network, and your code, here are 10 tips to follow for a safer network strategy.

1. Trust User Input at Your Own Peril
Even if you don't read the rest of this article, remember one thing, "don't trust user input." If you always assume that data is well formed and good, then your troubles are about to begin. Most security vulnerabilities revolve around the attacker providing malformed data to the server machine.
Trusting that input is well formed can lead to buffer overruns, cross-site scripting attacks, SQL injection attacks, and more.
Let's look at each of these potential attacks in more detail.

2. Protect Against Buffer Overruns
A buffer overrun occurs when the data provided by the attacker is bigger than what the application expects, and overflows into internal memory space. Buffer overruns are primarily a C/C++ issue. They're a menace, but generally easy to fix. We've seen only two buffer overruns which were not obvious and were hard to fix. The developer did not anticipate externally provided data that was larger than the internal buffer. The overflow causes corruption of other data structures in memory, and this corruption can often lead to the attacker running malicious code. There are also buffer underflows and buffer overruns caused by array indexing mistakes, but they are less common.
Take a look at the following C++ code snippet:
void DoSomething(char *cBuffSrc, DWORD cbBuffSrc) {
char cBuffDest[32];
memcpy(cBuffDest,cBuffSrc,cbBuffSrc);
}
What's wrong with it? Actually, there's nothing wrong with this code if cBuffSrc and cbBuffSrc come from a trusted source, such as code that did not trust the data and so validated it to be well formed and of the correct size. However, if the data comes from an untrusted source and has not been validated, then the attacker (the untrusted source) could easily make cBuffSrc larger than cBuffDest, and also set cbBuffSrc to be larger than cBuffDest. When memcpy copies the data into cBuffDest, the return address from DoSomething is clobbered because cBuffDest is next to the return address on the function's stack frame, and the attacker makes the code perform malicious operations.
The way to fix this is to distrust user input and not to believe any data held in cBuffSrc and cbBuffSrc:
void DoSomething(char *cBuffSrc, DWORD cbBuffSrc) {
const DWORD cbBuffDest = 32;
char cBuffDest[cbBuffDest];
#ifdef _DEBUG
memset(cBuffDest, 0x33, cbBuffSrc);
#endif
memcpy(cBuffDest, cBuffSrc, min(cbBuffDest, cbBuffSrc));
}
This function exhibits three properties of a well-written function which mitigates buffer overruns. First, it requires the caller to provide the length of the buffer. Of course, you should not blindly trust this value! Next, in a debug build, the code will probe the buffer to check that it is indeed large enough to hold the source buffer, and if not, it will probably cause an access violation and throw the code into a debugger. It's surprising how many bugs you can find when doing this. Last, and most important, the call to memcpy is defensive; it copies no more data than the destination buffer can hold.
During the Windows® Security Push at Microsoft, we created a list of safe string handling functions for C programmers. You can check them out at Strsafe.h: Safer String Handling in C.

3. Prevent Cross-site Scripting
Cross-site scripting vulnerabilities are Web-specific issues and can compromise a client's data through a flaw in a single Web page. Imagine the following ASP.NET code fragment:

<script language=c#>
Response.Write("Hello, " + Request.QueryString("name"));
</script>
How many of you have seen code like this? You may be surprised to learn it's buggy! Normally, a user would access this code using a URL that looks like this:
http://explorationair.com/welcome.aspx?name=Michael
The C# code assumes that the data is always well formed and contains nothing more than a name. Attackers, however, abuse this code and provide script and HTML as the name. If you typed the following URL
http://northwindtraders.com/welcome.aspx?name=<script>alert('hi!');
</script>
you'd get a Web page that displays a dialog box, saying "hi!" "So what?" you say. Imagine that the attacker convinces a user to click on a link like this, but the querystring contains some really nasty script and HTML to get your cookie and post it to a site that the attacker owns; the attacker now has your private cookie information or worse.
There are two ways to avoid this. The first is not to trust the input and be strict about what comprises a user's name. For example, you could use regular expressions to check that the name contains only a common subset of characters and is not too big. The following C# code snippet shows the way that you can accomplish this:
Regex r = new Regex(@"^[\w]{1,40}$");

if (r.Match(strName).Success) {
// Cool! The string is ok
} else {
// Not cool! Invalid string
}
This code uses a regular expression to verify that a string contains between 1 and 40 alphanumeric characters and nothing else. This is the only safe way to determine whether a value is correct.
You cannot squeak HTML or script through this regular expression! Don't use a regular expression to look for invalid characters and reject the request if such characters are found because there is always a case that will slip by you.
The second defense is to HTML-encode all input when it is used as output. This will reduce dangerous HTML tags to more secure escape characters. You can escape any strings that might be a problem in ASP.NET with HttpServerUtility.HtmlEncode, or in ASP with Server.HTMLEncode.

4. Don't Require sa Permissions
The last kind of input trust attack we want to discuss is SQL injection. Many developers write code that takes input and uses that input to build SQL queries to communicate with a back-end data store, such as Microsoft® SQL Server™ or Oracle.
Take a look at the following code snippet:
void DoQuery(string Id) {
SqlConnection sql=new SqlConnection(@"data source=localhost;" +
"user id=sa;password=password;");
sql.Open();
sqlstring= "SELECT hasshipped" +
" FROM shipping WHERE id='" + Id + "'";
SqlCommand cmd = new SqlCommand(sqlstring,sql);
•••
This code is seriously flawed for three reasons. First, the connection is made from the Web Service to SQL Server as the system administrator account, sa. You'll see why this is bad, shortly. Second, notice the clever use of "password" as the password for the sa account!
However, the real cause for concern is the string concatenation that builds the SQL statement. If a user enters an ID of 1001, then you get the following SQL statement, which is perfectly valid and well formed.
SELECT hasshipped FROM shipping WHERE id = '1001'
However, attackers are more creative than this. They would enter an ID of "'1001' DROP table shipping --", which would execute the following query:
SELECT hasshipped FROM
shipping WHERE id = '1001'
DROP table shipping -- ';
This changes the way the query works. Not only does the code attempt to determine if something has shipped or not, it goes on to drop (delete) the shipping table! The -- operator is a comment operator in SQL and it makes it easier for an attacker to build a valid, yet dangerous, series of SQL statements!
At this point you're probably wondering how any user could delete a table in the SQL Server database. Surely only admins can do a task like that. You're right. But here you're connecting to the database as sa, and sa can do anything it wants to do on a SQL Server database. You should never connect as sa from any application to SQL Server; rather, you should either use Windows Integrated authentication, if appropriate, or connect as a predefined account with appropriately restricted rights.
Fixing the SQL injection issue is easy. Using SQL stored procedures and parameters, the following code shows how to build a query like this—and how to use a regular expression to make sure that the input is valid because our business dictates that a shipping ID can only be numeric and between four and ten digits in length:
Regex r = new Regex(@"^\d{4,10}$");
if (!r.Match(Id).Success)
throw new Exception("Invalid ID");

SqlConnection sqlConn= new SqlConnection(strConn);
string str="sp_HasShipped";
SqlCommand cmd = new SqlCommand(str,sqlConn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("@ID",Id);
Buffer overruns, cross-site scripting, and SQL injection attacks are all examples of trusting input. All these attacks can be mitigated by believing that all input is evil, until proven otherwise.

5. Watch that Crypto Code!
Now let's look at something near and dear to our hearts. I would say that more than 30 percent of the security code we review contains security mistakes. Probably the most common mistake is homegrown encryption code, which is typically quite fragile and easy to break. Never create your own encryption code; you won't get it right. Don't think that just because you've created your own cryptographic algorithm people won't figure it out. Attackers have access to debuggers, and they have both the time and the knowledge to determine exactly how these systems work—and often break them in a matter of hours. Rather, you should use the CryptoAPI for Win32® applications, and the System.Security.Cryptography namespace has a wealth of well-written and well-tested cryptographic algorithms.

6. Reduce Your Attack Profile
If a feature is not required by 90 percent of clients, then it should not be installed by default. Internet Information Services (IIS) 6.0 follows this plan of installation, and you can read about it in Wayne Berry's article, "Innovations in Internet Information Services Let You Tightly Guard Secure Data and Server Processes," in this month's issue. The idea behind this installation approach is that where services that you don't use are running, you don't pay attention to them and they can be exploited. If the feature is installed by default, then it should operate under the principle of least privilege. In other words, do not require the app to run with administrative rights if they are not required. Follow this advice as well.

7. Employ the Principle of Least Privilege
The operating system and the common language runtime (CLR) have a security policy for several reasons. Many people think that the main reason the security policy exists is to prevent users from intentionally doing bad things: accessing files they shouldn't be allowed to see, reconfiguring the network to suit their needs, and other dastardly deeds. While it's certainly true that insider attacks are common and need to be guarded against, there's another reason for keeping this security policy tight. The security policy is there to put walls around code so that intentional or (just as frequently) unintentional actions by users don't wreak havoc on the network. For instance, an attachment downloaded via e-mail and executed on Alice's machine is restricted to only accessing resources that Alice can access. If the attachment contains a Trojan horse, a good security policy will limit the damage it can do.
When you design, build, and deploy server applications, you cannot assume that every request will come from a legitimate user. If a bad guy manages to send you a malformed request that (heaven forbid) causes your code to behave badly, you want every possible wall around your application to limit the damage. Our point is that the reason your company has a security policy isn't just because it doesn't trust you or your code. It's also there to protect against well-intentioned code that's been exploited by outsiders.
The principle of least privilege says that any given privilege should be granted to the least amount of code necessary, for the least amount of time necessary. In other words, at any given time, try to erect as many walls around your code as possible. When something bad happens—as Murphy's Law guarantees it will—you'll be glad these walls were in place. So here are some concrete ideas for running code with the least privilege possible.
Choose a security context for your server code that grants access only to the resources it needs to get its work done. If certain parts of your code require significantly higher privileges, consider factoring the code out and running just that code with the higher privileges. To safely separate code that runs with different operating system credentials, your best bet is to run this code in a separate process that runs in a more privileged security context. This means you'll need interprocess communication such as COM or Microsoft .NET remoting, and you'll need to design the interface to that code to keep round-trips to a minimum.
If you're using the .NET Framework when factoring your code into assemblies, consider the required level of privilege of each piece of code. You may find it easy to isolate code that requires high privilege into separate assemblies that can be granted more permissions, allowing the majority of your assemblies to run with fewer privileges, thus adding more walls around your code. An easy way to restrict the privileges on a particular assembly is via assembly-level permission requests, as shown in Figure 1. Figure 2 shows how to create the XML files used by these permission requests. If you do this, don't forget that you're limiting not only the permissions of your own assembly, but those of any assemblies you call, due to the Code Access Security (CAS) stack walk.
Many people build their applications so that new components can be plugged in after their product has been tested and shipped. It's very difficult to secure these types of applications because there's no way you can test every possible code path for bugs and security holes. If your application is managed, however, there's a nifty feature provided by the CLR that you can use to lock down these extensibility points. By declaring a permission object or a permission set and calling PermitOnly or Deny, you add a marker on your stack that chokes down the permissions granted to any code you call. By doing this before calling to some plug-in, you can restrict what the plug-in can do. For instance, a plug-in that's supposed to do amortization calculations shouldn't need any access to the file system. This is just another example of least privilege, where you can protect yourself ahead of time. Be sure to document these restrictions and be aware that highly privileged plug-ins will be able to get around these restrictions with the Assert statement.

8. Pay Attention to Failure Modes
Admit it. You hate writing error handling code just as much as the next guy. There are so many ways a piece of code can fail; it's just depressing thinking about it. Most programmers, ourselves included, would much rather focus on the normal path of execution. That's where the real work gets done. Let's get that error handling done as quickly and painlessly as possible and move on to the next line of real code.
Sadly, this is not a safe frame of mind. We need to pay much closer attention to failure modes in code. These bits of code are often written with little attention to detail and often go completely untested. When was the last time you made absolutely sure you stepped your debugger through every single line of code in a function, including every single one of those little error handlers?
Untested code often leads to security vulnerabilities. There are three things you can do to help alleviate this problem. First of all, pay just as much attention to those little error handlers as you do your normal code. Think about the state of the system when your error-handling code is executing. Are you leaving the system in a valid and secure state? Second, once you write a function, step your debugger through it several times, ensuring that you hit every error handler. Note that even this technique may not uncover subtle timing errors. You may need to pass bad arguments to your function or adjust the state of the system in some way that causes your error handlers to execute. By taking the time to step through the code, you are slowing yourself down long enough to take at least a second look at the code and the state of the system at the time it runs. We've discovered many flaws in our programming logic by carefully stepping through code in a debugger; it's a proven technique. Use it. Finally, make sure your test suites force your functions to fail. Try to have test suites that exercise every line of code in your function. These can help you discover regression, especially if you automate your tests and run them after every build.
There's one more very important thing to say about failure modes. Be sure that if your code fails, it leaves the system in the most secure state possible. Here's some bad code:
bool accessGranted = true; // optimistic!
try {
// see if we have access to c:\test.txt
new FileStream(@"c:\test.txt",
FileMode.Open,
FileAccess.Read).Close();
}
catch (SecurityException x) {
// access denied
accessGranted = false;
}
catch (...) {
// something else happened
}
Let's say that as far as the CLR is concerned, we're granted access to the file. In this case, a SecurityException won't be thrown. But what if, for instance, the discretionary access control list (DACL) on the file doesn't grant us access? In this case, a different type of exception will be thrown. But due to our optimistic assumption in the first line of code, we'll never know this.
A better way to write this code is to be pessimistic:
bool accessGranted = false; // pessimistic!
try {
// see if we have access to c:\test.txt
new FileStream(@"c:\test.txt",
FileMode.Open,
FileAccess.Read).Close();
// if we're still here, we're good!
accessGranted = true;
}
catch (...) {}
This is much more robust, because no matter how we fail, we'll fall back to the most secure mode.

9. Impersonation is Fragile
When writing server applications, you'll often find yourself using, directly or indirectly, a convenient feature of Windows called impersonation. Impersonation allows each thread in a process to run in a distinct security context, typically the client's security context. For instance, when the file system redirector receives a request for a file via the network, it authenticates the remote client, checks to see that the client's request doesn't violate the DACL on the share, then attaches the client's token to the thread handling the request, thus impersonating the client. This thread can then access the local file system on the server using the security context of the client. This is convenient since the local file system is already secure; it will do an access check that considers the type of access being requested, the DACL on the file, and the impersonation token on the thread. If the access check fails, the local file system reports this to the file system redirector, who then can send a fault back to the remote client. This is incredibly convenient for the file system redirector because it simply passes the buck to the local file system and lets the local file system do its own access checking, just as if the client was local.
This is all well and good for simple gateways like the file system redirector. However, impersonation is often used in other, more complex applications. Take a Web application for instance. If you're writing a classic unmanaged ASP application, ISAPI extension, or an ASP.NET application which specifies in its Web.config file, you are running in an environment with two different security contexts: you have a process token and a thread token, and generally speaking, the thread token will be used for access checks (see Figure 3). Say you are writing an ISAPI application that runs inside the Web server process. Your thread token is likely IUSR_MACHINE, given that most requests are unauthenticated. But your process token is SYSTEM! Say your code is compromised by a bad guy via a buffer overflow exploit. Do you think the bad guy will be content with running as IUSR_MACHINE? No way. It's very likely that his attack code will call RevertToSelf to remove the impersonation token, hoping to elevate his privilege level. In this case, he'll succeed quite nicely. Another thing he can do is call CreateProcess. The token for that new process will be copied not from the impersonation token, but from the process token, so the new process runs as SYSTEM.
Figure 3 Checking
What's the solution to this little problem? Well, besides making sure you don't have any buffer overflows to begin with, remember the principle of least privilege. If your code doesn't need the god-like privileges afforded to SYSTEM, don't configure your Web application to run inside the Web server process. If you simply configure your Web application to run with medium or high isolation, your process token will be IWAM_MACHINE. You'll have virtually no privileges at all, and this sort of attack won't be nearly as effective. Note that in IIS 6.0, which will be a component of Windows .NET Server, no user-written code runs as SYSTEM by default. This is based on the realization that developers do make mistakes, and any assistance the Web server can provide to reduce the privileges given to code is a good thing, just in case there is a security bug in the code.
Here's another gotcha that COM programmers can run into. COM has a nasty tendency to play games with threads. If you make a call to an in-process COM server whose threading model doesn't match that of the calling thread, COM will execute the call on a different thread. COM will not propagate the impersonation token on the caller's thread, so the result is that the call will execute in the security context of the process, not of the calling thread. What a Surprise!
Here's another scenario where impersonation can bite you. Say you have a server that accepts requests via named pipes, DCOM, or RPC. You authenticate your clients and impersonate them, opening kernel objects on their behalf while impersonating. Let's say you forget to close one of these objects (for instance, a file) when the client disconnects. When the next client comes along, you authenticate and impersonate that client, and guess what? You can still access the file that was "leaked" from the previous client, even if the new client isn't granted access to the file. For performance reasons, the kernel only performs access checks on objects when you first open them. Even if your security context changes later on because you're impersonating somebody else, you will still be able to access this file.
Each of the scenarios we've mentioned so far is a reminder that impersonation is a convenience for server developers, and it's a fragile convenience at that. Pay close attention to your code when you're running with an impersonation token.

10. Write Apps that Non-admins Can Actually Use
This really is a corollary of the principal of least privilege. If programmers continue to produce code that doesn't run well on Windows unless the user is an administrator, how the heck can we ever expect to shake free of the stigma of targeting an "insecure" system? Windows has a very robust set of security features, but if users are forced to run as administrators to get anything done, they aren't getting much benefit from these features.
How can you help? Well first of all, eat your own dogfood. Quit running as an administrator yourself. You will learn very quickly the pain of using programs that were not designed with security in mind. The other day, I (Keith) installed some software provided by the maker of my handheld device that was designed to synchronize data between my desktop and the device. So just as I usually do, I logged off my normal user account, logged back in using the built-in administrator account, installed the software, then logged back to my normal account and tried to run the software. Well, the application promptly popped up a dialog saying it could not access some data file it needed, then proceeded to blow up with an access violation. Folks, this was a piece of software from a major vendor in the handheld space. There is no excuse for this!
After running FILEMON from http://sysinternals.com, I quickly discovered that the application was trying to open up a data file for write access that it had installed in the same directory as its executables. When applications are installed into the Program Files directory like they should be, they should never, ever, try to write data to that directory. There's a reason that Program Files has a restricted access control policy. We don't want users writing to those directories because that could easily allow one user to leave a Trojan horse behind for another user to execute. In fact, this stipulation is part of the basic logo requirements for Windows XP (see http://www.microsoft.com/winlogo).
We hear way too many programmers give excuses for why they choose to run as administrators when developing code. If we all keep ignoring the problem, it's only going to get worse. Folks, it doesn't take admin privileges to edit a text file. It doesn't take admin privileges to compile or debug a program that you started. When you need admin privileges, run individual programs with elevated privileges using the RunAs feature of the operating system (see the November 2001 Security Briefs column). If you are writing tools for developers to use, you have an extra responsibility to the community. We need to stop this vicious circle of folks writing code that only administrators can run, and the only way it's going to happen is if we do it at the grassroots level.
Check out Keith's Web site for more info on how developers can easily run as non-admins at http://www.develop.com/kbrown. Also be sure to pick up a copy of Michael's book, Writing Secure Code (Microsoft Press, 2001), which has tips on how to write apps that run well in a non-admin environment.

For related articles see:
SQL Server Security Modes
Avoiding Buffer Overruns

origin page : http://msdn2.microsoft.com/en-us/magazine/cc188938.aspx

Friday, March 14, 2008

Use volatile variable when control thread procedure closing

When writting a thread procedure , I've written below codes.

BOOL is_running = FALSE;
void thrd_proc(...)
{
while(!is_running)
{
update_windows();
}
}
void exit_program()
{
is_running = FALSE;
CloseHandle(thrd);
}

Thread procedure, thrd_proc is run only is_running is set to TRUE.
thrd_proc's work is update all windows interface.
When closing a program, I call an exit_program function.
An exit_program function set is_running variable to FALSE.
So that a thread procedure can exit an while loop.
That's looks like no problems.

However, when program close, this program will be occure an error.
I could know that still a thread procedure running via debugging.
And is_running value still TRUE.

Because a system optimize an is_running variable via is_running variable moving to CPU register, L1 cache or L2 cache from memory.
Thread access an is_running variable via memory that it's not changed.

To prevent this problem.
I should use volatile variable.
Just add volatile keyword before "BOOL is_running"

volatile BOOL is_running

Monday, March 10, 2008

Who is a programmer?

Who is programmer?

Answer : A sculling person.

Saturday, March 8, 2008

Create Window with WS_EX_LAYERED

When create an window with WS_EX_LAYERED style, an Window shown invisible.
Maybe window's alpha blend value is 0.
I wonder that it's bug or normal.

It can be shown correcting an alpha blend value.

CLayeredWindow* LW = new CLayeredWindow;
LW->CreateEx(WS_EX_LAYERED, _T("Layered"), 0, WS_CHILD WS_POPUP

WS_CLIPCHILDREN

WS_CLIPSIBLINGS


WS_THICKFRAME,

rect, this, 0,0);
LW->ShowWindow(SW_SHOW);
LW->SetLayeredWindowAttributes(0, 100, LWA_ALPHA);

Thursday, March 6, 2008

[MFC]Alpha blended LayeredWindow during changing an window's size

We are always want to make an window has special effects.


When user changing an window's size, we can make an alpha blended window during sizing.


After changed an window's size, window's alpha blend value shoud be origin value.


Here is an answer with codes, I've posted.


http://forums.microsoft.com/Forums/ShowPost.aspx?PostID=2950770&SiteID=1



Captured image that an window's size was being changed.


Sysinternals

Many peoples want to managing an own computer effectively.
Sysinternals make sure that anybody can be manage a computer easily with
useful program.
Especially Autoruns and ProcessExplorer is a powerful tools.

Use Carefully!!!
http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx

Monday, March 3, 2008

Office Automation Using Visual C++

Office Automation Using Visual C++
View products that this article applies to.
function loadTOCNode(){}
Article ID : 196776
Last Review : January 23, 2007
Revision : 6.2
This article was previously published under Q196776
On This Page
SUMMARY
MORE INFORMATION
Table of Contents
Questions and Answers

SUMMARY
loadTOCNode(1, 'summary');
This article answers common questions concerning Automation to Microsoft Office from Visual C++.
Back to the top
MORE INFORMATION
loadTOCNode(1, 'moreinformation');
Table of Contents
loadTOCNode(2, 'moreinformation');
1.What is Automation?
2.I'm new to Automation, where can I find good resources to learn more?
3.Are there different ways I can use Automation?
4.What is COM?
5.How do I attach to the running instance of an Office application?
6.How do I pass optional parameters?
7.How do I catch events exposed by the Office applications?
8.My automation code is too slow. How can I speed things up?
9.What do these huge error values, like -2147352573 or 0x80030002, mean?
10.What is a type library?
11.My automation code worked with Microsoft Excel 95, but fails with Microsoft Excel 97. Why?
12.Why does the application I'm automating stay in memory after my program is finished?
13.I know what I want to do as a Microsoft Office application user, but how do I do this programmatically using Automation?
14.Can I automate an embedded Microsoft Office application?
15.How do I access my document properties in a Microsoft Office document?
Back to the top
Questions and Answers
loadTOCNode(2, 'moreinformation');
1. What is Automation?Automation (formerly OLE Automation) is a technology that allows you to take advantage of an existing program's functionality and incorporate it into your own applications. For instance, you can utilize the Microsoft Word spelling and grammar checking capabilities into your application without Microsoft Word visible to your users. You can even use all of the Microsoft Excel charting, printing, and data analysis tools. This technology can greatly simplify and speed up your development.

2. I'm new to Automation, where can I find good resources to learn more? Chapter 24 of David Kruglinski's "Inside Visual C++" (ISBN:1-57231-565- 2) supplies a general overview as well as some great examples. Also, the Microsoft Knowledge Base is a good source of information. This article itself is a good start, and you can find more specific references in the following article in the Microsoft Knowledge Base:
152023 (http://support.microsoft.com/kb/152023/EN-US/) Locating Resources to Study OLE Automation If you prefer learning by example, please see the following article in the Microsoft Knowledge Base:
179706 (http://support.microsoft.com/kb/179706/EN-US/) HOWTO Use MFC to Automate Excel & Create/Format a New Workbook

3. Are there different ways I can use Automation?There are three basic ways you can use Automation: MFC, #import, and C/C++:
• With MFC, use the Visual C++ ClassWizard to generate "wrapper classes" from the Microsoft Office type libraries. These classes, as well as other MFC classes, such as COleVariant, COleSafeArray, COleException, simplify the tasks of Automation. This method is usually recommended over the others, and most of the Microsoft Knowledge Base examples use MFC.
• #import, a new directive that became available with Visual C++ 5.0, creates VC++ "smart pointers" from a specified type library. It is very powerful, but often not recommended because of reference- counting problems that typically occur when used with the Microsoft Office applications.
• C/C++ Automation is much more difficult, but sometimes necessary to avoid overhead with MFC, or problems with #import. Basically, you work with such APIs as CoCreateInstance(), and COM interfaces such as IDispatch and IUnknown.It is important to note that there are some slight differences between Automation from C++ compared to plain C, because COM was designed around the C++ class. For more information, please see the following article in the Microsoft Knowledge Base for a C example:
181473 (http://support.microsoft.com/kb/181473/EN-US/) HOWTO: Use OLE Automation from a C Application

4. What is COM?Automation is based on the Component Object Model (COM). COM is a standard software architecture based on interfaces, and designed to have code separated into self-contained objects. Think of it as an extension of the Object Oriented Programming (OOP) paradigm, but applicable to separate applications. Each object exposes a set of interfaces, and all communication to an object, such as initialization, notifications, and data transfer, happens through these interfaces.COM is also a set of services provided by dynamic-link libraries (DLLs) installed with the operating system. Automation uses many of those services. One example is the "Marshalling" service, which packages the client application's calls to the member functions of the server application's interfaces and passes those, with their arguments, to the server application. It makes it appear that the server's interfaces are exposed in the client's memory space, which is not the case when the client is an .exe running in its own process space. Marshalling also gets the return values from the server's methods back across the process boundaries and safely into the hands of the client's call. There are many other services essential to Automation that are provided by the various COM libraries. Sources of information about those include "Inside Ole - Second Edition" by Kraig Brockschmidt, ISBN 1-55615-843-2, "Inside COM" by Dale Rogerson - ISBN 1-57231-349-8, and "Automation Programmer's Reference," ISBN 1-57231-584-9.

5. How do I attach to the running instance of an Office application?Use the GetActiveObject() API. Automation servers register themselves in the ROT (Running Object Table), via the RegisterActiveObject() API. Automation clients can get at the running instance with code such as:

// Translate server ProgID into a CLSID. ClsidFromProgID
// gets this
information from the registry.
CLSID
clsid;
CLSIDFromProgID(L"Excel.Application", &clsid);
// Get an
interface to the running instance, if any..
IUnknown *pUnk;
HRESULT hr =
GetActiveObject(clsid, NULL,
(IUnknown**)&pUnk);
ASSERT(!FAILED(hr));
// Get IDispatch interface
for Automation...
IDispatch *pDisp;
hr =
pUnk->QueryInterface(IID_IDispatch, (void **)&pDisp);
ASSERT(!FAILED(hr));
// Release the no-longer-needed
IUnknown...
pUnk->Release();
NOTE: If there are multiple instances running of the Office application you want to attach, you will only be able to attach to the first instance that was launched using the GetActiveObject() API.Theoretically, you can iterate the ROT for each individual instance, but the Office apps don't register themselves if another instance is already in the ROT because the moniker for itself is always the same (it couldn't be distinguished anyway). This means that you can't attach to any instance except for the first. However, because the Office apps also register their documents in the ROT, you can successfully attach to other instances by iterating the ROT looking for a specific document, attaching to it, then getting the Application object from it. There is some code in the following Microsoft Knowledge Base article for iterating the ROT and looking for a document name:
190985 (http://support.microsoft.com/kb/190985/EN-US/) HOWTO: Get IDispatch of an Excel or Word Document From an OCX You won't need to do this for PowerPoint, because it is a single- instance application; you can only have one instance of it running.

6. How do I pass optional parameters?Some methods have "optional" parameters. In Visual Basic, you can casually omit them when calling the method. However, when calling with Visual C++ you have to pass a special VARIANT whose .vt field is VT_ERROR, and .scode field is DISP_E_PARAMNOTFOUND. That is:

// VARIANT used in place of optional-parameters.
VARIANT
varOpt;
varOpt.vt = VT_ERROR;
varOpt.scode = DISP_E_PARAMNOTFOUND;
This is really what Visual Basic is doing behind-the-scenes.

7. How do I catch events exposed by the Office applications?Basically you implement the event interface you want to catch (the "sink"), and setup an advisory connection with the application (the "source"). The following article gives you step-by-step examples for Microsoft Word:
183599 (http://support.microsoft.com/kb/183599/EN-US/) HOWTO: Catch Microsoft Word97 Application Events Using VC++ In general, to setup the advisory connection, you get the server's IConnectionPointContainer and call FindConnectionPoint() with the IID of the event interface. This gives you an IConnectionPoint interface and all that's left is to call Advise() with an instance of your event interface. The server will then call back through this interface when these events occur.

8. My automation code is too slow. How can I speed things up?A common cause of speed problems with Automation is with repetitive reading and writing of data. This is typical for Excel Automation clients. However, most people aren't aware that this data can usually be written or read all at once using SAFEARRAY. See the following Microsoft Knowledge Base articles for more information and informative examples:
186120 (http://support.microsoft.com/kb/186120/EN-US/) HOWTO: Use MFC to Automate Excel and Fill a Range with an Array
186122 (http://support.microsoft.com/kb/186122/EN-US/) HOWTO: Use MFC to Automate Excel & Obtain an Array from a Range
179706 (http://support.microsoft.com/kb/179706/EN-US/) HOWTO: Use MFC to Automate Excel and Create/Format a New Workbook Also, it is important to point out that using the clipboard can sometimes improve performance. For instance, you can copy your data to the clipboard, then use automation to tell the server to paste. Or vice- versa; tell the server to copy-to-clipboard, and paste into your application.

9. What do these huge error values, such as -2147352573, or 0x80030002 mean?These values are known as HRESULTs and are defined in winerror.h. The numbers are so large because the first bit represents whether or not it is an error result. You can use the ErrLook.Exe utility that comes with Visual C++ to translate these numbers into meaningful descriptions.If you want to programmatically obtain a description for the errors, you can use the FormatMessage() API. See the following Microsoft Knowledge Base articles for more information and examples on the use of FormatMessage():
186063 (http://support.microsoft.com/kb/186063/EN-US/) INFO: Translating Automation Errors for VB/VBA
122957 (http://support.microsoft.com/kb/122957/EN-US/) SAMPLE: Decode32 and Decode16 OLE Error Code Decoder ToolsNOTE: If you are using Visual C++ 6.0 and have a variable containing this value in the debug watch window, append ", hr" (without the quotes) to it to have Visual C++ translate it for you!

10. What is a type library?A type library is similar to a C/C++ header file. It contains the interfaces, methods, and properties that a server is publishing. You can view the type library with the OLE/COM Object Viewer (Oleview.exe) that comes with Visual C++. Here is a list of the type library filenames for Microsoft Office 95, 97, and 2000: Office Application Type library
------------------------+----------------
Word 95 and prior wb70en32.tlb
Excel 95 and prior xl5en32.olb
Powerpoint 95 and prior Powerpoint.tlb
Access 95 and prior msaccess.tlb
Binder 95 binder.tlb
Schedule+ sp7en32.olb
Project pj4en32.olb
Team Manager mstmgr1.olb
Word 97 msword8.olb
Excel 97 excel8.olb
Powerpoint 97 msppt8.olb
Access 97 msacc8.olb
Binder 97 msbdr8.olb
Graph 97 graph8.olb
Outlook 97 msoutl8.olb
Outlook 98 msoutl85.olb
Word 2000 msword9.olb
Excel 2000 excel9.olb
Powerpoint 2000 msppt9.olb
Access 2000 msacc9.olb
Outlook 2000 msoutl9.olb
Word 2002 msword.olb
Excel 2002 excel.exe
Powerpoint 2002 msppt.olb
Access 2002 msacc.olb
Outlook 2002 msoutl.olb

1. My automation code worked with Excel 95, but fails with Excel 97. What's happening?The object model for Excel made a significant change from version 95 to 97. Excel 95 implemented all its methods and properties in a single implementation of IDispatch. This meant that often you could call methods meant for object X, from object Y. This was not a good design, so in Office 97, each object has its own separate Idispatch implementation. This means that if you ask for a method or property from object X from a separate object Y, you get the error 0x80020003, -2147352573, "Member not found." To avoid this error, you need to make sure that the underlying IDispatch interface you are making calls from is the semantically correct one. See the following Microsoft Knowledge Base articles for more information:
172108 (http://support.microsoft.com/kb/172108/EN-US/) HOWTO: Troubleshooting "Member not found", 0x80020003 Error

2. The application I'm automating stays in memory after my program is finished. What's happening?Most likely, this is because you have forgotten to release an acquired interface and you'll need to track it down. Here are some general suggestions, and things to looks for:
• If you're using #import, it is very likely you could be running into one of the reference-counting bugs associated with it. Often times the bugs can be worked around, but usually it is preferred to use one of the other Automation methods. #import doesn't work very well with the Office applications, because its type libraries and use are fairly complex. Also, such reference counting problems are hard to track down because a lot of the interface-level COM calls are behind-the-scenes when using #import.
• Check to see if you are calling any methods, such as Open, or New, that return an IDispatch * (LPDISPATCH), and ignoring the return value. If you are, then you are abandoning this returned interface and will need to change your code so that you release it when no longer needed.
• Gradually comment out sections of your code until the problem disappears, then add it back judiciously to track down where the problem starts.
• Note that some applications will stay running if the user has "touched" the application. If this occurs while you are automating, then the application will probably stay running afterwards. The Office applications have a "UserControl" property on the Application object that you can read/write to change this behavior.
• Also, some applications will decide to stay running if enough user-interface "action" has occurred. If you are intending the application to exit, then call its Quit() method on the Application object. Word will shutdown regardless of its reference count when Quit is called. This isn't expected COM behavior. Excel, however, will properly just hide itself but stay running until all outstanding interfaces are released. In general, you should release all outstanding references, and only call Quit() if you intend the application to quit.

3. I know what I want to do as a Office application user, but how do I do this programmatically through Automation?What you are interested in is what objects, methods, and properties you need to use. The best way to learn how to navigate the object models of Word, Excel, and Powerpoint, based on what you want to do as a user, is to use the Macro Recorder. Just choose Macro\'Record New Macro' from the Tools menu, execute the task you're interested in, then choose Macro\'Stop Recording.' Once you're done recording, choose Macro\Macros from the Tools menu, select the macro you recorded, then click Edit. This will take you to the generated VBA code that will accomplish the task you recorded. Keep in mind the recorded macro won't be the best possible code in most cases, but it's does very well for a quick example.

4. Can I automate an embedded Office application?Absolutely. The trick is getting the IDispatch pointer: this is given in the Visual C++ Technical Note 39 (TN039). See the following Microsoft Knowledge Base article for a step-by-step example:
184663 (http://support.microsoft.com/kb/184663/EN-US/) HOWTO: Embed and Automate a Microsoft Excel Worksheet With MFC

5. How do I access my document properties in an Office document?The document properties are accessible through Automation, or directly through IPropertyStorage. The following Microsoft Knowledge Base articles demonstrate each method:
179494 (http://support.microsoft.com/kb/179494/EN-US/) HOWTO: Use Automation to Retrieve Built-In Document Properties
186898 (http://support.microsoft.com/kb/186898/EN-US/) HOWTO: Read Compound Document Properties Directly with VC++

Origin Articles : http://support.microsoft.com/kb/196776

Saturday, March 1, 2008

Pattern Oriented Software Architecture Vol.1 [POSA]

Currently, I'm developing a software with Copy & Paste.
It's really bother work, takes long long times.
So I decided to applying a design patterns to my job.
And I ordered a book, Pattern Oriented Software Architect.
I have a preconception that this book will be tedious and scholarstic.
However this book described a key what shoud I have to do.
Especially Model View Controller pattern can be so for my job.
And each introduced patterns are specified problems, requirements, solutions and known uses.
I recommand this book for programmer , working with infinite Copy & Paste.

Powered By Blogger