Presentation is loading. Please wait.

Presentation is loading. Please wait.

Security Development Lifecycle: Development Practices Michael Howard Principal Security Program Manager Microsoft Corp. Stuff you.

Similar presentations


Presentation on theme: "Security Development Lifecycle: Development Practices Michael Howard Principal Security Program Manager Microsoft Corp. Stuff you."— Presentation transcript:

1 Security Development Lifecycle: Development Practices Michael Howard Principal Security Program Manager Microsoft Corp. Stuff you can use!

2 Who is this Guy? Microsoft employee for >15 years Always in security Editor for IEEE Security & Privacy A pragmatist!

3 What *IS* the SDL? A set of design, development, testing and post-release security and privacy-related software process improvements The goal is to improve security and privacy by: Reducing the number of vulnerabilities in shipping software Reducing the severity of remaining vulnerabilities SDL works!

4 SDL Works!

5 We actually consider Microsoft to be leading the software [industry] now in improvements in their security development life cycle [SDL]. John Pescatore Vice President and Distinguished Analyst Gartner, Inc (From CRN, Feb 13 th 2006) Security Development Lifecycle Demonstrating Results

6 Security Development Lifecycle

7 SDL Requirements vs Recommendations Some development practices are requirements Must be followed in order to ship Some development practices are recommendations Good to have

8 Some Functionality is Just Bad Some functions were fine 20 years ago! But the threats have changed Some functions are hard to use securely! So we banned approx 120 C runtime functions And we will continue to ban other functions too

9 Banned APIs strcpy, strcpyA, strcpyW, wcscpy, _tcscpy, _mbscpy, StrCpy, StrCpyA, StrCpyW, lstrcpy, lstrcpyA, lstrcpyW, _tccpy, _mbccpy strcat, strcatA, strcatW, wcscat, _tcscat, _mbscat, StrCat, StrCatA, StrCatW, lstrcat, lstrcatA, lstrcatW, StrCatBuff, StrCatBuffA, StrCatBuffW, StrCatChainW, _tccat, _mbccat strncpy, wcsncpy, _tcsncpy, _mbsncpy, _mbsnbcpy, StrCpyN, StrCpyNA, StrCpyNW, StrNCpy, strcpynA, StrNCpyA, StrNCpyW, lstrcpyn, lstrcpynA, lstrcpynW strncat, wcsncat, _tcsncat, _mbsncat, _mbsnbcat, StrCatN, StrCatNA, StrCatNW, StrNCat, StrNCatA, StrNCatW, lstrncat, lstrcatnA, lstrcatnW, lstrcatn CharToOem, CharToOemA, CharToOemW, OemToChar, OemToCharA, OemToCharW, CharToOemBuffA, CharToOemBuffW alloca, _alloca wnsprintf, wnsprintfA, wnsprintfW, sprintfW, sprintfA, wsprintf, wsprintfW, wsprintfA, sprintf, swprintf, _stprintf, _snwprintf, _snprintf, _sntprintf, wvsprintf, wvsprintfA, wvsprintfW, vsprintf, _vstprintf, vswprintf, _vsnprintf, _vsnwprintf, _vsntprintf, wvnsprintf, wvnsprintfA, wvnsprintfW strtok, _tcstok, wcstok, _mbstok makepath, _tmakepath, _makepath, _wmakepath, _splitpath, _tsplitpath, _wsplitpath scanf, wscanf, _tscanf, sscanf, swscanf, _stscanf, snscanf, snwscanf, _sntscanf _itoa, _itow, _i64toa, _i64tow, _ui64toa, _ui64tot, _ui64tow, _ultoa, _ultot, _ultow gets, _getts, _gettws IsBadWritePtr, IsBadHugeWritePtr, IsBadReadPtr, IsBadHugeReadPtr, IsBadCodePtr, IsBadStringPtr strlen, wcslen, _mbslen, _mbstrlen, StrLen, lstrlen

10 Banned Function and Tools Use of banned functions caught during development Warning C4996 This function or variable may be unsafe. Consider using XXXXX instead. Included in Visual Studio 2005 Or use #include banned.h

11 Banned Function Replacements Safe CRT Included in Visual Studio 2005 Strsafe Included in Visual Studio 2005 and Windows SDK

12 Auto-replacement of Banned Functions If the compiler knows the destination buffer size at compile time, it can automatically generate secure code Included in Visual Studio 2005 and Windows SDK char buf[32]; strcpy(buf,src); char buf[32]; strcpy_s(buf,src,32);

13 Standard Annotation Language Used by static analysis tools such as /analyze (Visual Studio 2005 and Windows SDK) Benefits of adding annotations to your code: Help the tools find hard to find bugs The process of adding annotations finds bugs! Bugs found are low noise

14 SAL at Work void FillString( TCHAR* buf, size_t cchBuf, TCHAR ch) { for (size_t i = 0; i < cchBuf; i++) { buf[i] = ch; } These two arguments are related, but the compiler does not know!

15 SAL at Work void FillString( __out_ecount(cchBuf) TCHAR* buf, size_t cchBuf, TCHAR ch) { for (size_t i = 0; i < cchBuf; i++) { buf[i] = ch; }

16 SAL at Work __out_ecount(cchBuf) Out buffer, function will write to the buffer. Other examples include __in and __inout Element count. Other example includes bcount, byte count. __checkReturn __bcount_opt(_Size) malloc(__in size_t _Size); Optional, can be NULL Must check return value

17 SAL at Work Warning C6386: Buffer overrun: accessing 'argument 1', the writable size is 200*2' bytes, but '420' bytes might be written: Lines: 33, 34 Warning C6387: 'argument 1' might be '0': this does not adhere to the specification for the function 'FillString': Lines: 33, 34 void FillString( __out_ecount(cchBuf) TCHAR* buf, size_t cchBuf, TCHAR ch) { for (size_t i = 0; i < cchBuf; i++) { buf[i] = ch; } void main() { TCHAR *buff = malloc(200 * sizeof(TCHAR)); FillString(buff,210,_T(x)); }

18 Integer Overflows Three flavors Overflow and underflow Truncation Signed vs unsigned Very common C/C++ bug Lead to buffer overruns

19 Integer Overflow Remedies Compile with the latest C/C++ compiler Visual Studio 2005 Automatically protects against operator::new overflows Review code that allocates memory to determine if the calculation could be influenced by an attacker Use integer manipulation functions IntSafe (C functions, MSDN download) SafeInt (C++ class, Visual Studio 2005)

20 Is this a Security Bug? void *MyMalloc(const size_t cbAlloc) { size_t cbTotal = cbAlloc + SIG_BLOCK_LEN; void *p = malloc(cbTotal); if (!p) return NULL; memcpy((char*)p+cbAlloc,SIG_BLOCK,SIG_BLOCK_LEN); return p; }

21 A Fix using IntSafe void *MyMalloc(const size_t cbAlloc) { size_t cbTotal; if (SizeTAdd(cbAlloc, SIG_BLOCK_LEN, &cbTotal) != S_OK) return NULL; void *p = malloc(cbTotal); if (!p) return NULL; memcpy((char*)p+cbAlloc,SIG_BLOCK,SIG_BLOCK_LEN); return p; }

22 No Weak Crypto No new code must use: MD4, MD5, SHA1 (use SHA2 suite) DES (use AES) RC4 (without crypto review) No symmetric keys <128 bits No RSA keys < 1024 bits No weak random number generation No embedded secrets Be crypto agile

23 No Weak ACLs on Objects A weak permission could render an installation open to privilege elevation bugs No weak ACLs, and no NULL DACLs Tools constantly scan products for weak DACLs Diff versions

24 Compiler Flag Requirements C/C++ /GS Linker /SAFESEH /NXCOMPAT /DYNAMICBASE RPC and DCOM MIDL /STRICT

25 /GS – Stack Overflow Detection BuffersNon-BuffersEBPEIPArgs Non-BuffersBuffersEBPEIPArgs Cookie Args Normal Stack Stack after Visual Studio 2005 /GS

26 /SAFESEH Exception Handler Protection Would have prevented CodeRed During compilation exception handler target addresses are written to PE header At runtime, the OS checks any exception against the list in the PE header Detected through tool use

27 Other Important Linker Flags /NXCOMPAT Your application can take advantage of DEP/NX/XD /DYNAMICBASE Works on Windows Vista and Windows Server 2008 Moves your image around in memory Moves your stack around Both make attacks less predictable

28 /STRICT MIDL flag Creates more robust proxy and stub code Uses the IDL definitions to greater effect

29 A Note About Tools Tools DO NOT MAKE CODE SECURE! They help scale the process They help enforce policy Common tools: PREfast SAL FxCop AppVerif CodeCoverage Constantly upgrading our compilers to add new defenses

30 Heap Corruption Detection A new heap flag in Windows Vista Applies only to apps that run on Vista Ignored pre-Vista Fails the app if heap block metadata is corrupted HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);

31 Web-Specific Requirements Were still seeing the same Web-specific vulns we saw years ago They now apply to Web 2.0 apps too People are producing insecure code very quickly

32 XSS Defenses Hand review all untrusted data entry and exit points Is the data valid and/or scrubbed? Use the AntiXss library Consider HttpOnly cookies

33 SQL Injection Defenses No SQL statements built with string concatenation Use prepared statements instead Deny Access to Underlying Database Objects Granting access only to views and stored procedures means that attacks that read other database objects will fail

34 SQL Injection and LINQ LINQ does a great job mitigating SQL Injection vulns Because it uses prepared statements under the covers var q = from c in db.Customers where c.City == "London" select c.ContactName; SELECT [t0].[ContactName] FROM [dbo].[Customers] AS [t0] WHERE [t0].[City] Input NVarChar (Size = 6; Prec = 0; Scale = 0) [London] Translates to

35 Sidebar (literally!): A Look at Gadgets Windows Vista Sidebar hosts Gadgets written in HTML, JavaScript and often ActiveX controls You should treat Gadgets as fully trusted code with complete access to the system System.Sidebar.Execute Gadgets are susceptible to client-side XSS issues Validate all your incoming data Code review for insecure use of: innerHtml document.write Eval Read Inspect your Gadget Michael Howard & David Ross

36 Call to Action Process Evaluate the SDL (it works!) Utilize all available tools (eg; compiler, /analyze, SAL etc) Engineering Remove banned APIs No weak crypto Compile with /GS Link with /NXCOMPAT, /SAFESEH and /DYNAMICBASE

37 There will be a book signing at Booth 22 after this session.

38 QUESTIONS?

39 Resources Technical Communities, Webcasts, Blogs, Chats & User Groups Microsoft Learning and Certification Microsoft Developer Network (MSDN) & TechNet Trial Software and Virtual Labs ult.mspx ult.mspx New, as a pilot for 2007, the Breakout sessions will be available post event, in the TechEd Video Library, via the My Event page of the website Required slide: Please customize this slide with the resources relevant to your session MSDN Library Knowledge Base Forums MSDN Magazine User Groups Newsgroups E-learning Product Evaluations Videos Webcasts V-labs Blogs MVPs Certification Chats learn support connect subscribe Visit MSDN in the ATE Pavilion and get a FREE 180-day trial of MS Visual Studio Team System!

40 Complete your evaluation on the My Event pages of the website at the CommNet or the Feedback Terminals to win!

41 © 2007 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.

42 Backup Slides

43 A Sample Scenario An imaginary game server Runs as SYSTEM Enumerates and hashes saved games to send to the user Saved game file name comes from a valid user over UDP In some code examples, error checking is removed for brevity

44 Startup() EnumAndHashFiles() GetFileFromUser() HashOneFile() AddFileDataToList() SYSTEM 30,000 ft. View of the Code UDP Gimme the saved game

45 ServiceMain() Startup() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() VOID WINAPI Startup(DWORD dwArgc,LPTSTR* lpszArgv) { // Initialization code // Setup threads // Create UDP listener while (true) { // Get directory from user over RPC wchar_t *wszDir = GetDirFromUser(); EnumAndHashFiles(wszDir); }

46 ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() ServiceMain() VOID WINAPI Startup(DWORD dwArgc,LPTSTR* lpszArgv) { // Initialization code // Setup threads // Create UDP listener while (true) { // Get directory from user over RPC wchar_t *wszDir = GetDirFromUser(); EnumAndHashFiles(wszDir); } Run as network service

47 ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() VOID WINAPI ServiceMain(DWORD dwArgc,LPTSTR* lpszArgv) { // Initialization code // Setup threads // Create UDP listener HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0); LPCWSTR wszPrivs [] = { SE_TAKE_OWNERSHIP_NAME, SE_DEBUG_NAME, SE_CREATE_TOKEN_NAME, SE_ASSIGNPRIMARYTOKEN_NAME, SE_TCB_NAME, SE_SECURITY_NAME, SE_LOAD_DRIVER_NAME, SE_SYSTEMTIME_NAME, SE_BACKUP_NAME, SE_RESTORE_NAME, SE_SHUTDOWN_NAME, SE_AUDIT_NAME}; DropUnusedPrivs(wszPrivs,_countof(wszPrivs)); while (true) { // Get directory from user over RPC wchar_t *wszDir = GetDirFromUser(); EnumAndHashFiles(wszDir); } Terminate if a heap overflow occurs Drop unneeded privileges

48 EnumAndHashFiles() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool EnumAndHashFiles(wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy(wszPath2,(wchar_t*)wszPath); wcscat(wszPath2,L"\\*.*"); if (!CryptAcquireContext(&g_hProv, NULL,NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return false; WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile(wszPath2,&ffd); while (h != INVALID_HANDLE_VALUE) { wchar_t wszFilename[MAX_PATH]; _snwprintf(wszFilename, sizeof(wszFilename), L"%s\\%s", wszPath,ffd.cFileName); HashOneFile(wszFilename); if (!FindNextFile(h,&ffd)) break; } CryptReleaseContext(g_hProv,0); FindClose(h); return fRet; }

49 EnumAndHashFiles() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool EnumAndHashFiles(__in_z wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy(wszPath2,(wchar_t*)wszPath); wcscat(wszPath2,L"\\*.*"); if (!CryptAcquireContext(&g_hProv, NULL,NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return false; WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile(wszPath2,&ffd); while (h != INVALID_HANDLE_VALUE) { wchar_t wszFilename[MAX_PATH]; _snwprintf(wszFilename, sizeof(wszFilename), L"%s\\%s", wszPath,ffd.cFileName); HashOneFile(wszFilename); if (!FindNextFile(h,&ffd)) break; } CryptReleaseContext(g_hProv,0); FindClose(h); return fRet; } Add SAL annotation to detect bugs

50 EnumAndHashFiles() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool EnumAndHashFiles(__in_z wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy_s(wszPath2,__countof(wszPath2),(wchar_t*)wszPath); wcscat_s(wszPath2,__countof(wszPath2),L"\\*.*"); if (!CryptAcquireContext(&g_hProv, NULL,NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) return false; WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile(wszPath2,&ffd); while (h != INVALID_HANDLE_VALUE) { wchar_t wszFilename[MAX_PATH]; swprintf_s(wszFilename, sizeof(wszFilename), L"%s\\%s", wszPath,ffd.cFileName); HashOneFile(wszFilename); if (!FindNextFile(h,&ffd)) break; } CryptReleaseContext(g_hProv,0); FindClose(h); return fRet; } Add SAL annotation to detect bugs Replace Banned APIs

51 EnumAndHashFiles() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool EnumAndHashFiles(__in_z wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy_s(wszPath2,__countof(wszPath2),(wchar_t*)wszPath); wcscat_s(wszPath2,__countof(wszPath2),L"\\*.*"); if (!CryptAcquireContext(&g_hProv, NULL,NULL, GetCryptoProvider(), CRYPT_VERIFYCONTEXT)) return false; WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile(wszPath2,&ffd); while (h != INVALID_HANDLE_VALUE) { wchar_t wszFilename[MAX_PATH]; swprintf_s(wszFilename, sizeof(wszFilename), L"%s\\%s", wszPath,ffd.cFileName); HashOneFile(wszFilename); if (!FindNextFile(h,&ffd)) break; } CryptReleaseContext(g_hProv,0); FindClose(h); return fRet; } Add SAL annotation to detect bugs Replace Banned APIs Crypto Agility Get crypto provider from configuration

52 EnumAndHashFiles() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool EnumAndHashFiles(__in_z wchar_t *wszPath) { bool fRet = false; wchar_t wszPath2[128]; wcscpy_s(wszPath2,__countof(wszPath2),(wchar_t*)wszPath); wcscat_s(wszPath2,__countof(wszPath2),L"\\*.*"); if (!CryptAcquireContext(&g_hProv, NULL,NULL, GetCryptoProvider(), CRYPT_VERIFYCONTEXT)) return false; WIN32_FIND_DATA ffd; HANDLE h = FindFirstFile(wszPath2,&ffd); while (h != INVALID_HANDLE_VALUE) { wchar_t wszFilename[MAX_PATH]; swprintf_s(wszFilename, __countof(wszFilename), L"%s\\%s", wszPath,ffd.cFileName); HashOneFile(wszFilename); if (!FindNextFile(h,&ffd)) break; } CryptReleaseContext(g_hProv,0); FindClose(h); return fRet; } Add SAL annotation to detect bugs Replace Banned APIs Static Analysis: Byte count vs. character count mismatch Crypto Agility Get crypto provider from configuration

53 HashOneFile() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool HashOneFile(wchar_t *wszFilename) { HANDLE hFile = CreateFile(wszFilename, GENERIC_READ,0,NULL, OPEN_EXISTING,0,NULL); if (INVALID_HANDLE_VALUE == hFile) return false; HCRYPTHASH hHash = NULL; if (CryptCreateHash(g_hProv,CALG_SHA1,0,0,&hHash)) { const int cbBuff = 16384; BYTE *pBuff = new BYTE[cbBuff]; while (true) { DWORD cbRead = 0; BOOL fReadOK = ReadFile(hFile,pBuff,cbBuff,&cbRead,NULL); if (!cbRead) break; CryptHashData(hHash,pBuff,cbRead,0); } DWORD cbHash = 160 / 8; BYTE bHash[160 / 8]; CryptGetHashParam(hHash,HP_HASHVAL,&bHash[0],&cbHash,0); AddFileDataToList(wszFilename,bHash,cbHash); free(pBuff); CryptDestroyHash(hHash); } CloseHandle(hFile); return true; }

54 HashOneFile() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool HashOneFile(__in_z wchar_t *wszFilename) { HANDLE hFile = CreateFile(wszFilename, GENERIC_READ,0,NULL, OPEN_EXISTING,0,NULL); if (INVALID_HANDLE_VALUE == hFile) return false; HCRYPTHASH hHash = NULL; if (CryptCreateHash(g_hProv,CALG_SHA1,0,0,&hHash)) { const int cbBuff = 16384; BYTE *pBuff = new BYTE[cbBuff]; while (true) { DWORD cbRead = 0; BOOL fReadOK = ReadFile(hFile,pBuff,cbBuff,&cbRead,NULL); if (!cbRead) break; CryptHashData(hHash,pBuff,cbRead,0); } DWORD cbHash = 160 / 8; BYTE bHash[160 / 8]; CryptGetHashParam(hHash,HP_HASHVAL,&bHash[0],&cbHash,0); AddFileDataToList(wszFilename,bHash,cbHash); free(pBuff); CryptDestroyHash(hHash); } CloseHandle(hFile); return true; } Add SAL annotation to detect bugs

55 HashOneFile() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool HashOneFile(__in_z wchar_t *wszFilename) { HANDLE hFile = CreateFile(wszFilename, GENERIC_READ,0,NULL, OPEN_EXISTING,0,NULL); if (INVALID_HANDLE_VALUE == hFile) return false; HCRYPTHASH hHash = NULL; if (CryptCreateHash(g_hProv,GetHashAlg(),0,0,&hHash)) { const int cbBuff = 16384; BYTE *pBuff = new BYTE[cbBuff]; while (true) { DWORD cbRead = 0; BOOL fReadOK = ReadFile(hFile,pBuff,cbBuff,&cbRead,NULL); if (!cbRead) break; CryptHashData(hHash,pBuff,cbRead,0); } DWORD cbHash = 160 / 8; BYTE bHash[160 / 8]; CryptGetHashParam(hHash,HP_HASHVAL,&bHash[0],&cbHash,0); AddFileDataToList(wszFilename,bHash,cbHash); free(pBuff); CryptDestroyHash(hHash); } CloseHandle(hFile); return true; } Add SAL annotation to detect bugs Replace Banned hash function Crypto-Agility Get hash alg from configuration

56 HashOneFile() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() bool HashOneFile(__in_z wchar_t *wszFilename) { HANDLE hFile = CreateFile(wszFilename, GENERIC_READ,0,NULL, OPEN_EXISTING,0,NULL); if (INVALID_HANDLE_VALUE == hFile) return false; HCRYPTHASH hHash = NULL; if (CryptCreateHash(g_hProv,GetHashAlg(),0,0,&hHash)) { const int cbBuff = 16384; BYTE *pBuff = new BYTE[cbBuff]; while (true) { DWORD cbRead = 0; BOOL fReadOK = ReadFile(hFile,pBuff,cbBuff,&cbRead,NULL); if (!cbRead) break; CryptHashData(hHash,pBuff,cbRead,0); } DWORD cbHash = 160 / 8; BYTE bHash[160 / 8]; CryptGetHashParam(hHash,HP_HASHVAL,&bHash[0],&cbHash,0); AddFileDataToList(wszFilename,bHash,cbHash); delete [] pBuff; CryptDestroyHash(hHash); } CloseHandle(hFile); return true; } Compiled code detects integer overflow automatically in ::new Static analysis spotted mismatch between new/delete [] (was free) Crypto-Agility Get hash alg from configuration Add SAL annotation to detect bugs Replace Banned hash function

57 AddFileDataToList() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() void AddFileDataToList(wchar_t *wszName, BYTE *pHash, size_t cbHash) { // snip }

58 AddFileDataToList() ServiceMain() EnumAndHashFiles() GetDirFromUser() HashOneFile() AddFileDataToList() void AddFileDataToList(__in_z wchar_t *wszName, __in_bcount(cbHash) BYTE *pHash, size_t cbHash) { // snip } Add SAL annotation to detect bugs


Download ppt "Security Development Lifecycle: Development Practices Michael Howard Principal Security Program Manager Microsoft Corp. Stuff you."

Similar presentations


Ads by Google