AD2011: EnableStackProtection¶
Summary¶
| Property | Value |
|---|---|
| ID | AD2011 |
| Name | EnableStackProtection |
| Category | Security |
| Severity | Error |
| Applies to | PE (Windows) |
Description¶
Binaries should be built with the /GS flag to enable stack buffer overflow detection and protection. The /GS flag provides security checks that detect stack buffer overruns, a common technique for exploiting buffer overrun vulnerabilities.
The security check adds a randomly-initialized security cookie to the stack frame, placed between local buffers and the return address. On function return, this cookie is verifiedβif corrupted, the process terminates.
How It Works¶
The rule checks for evidence of /GS protection by examining:
- The presence of
__security_cookiesymbol - Load configuration directory with security cookie pointer
- PDB compilation flags (if available)
Why This Matters¶
Stack buffer overflows have been the most common vulnerability class for decades. The /GS compiler option adds runtime detection that catches these attacks before they can hijack program execution.
The Classic Stack Smashing Attack¶
Without /GS, a stack overflow proceeds undetected:
Stack layout (without /GS):
[Local buffer][Saved EBP][Return Address]
^
Overflow starts here
β Overwrites return address
β Function returns to attacker code
With /GS, a security cookie blocks this:
Stack layout (with /GS):
[Local buffer][Security Cookie][Saved EBP][Return Address]
^
Overflow starts here
β Must overwrite cookie to reach return address
β Cookie check fails on function return
β Program terminates safely
How the Security Cookie Works¶
- At startup: Cookie is initialized with a random value from the OS
- Function entry: Cookie is placed on stack after local variables
- Function exit: Cookie is compared against expected value
- If mismatch:
__security_check_cookiecalls__report_gsfailure, terminating the process
Historical Impact¶
The introduction of /GS in Visual Studio 2003 significantly impacted exploit development:
| Era | Exploit Difficulty |
|---|---|
| Pre-/GS | Trivial stack overwrites |
| /GS enabled | Must bypass or leak cookie |
| /GS + ASLR + DEP | Multiple primitives needed |
What /GS Protects¶
The compiler inserts cookies for functions with:
- Local arrays
- alloca() calls
- Structures containing arrays
- Parameter blocks for exception handlers
Performance Overhead¶
/GS has minimal performance impact:
| Operation | Overhead |
|---|---|
| Function entry | 1 store instruction |
| Function exit | 1 compare + conditional |
| Typical overall | <1% CPU |
This tiny cost provides protection against one of the most exploited vulnerability classes.
Defense in Depth¶
/GS is most effective when combined with:
| Mitigation | Additional Protection |
|---|---|
| ASLR | Cookie value harder to predict |
| DEP | Even if bypassed, can't execute shellcode |
| CFG | Limits where corrupted returns can go |
| SafeSEH | Protects exception handler overwrites |
Resolution¶
Enable /GS¶
The /GS flag is enabled by default in Visual Studio. Ensure it's not disabled:
Project Properties¶
- Open Project Properties
- Navigate to C/C++ β Code Generation
- Set "Security Check" to "Yes (/GS)"
CMake¶
if(MSVC)
# /GS is on by default, ensure it's not disabled
string(REPLACE "/GS-" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endif()
Remove /GS-¶
Search your project for /GS- which disables protection:
When to Suppress¶
This rule should rarely be suppressed. Exceptions might include:
- Kernel mode code: May need special handling
- Bare metal code: No CRT support for security cookie
- Extreme performance: Rarely justified for security-sensitive code
Caveats¶
- Requires proper CRT initialization (
__security_init_cookie) - Assembly code doesn't benefit from
/GS - Only protects functions with vulnerable buffer layouts
- Not all buffer overflows are detected (only those affecting stack layout)
How /GS Works¶
- Compile time: Compiler identifies vulnerable functions
- Function entry: Cookie copied to stack
- Function exit: Cookie verified
- Mismatch: Process terminated via
__report_securitycookiefailure
Stack Layout with /GS:
βββββββββββββββββββ
β Return Address β β Target of overflow
βββββββββββββββββββ€
β Security Cookie β β Canary (random value)
βββββββββββββββββββ€
β Local Buffers β β Source of overflow
βββββββββββββββββββ
Related Rules¶
- AD2012: DoNotModifyStackProtectionCookie
- AD2013: InitializeStackProtection
- AD2014: DoNotDisableStackProtectionForFunctions