11. Allow Long Passwords
Versions of Windows prior to Windows 2000 allowed 14-character passwords, Windows 2000 supports passwords up to 127 characters. Don't hard-code 14-character password limits in your application.
12. Clear Out Unused Secrets
Zero out secret data once it no longer has any use. Whether the data is stored temporarily in memory or written to disk, overwrite the data once you have finished using it. It is possible that secret data may be written to the pagefile. At the very least, use ZeroMemory() to scrub the data. If you are truly paranoid, which isn't a bad thing, use code like this:
void Scrub(LPVOID pBlob, DWORD cbBlob) {
const int iParanoiaLevel = 7;
for (int i=0; i < iParanoiaLevel; i++) {
memset(pBlob,0xFF,cbBlob); // all 1's
memset(pBlob,0x00,cbBlob); // all 0's
memset(pBlob,0xAA,cbBlob); // 10101010
memset(pBlob,0x55,cbBlob); // 01010101
}
ZeroMemory(pBlob,cbBlob);
}
13. Check the Return Conditions from All Security-Related Functions
Checking return values is standard programming practice, but it is doubly important when a security function fails. For example, I once saw some code that called RpcImpersonateClient() but failed to check whether the function succeeded or that its return status was RPC_S_OK. I missed that the next line of code accessed some sensitive data and returned it to the user. What's tricky is a call may be made in the context of the calling thread if the impersonation fails, which in this case was LocalSystem. The ACL on the resource being accessed included only those with Administrators (full control) and SYSTEM (full control) status; all other users should have been denied access. However, upon impersonation failure, the user gains access to the resource...very bad!
14. Write to the Event Log
Log anything that relates to security to the Windows NT/2000 event log, such as failed access to your private objects for example. Don't log anything that the OS may already log such as logon and logoff, it just creates more work for admins. Use the RegisterEventSource() and ReportEvent() functions. If you are writing scripts, then use the Windows Script Host WScript.Shell object, it has a LogEvent method.
15. Document Your Interfaces
Document the named pipes, sockets, RPC and DCOM protocols, and ports you use. This has two benefits: (1) it helps firewall admins determine which ports to open on the perimeter and (2) helps the testers determine how to test the interface.
The Checklist You've Been Waiting For
Keep these tips closeby and refer to them whenever you get into your Win32 programming. Now you have the security checklist that's been missing from your Win32 documentation. Don't say I never gave you anything.
Michael Howard is a program manager on the Windows 2000 security team. He is the author of Designing Secure Web-Based Applications for Microsoft Windows 2000 and has spoken about security-related issues at many events, including Microsoft Tech·Ed, Microsoft Professional Developer's Conferences, and numerous industry gatherings. He can be reached at mikehow@microsoft.com.