Writing secure C++ software requires action at every layer: the compiler, the linker, the runtime library, and your own coding practices. MSVC provides a comprehensive set of hardening flags that detect vulnerabilities at compile time and enable operating system defenses at runtime. When combined with safe coding practices — using the secure CRT, smart pointers, and integer-safe arithmetic — these mitigations dramatically reduce your application’s attack surface.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/MicrosoftDocs/cpp-docs/llms.txt
Use this file to discover all available pages before exploring further.
Compiler Security Flags
/GS — Buffer Security Check
The /GS flag (enabled by default) inserts stack canary cookies into functions that have local buffers or use exception handling. When a buffer overrun corrupts the stack, the canary mismatch is detected before the function returns, and execution is terminated.
/sdl — Security Development Lifecycle Checks
The /sdl flag elevates a subset of security-relevant warnings to errors and enables additional secure code generation features beyond /GS:
/sdl promotes these categories of issues to build errors:
- Uninitialized variable usage that could leak sensitive data
- Unsafe use of deprecated CRT functions (e.g.,
strcpy,sprintf) - Unsafe conversion patterns identified by the analyzer
Microsoft recommends enabling
/sdl for all new projects. Combined with /W4 and /WX, it creates a strict, secure-by-default build environment that catches many vulnerabilities at compile time rather than at runtime.Linker Security Flags
/SAFESEH — Safe Exception Handlers
The /SAFESEH linker flag produces a table of registered exception handler addresses in the image. The OS validates exception handler addresses at runtime against this table, preventing attackers from hijacking exception handling to redirect execution to injected shellcode.
/SAFESEH applies only to x86 (32-bit) binaries. x64 binaries use a different exception model (table-based unwinding) that is inherently safe and does not require this flag./DYNAMICBASE — Address Space Layout Randomization (ASLR)
ASLR randomizes the load address of your executable and its DLLs each time the process starts, making it far harder for attackers to predict where code or data lives in memory.
/HIGHENTROPYVA to use the full 64-bit address space for rebasing:
/NXCOMPAT — Data Execution Prevention (DEP)
DEP (NX/XD bit) prevents the CPU from executing code from pages that contain only data — the stack, the heap, and global data segments. This defeats classic shellcode injection attacks.
Control Flow Guard — /guard:cf
Control Flow Guard (CFG) inserts compiler-generated checks before every indirect function call (call rax, jmp [rsp+...], vtable dispatches). At runtime, the OS validates each call target against a bitmap of valid call sites, preventing attackers from redirecting control flow through corrupted function pointers.
CET Shadow Stack — /CETCOMPAT
Intel’s Control-flow Enforcement Technology (CET) Shadow Stack maintains a second, hardware-protected call stack used only for return addresses. Return-oriented programming (ROP) attacks that corrupt the main stack’s return addresses are detected because the shadow stack values don’t match.
Recommended Security Flag Summary
Secure CRT Functions
The C Runtime Library (CRT) ships secure replacements for every unsafe string and buffer function. These functions take an additionaldestSize parameter and return an errno_t error code, ensuring that writes never exceed the destination buffer.
Common Secure CRT Replacements
| Unsafe Function | Secure Replacement | Notes |
|---|---|---|
strcpy | strcpy_s | Requires destination size |
strcat | strcat_s | Requires destination size |
sprintf | sprintf_s | Requires destination size |
gets | fgets / scanf_s | gets removed in C11 |
strtok | strtok_s | Thread-safe, context pointer |
wcscpy | wcscpy_s | Wide-character equivalent |
memcpy (overlapping) | memmove | For overlapping regions |
scanf | scanf_s | Requires size for %s and %c |
Smart Pointers and RAII
Rawnew and delete are one of the most common sources of memory bugs: leaks, double-frees, and use-after-free. Prefer RAII-based smart pointers from <memory>:
Integer Safety with SafeInt
Integer overflows in size calculations are a common source of heap overflows. TheSafeInt library wraps arithmetic operations and throws on overflow:
User Accounts and Least Privilege
Run your application with the minimum required privileges. Developers who run as Administrator expose their machines — and their customers — to unnecessary risk:- Test your application running as a standard user to surface privilege-related issues early.
- Use User Account Control (UAC) manifest settings to request elevation only when genuinely required.
- Embed the appropriate
requestedExecutionLevelin your application manifest:
Spectre Mitigations (/Qspectre)
Speculative execution side-channel attacks (Spectre/Meltdown) can leak sensitive data through CPU microarchitectural state. The /Qspectre flag inserts LFENCE barrier instructions at vulnerable speculative load sites:
Security Checklist
Compiler flags checklist
Compiler flags checklist
-
/GS— enabled (default) -
/sdl— SDL checks enabled -
/guard:cf— Control Flow Guard enabled -
/W4 /WX— high warning level, warnings as errors -
/analyze— static analysis enabled
Linker flags checklist
Linker flags checklist
-
/DYNAMICBASE— ASLR enabled -
/HIGHENTROPYVA— high-entropy ASLR (64-bit) -
/NXCOMPAT— DEP enabled -
/SAFESEH— safe exception handlers (x86) -
/guard:cf— CFG linker flag also set -
/CETCOMPAT— CET Shadow Stack compatible
Coding practices checklist
Coding practices checklist
- Use
strcpy_s,sprintf_s,strcat_sinstead of unsafe equivalents - Use
std::unique_ptr/std::shared_ptrinstead of rawnew/delete - Use
std::vectorandstd::stringinstead of raw arrays - Use
SafeIntfor size arithmetic that feeds allocations - Run
/analyzeand address allError-severity warnings - Enable C++ Core Guidelines checker rules
- Run as standard user during development and testing