Introduction
Confidentiality, integrity and availability (CIA) are the core principles of information security. Confidentiality refers to limiting information access and allows only authorized users. Integrity refers to trust worthiness of information. Availability refers to the availability of computer information. Security principle should be considered in the entire software development life cycle. Microsoft gives higher priority for building secured environment for customers and provides Microsoft Security Development Lifecycle (SDL) methodologies for building secured applications. Security should be considered in requirements, analysis, design, implementation, verification and release phases. Many system side applications are developed by using C and C++ programming languages. The C and C++ vulnerabilities allow the attacker to attack the operating system lower level layer. Microsoft increases the security for Microsoft products and gives Microsoft Security Development Lifecycle (SDL) process for developing secured software using Microsoft technologies. The software developers should consider security in the part of development process.
Secure String Handling
C/C++ doesn’t support any build in data type for string
s. C/C++ treats string
as array of characters. But, C++ can make use of Standard Template Library string
class. The security should be considered when the application uses both standard template library (STL) and C style string
s. The C style string
s are NULL
terminated. The Windows C/C++ programmers have many options for string
handling. The developers can use C Run time library (CRT) (strcpy
, strcmp
, etc), Windows string
functions (lstrcmp
, lstrcpy
, etc), C++ STL and MFC/ATL library String
functions. Microsoft increased security for all the string
functions because most of the application security attack is based on buffer overflow.
Microsoft released Strsafe
functions for increased Windows applications security. Later, Microsoft enhanced the CRT libraries for increased security. It helps the developers build secured applications and Microsoft uses those functions internally too. Microsoft rebuilds the ATL and MFC libraries for making use of secured C run time functions. So, if developers rebuild their applications by using new versions of MFC and ATL, they will make sure the applications use secured version libraries.
The Secure string
handling comes under Secure Development Lifecycle (SDL) Practice #9: Deprecate Unsafe Functions. Microsoft SDL recommends making use of Banned.H, Strsafe.h (with Visual Studio) and Safe CRT (with Visual Studio). The National Institute of Standards and Technology (NIST) states that designing the secured software during the early stage can cost 30 times less than fixing them post release.
Single Byte Character Set (SBCS), Multi Byte Character Set (MBCS) and Unicode
The developer should be aware of the difference between Single Byte Character set (SBCS), Multi byte Character set (MBCS) and Unicode. The Single Byte Character allocates only a single byte memory for each character. Single byte character set (SBCS) is sufficient to represent the ASCII character and many European languages. But some non-European characters require more than one byte character. So, it requires multi byte character set (MBCS). A Unicode character is a 2-byte multilingual character code. Most of the modern Microsoft operating systems use Unicode format only. Even if you develop ASCII version, the Microsoft layer converts into Unicode format before calling the function. So, it will reduce the performance. So, Microsoft recommends using Unicode Strings.
The memory allocation for Unicode and SBCS/MBCS are different. So, Microsoft provides two versions of functions. The function calls the ASCII or Unicode based on application compiler settings. Microsoft also provides generic text data type for handling both Unicode and SBCS/MBCS. It will call SBCS/MBCS functions for non-Unicode and Unicode functions for Unicode compiler options. Microsoft recommends making use of the Unicode version for future development. So, the component can be easily migrated to different locale without much effort.
The Windows API provides separate functions for ASCII and Unicode. The Strsafe
family function provides the separate function A
for ASCII or W
for Unicode at the end of the name. For example, the StrSafe StringCbCatEx
function is available for StringCbCatExW
(Unicode) and StringCbCatExA
(ASCII). The Windows API MultiByteToWideChar
and WideCharToMultiByte
are used for translating string
s between Unicode and ASCII.
Banned Application Programming Interface (API)
Microsoft C++ compiler gives more options for application's security during compile time itself. Microsoft Visual C++ compiler gives a warning when the source code uses banned string
API. The Strsafe.h provides the secure functionality for C style string
s. Alternatively, the developers can choose Strsafe
or Safe
CRT for building secured applications. The list of banned API and alternative functions are discussed in Security Development Lifecycle (SDL) Banned Function Calls. If the strcpy
or strcat
is used incorrectly, it leads to buffer overflow. So, Microsoft added those kinds of family functions to Banned
API list. The banned
API listing is applicable for both Microsoft and Non Microsoft technologies and platforms. The N
family functions are also listed in Banned
API list. The C runtime “n
” functions make them difficult to use and is one of the reasons why they are listed as part of the Microsoft SDL Banned API listing.
As per SDL list of Banned
Function Calls, the developer should include #include “banned.h”;
. This will be able to locate any banned functions in code. The full list of banned APIs is also included in the header file. Alternately, if you are using the compiler in Visual Studio 2005 or later, you have a built-in way to check for these banned functions. To catch banned C runtime functions, you can compile with /W4 and then triage all C4996 warnings.
#include "c:\banned.h"
1>c:\development\c++\ban\ban\test.cpp(79) :
warning C4995: 'StrCpyN': name was marked as #pragma deprecated
1>c:\development\c++\ban\ban\test.cpp(79) :
warning C4995: 'StrCpyNW': name was marked as #pragma deprecated
Strsafe and Secured C Run time Library (CRT)
Microsoft released Strsafe
library for developing secured Windows applications. Software security should be considered for the entire software development life cycle (SDLC). The input validation is the major problem for system and web programming. It may have variations like buffer overflow, underflow, etc. The application uses array of characters for many places for string
compare, Append a string
, Append characters of a string
, String
Copy, Get String
input, String
length and format the string
characters. The functions supported from Strsafe
contain guaranteed null
terminated string
, return HRESULT
for successful call, separate functions for corresponding character count ("cch
") or byte count ("cb
") version[This articles explains only about cch version].
After Strsafe
, Microsoft wants to enhance the security for C run time library. So, CRT provides secure _s
function for validating their arguments. It checks the values are valid, buffers have enough memory space, etc. This functions return errno_t
for finding the success or failure. The release build auto terminates and debug version will gives the assertion dialog box for debugging further. This article explains about Strsafe
, Secured C run time library (CRT) and safe STL functions.
Copy String
The secured string
copy supports in wcscpy_s(wide-character)
, _mbscpy_s(multibyte-character)
and strcpy_s
formats. The arguments and return value of wcscpy_s
are wide character string
s and _mbscpy_s
are multibyte character string
s. Otherwise, these three functions behave identically.
The strcopy
functions don’t accept the destination buffer size as an input. So, the developer doesn’t have control for validating the size of destination buffer size. The _countof
macro is used for computing the number of elements in a statically-allocated array. It doesn’t work with pointer type. The wcscpy_s
takes the destination string
, Size
of the destination string
buffer and null
terminated source string
.
Copy string using secured CRT
wchar_t safe_copy_str1[]=L"Hello world";
wchar_t safe_copy_str2[MAX_CHAR];
wcscpy_s( safe_copy_str2, _countof(safe_copy_str2),safe_copy_str1 );
printf ("After copy string = %S\n\n", safe_copy_str2);
The StringCchCopy
function takes Pointer
to a destination buffer, Size
of the destination buffer in characters and pointer to a source string
. It returns S_OK
for successful; STRSAFE_E_INVALID_PARAMETER
for destination buffer is 0
or max STRSAFE_MAX_CCH
and STRSAFE_E_INSUFFICIENT_BUFFER
for the copy failed for insufficient buffer. The StringCchCopy
is a generic version equal to TCHAR
family functions. It will apply A
version for ASCII and w
version for wide character function.
The StringCchCopyEx
function provides more options. The Ex
function includes the parameter for address of a pointer to the end of Destination
, Pointer
to a variable that indicates the number of unused characters in destination and different flags (STRSAFE_FILL_BEHIND_NULL
, STRSAFE_IGNORE_NULLS
, STRSAFE_FILL_ON_FAILURE
, STRSAFE_NULL_ON_FAILURE
and STRSAFE_NO_TRUNCATION
).
Copy and append String using Strsafe
wchar_t wsString[128];
HRESULT Res;
Res= StringCchCopy(wsString, _countof(wsString), L"Hello ");
if (Res != S_OK) {
printf("StringCchCopy Failed: %S\n", wsString);
exit(-1);
}
Res= StringCchCat(wsString,sizeof(wsString),L" World!");
if (Res != S_OK) {
printf("StringCchCat Failed: %s\n", wsString);
exit(-1);
}
printf("%S\n", wsString);
Get String
The gets
function doesn’t validate the string
size. The secured version gets_s
validates the input string
size. If the buffer size is small, it will give a Buffer which is too small an error in debug mode [Figure 1]. When I run the application and give more character for the allocated memory produced the following Assertion error dialog during debug build.
Get User input String using CRT
#define MAX_BUF 10
wchar_t safe_getline[MAX_BUF];
if (gets_s(safe_getline, MAX_BUF) == NULL) {
printf("invalid input.\n");
abort();
}
printf("%S\n", safe_getline);
If the buffer is small, then this function invokes an invalid parameter handler. If execution is allowed to continue, these functions return NULL
and set errno
to EINVAL
.
The StringCchGets
takes a pointer to a buffer which receives the copied characters and Size
of the destination buffer in characters parameters. It will return S_OK
for successful get string
. It will return STRSAFE_E_END_OF_FILE
, STRSAFE_E_INVALID_PARAMETER
and STRSAFE_E_INSUFFICIENT_BUFFER
for error condition.
Get User input String using Strsafe
wchar_t wsString[128];
HRESULT Res;
Res=StringCchGets(wsString, sizeof(wsString));
if (Res != S_OK) {
printf("StringCchGets Failed: %S\n", wsString);
exit(-1);
}
printf("%S \n",wsString);
String Length
The StringCchLength
uses for getting the length for the string
in characters which does not including the terminating null
character. It also takes the maximum number of characters allowed in wsString
and returns the length of the input string
. It returns S_OK
for successful call and STRSAFE_E_INVALID_PARAMETER
for failure call.
Get String lengths using Strsafe
wchar_t wsString[] = L"Hello World";
size_t length;
HRESULT Res;
Res = StringCchLength(wsString, MAX_PATH, &length);
if (Res != S_OK) {
printf("StringCchLength Failed: %S\n", wsString);
exit(-1);
}
printf("StringCchLength = %d \n",length);
Format String
The StringCchPrintf
accepts the list of arguments and return the string
. The StringCchPrintf
function takes Pointer
to a buffer and size of the destination buffer. It returns S_OK
for successful call and STRSAFE_E_INVALID_PARAMETER
and STRSAFE_E_INSUFFICIENT_BUFFER
failed call. The Uncontrolled Format String
gives ‘Command Injection’ attacks.
Format String using Strsafe
TCHAR msgBuf[BUF_SIZE];
size_t cchStringSize;
DWORD dwChars;
int val1 = 10;
int val2= 20;
HANDLE hStdout;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if( hStdout == INVALID_HANDLE_VALUE )
return 1;
StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"), val1, val2);
StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
WriteConsole(hStdout, msgBuf, cchStringSize, &dwChars, NULL);
Secured Standard Template Library (STL)
The standard C++ library is enhanced for use secured string
and character handling. Microsoft enhanced the standard template library for security. STL added new functions with _s
for security. The following table contains the unsafe function and safer functions.
STL | Secured STL |
basic_string::copy | basic_string::_Copy_s |
basic_streambuf::sgetn | basic_streambuf::_Sgetn_s |
basic_streambuf::xsgetn | basic_streambuf::_Xsgetn_s |
char_traits::copy | char_traits::_Copy_s |
char_traits::move | char_traits::_Move_s |
ctype::narrow | ctype::_Narrow_s |
ctype::do_narrow | ctype::_Do_narrow_s |
ctype::widen | ctype::_Widen_s |
ctype::do_widen | ctype::_Do_widen_s |
All secured STL functions are validated with the size of the destination string
. Secured STL enhanced the debug iterator and checked iterators for making iterators and algorithms more secure. The Microsoft C++ runtime detects the incorrect use of iterator and asserts and displays a dialog box at run time. This will enable only program compiled in debug mode.
Checked iterators do not overwrite the bounds of container. It works for both release and debug build. If the program defines #define _SECURE_SCL 1
, all the standard iterators are checked. The _SECURE_SCL
default value is 1
. If the program defines #define
_SECURE_SCL_THROWS 1
, an out of range iterator use causes an exception at runtime. The _SECURE_SCL_THROWS
default value is 0
(program will be terminated by default).
The following STL functions will generate runtime error if they face outside the bounds:
basic_string
, valarray
and bitset
back
, front
and operator[]
operations for dequeue and vector - back and front operations for list and queue
Difference between Strsafe and CRT
No | Strsafe | CRT |
1 | Run on kernel mode | Run on user mode |
2 | Always NULL -terminate the string | Parameter Validation. Includes NULL values passed to the functions, Null termination, enumerated values for validity, integral values are in valid ranges |
3 | Always return HRESULT return codes | Zero if successful, otherwise an error code |
4 | Support 32-bit and 64-bit environments. | Support 32-bit and 64-bit environments. |
5 | Windows software development kit | Microsoft Visual Studio |
6 | Include One header | Include Many headers |
7 | Supports from Windows XP with Service Pack 2 onwards | Supports from Visual C++ 2005 onwards |
8 | All functions require size of destination buffer parameter | Sized Buffers |
9 | Buffer overflows | Buffer overflows and other vulnerabilities |
10 | Only string handling | Includes String handling and Windows security, File system security, Enhanced error reporting, etc. |
Conclusion
Microsoft is concentrating more about secured application development. The buffer overflow and other input validation allow the hacker to attack the applications (DOS or DDOS attacks). There is no single document or guide for write secured applications. The guidelines provided by Microsoft make it difficult for attacking the applications in Microsoft environment. The security should consider all the phases in software development. It doesn’t mean the security is considered only for development phase. This article explains only about secured string
handling. But, Microsoft released Security Development Lifecycle (SDL) guidelines version 5.0 (Updated November 5, 2010) for developing secured application development. Microsoft is continuously updating Security Development Lifecycle (SDL) guidelines based on current vulnerabilities.
Summary
Banned
API is the set of functions calls that you should avoid for both new applications and legacy application development. This list can vary based on current vulnerabilities. - If the application is built on Windows:
- Use
Strsafe
functions and Validate return values. - Else if the application is built on CRT, use Secured CRT functions.
- Rebuild MFC and ATL based applications using latest Microsoft libraries which are built using secured versions.
- If application uses STL, check safe functions availability.
- Follow Microsoft Secured development life cycle (SDL) 5.0 guidelines.
Points of Interest
- Microsoft Security Development Life Cycle
- MSDN Visual C++ 2008
- MSDN Magazine
- Security Development Lifecycle (SDL) Banned Function Calls
- banned.h
History
- 9th March 2014: Updated __countof for StringCchCopy, Thanks to virtualnik
- 12th May, 2011: Updated '
Strafe
' and 'Starsafe
' to "Strsafe
", thanks to Stefan63 - 15th April, 2011: Initial version