Skip to content

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:

  1. The presence of __security_cookie symbol
  2. Load configuration directory with security cookie pointer
  3. 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
  1. At startup: Cookie is initialized with a random value from the OS
  2. Function entry: Cookie is placed on stack after local variables
  3. Function exit: Cookie is compared against expected value
  4. If mismatch: __security_check_cookie calls __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:

cl.exe /GS ...

Project Properties

  1. Open Project Properties
  2. Navigate to C/C++ β†’ Code Generation
  3. 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:

# Bad
cl.exe /GS- ...

# Good
cl.exe /GS ...

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

  1. Compile time: Compiler identifies vulnerable functions
  2. Function entry: Cookie copied to stack
  3. Function exit: Cookie verified
  4. 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
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

References