In 2023, CrowdStrike reported that 75% of intrusions were malware-free, relying instead on legitimate tools already present on the endpoint. Attackers don't need to bring their own weapons when yours are already lying around unlocked. Application whitelisting flips the default-allow paradigm on its head—and when implemented correctly, it's one of the most powerful controls you can deploy.
Why Default-Deny Changes Everything
Traditional antivirus operates on a blocklist model: allow everything, block known bad. This is a losing game. Every novel binary, every repackaged loader, every renamed powershell.exe slips through until a signature catches up.
Application whitelisting (or execution control) inverts this. Nothing executes unless explicitly permitted. This single architectural shift neutralizes entire attack categories—ransomware droppers, trojanized installers, unauthorized scripts, and abuse of LOLBins (living-off-the-land binaries).
The Australian Signals Directorate ranks application whitelisting as the #1 mitigation strategy in their Essential Eight framework. Yet adoption in enterprise environments remains surprisingly low, often due to fear of operational disruption. Let's fix that.
Windows: WDAC vs. AppLocker
AppLocker is the more familiar tool, but Microsoft now positions Windows Defender Application Control (WDAC) as the preferred solution. The key difference: WDAC enforces in kernel mode and cannot be bypassed by an admin-level user, while AppLocker runs as a service that a local admin can disable.
Starting with WDAC in Audit Mode
Never deploy in enforcement mode on day one. Begin by generating a baseline policy from a known-good reference machine:
# Generate a policy from a reference system
New-CIPolicy -Level Publisher -FilePath "C:\Policies\BasePolicy.xml" `
-UserPEs -Fallback Hash -Audit
# Convert to binary for deployment
ConvertFrom-CIPolicy -XmlFilePath "C:\Policies\BasePolicy.xml" `
-BinaryFilePath "C:\Windows\System32\CodeIntegrity\SIPolicy.p7b"The -Audit flag is critical. It logs what would be blocked (Event ID 3076 in Microsoft-Windows-CodeIntegrity/Operational) without actually preventing execution. Run this for 2–4 weeks, analyze the logs, and refine your policy before switching to enforcement.
Supplemental Policies for Flexibility
WDAC supports multiple policy composition in Windows 10 1903+. Create a restrictive base policy, then layer supplemental policies for specific teams:
# Create a supplemental policy for the engineering team's toolchain
New-CIPolicy -Level Publisher -FilePath "C:\Policies\EngineeringSupplemental.xml" `
-UserPEs -SupplementsBasePolicyID "{BASE-POLICY-GUID}"This avoids the "one giant policy" anti-pattern that becomes unmaintainable at scale.
Linux: fapolicyd and Beyond
On RHEL/CentOS systems, fapolicyd provides file-access policy enforcement tied to the RPM database—essentially whitelisting everything installed via the package manager:
# Install and enable
sudo dnf install fapolicyd
sudo systemctl enable --now fapolicyd
# Check trust database (RPM-based by default)
sudo fapolicyd-cli --dump-db | head -20
# Add a custom trusted binary
sudo fapolicyd-cli --file add /opt/myapp/bin/custom-tool
sudo fapolicyd-cli --updateFor containers and immutable infrastructure, combine this with read-only root filesystems and seccomp profiles to enforce execution control at the runtime layer.
Operational Lessons from the Field
1. Inventory before you enforce. Use audit modes, software asset management tools, and EDR telemetry to discover what's actually running. You will find surprises—shadow IT, legacy tools, unsigned updaters.
2. Manage by publisher, not hash. Hash-based rules break on every update. Publisher-level rules (code-signing certificate) allow patched versions automatically while blocking unsigned binaries.
3. Plan for exceptions ruthlessly. Every exception is an attack surface. Document each one with a business justification, an owner, and a review date. Treat your exception list like a firewall rule base.
4. Integrate with CI/CD. If your developers ship internal tools, mandate code signing as part of the build pipeline. No signature, no execution. This turns whitelisting from a bottleneck into a quality gate.
Final Thought
Application whitelisting isn't a "set and forget" control—it's a discipline. But in a threat landscape dominated by fileless attacks and tool abuse, controlling what runs on your endpoints is no longer optional. Start in audit mode, build your policy iteratively, and treat every unsigned binary as guilty until proven innocent.
Have questions about application whitelisting and execution control? I'm always happy to talk shop — reach out or connect with me on LinkedIn.