3328 words
17 minutes
WDAC File Rule Level: WHQLPublisher

WDAC File Rule Level: WHQLPublisher#

Combines the WHQL EKU trust check with the Common Name (CN) of the leaf certificate — allowing only WHQL-certified drivers from a specific named hardware vendor, rather than any WHQL-certified driver.


Table of Contents#

  1. Overview
  2. How WHQLPublisher Differs from WHQL
  3. The Dual Trust Check
  4. Certificate Chain / Trust Anatomy
  5. Where in the Evaluation Stack
  6. XML Representation
  7. PowerShell Examples
  8. Comparison Table: WHQL vs. WHQLPublisher vs. WHQLFilePublisher
  9. Pros & Cons Table
  10. Attack Resistance Analysis
  11. When to Use vs. When to Avoid — Decision Flowchart
  12. Real-World Scenario: OEM-Specific Driver Allowlisting
  13. OS Version & Compatibility
  14. Common Mistakes & Gotchas
  15. Summary Table

1. Overview#

The WHQLPublisher file rule level is a compound trust check that requires both:

  1. The file’s certificate chain contains the WHQL EKU (OID 1.3.6.1.4.1.311.10.3.5) — confirming Microsoft certified the driver
  2. The leaf certificate’s CN (Common Name) matches a specific value — confirming the driver belongs to a particular vendor

This level sits between WHQL (broad — any certified vendor) and WHQLFilePublisher (very specific — particular file at particular version) in the specificity spectrum.

Core use case: Organizations that deploy hardware from known, specific vendors and want to permit only that vendor’s WHQL-certified drivers, not drivers from all possible WHQL-certified vendors.

Example distinction:

  • WHQL: “Allow any driver that Microsoft has WHQL-certified” (covers thousands of drivers from hundreds of vendors)
  • WHQLPublisher: “Allow WHQL-certified drivers, but only if signed with CN=NVIDIA Corporation” (covers all NVIDIA WHQL drivers, no others)

2. How WHQLPublisher Differs from WHQL#

The WHQL level checks only for the presence of the WHQL EKU in the certificate chain. The WHQLPublisher level adds an additional gate: the leaf certificate’s subject CN must match the specified publisher name.

The Critical Difference#

In the WHQL signing model, Microsoft signs the driver on behalf of the vendor. The vendor’s identity is preserved in the submission metadata and reflected in the leaf certificate’s Common Name. While the signing certificate is Microsoft’s, the CN embedded in it identifies the submitting organization:

  • Driver submitted by NVIDIA → Leaf cert CN = NVIDIA Corporation
  • Driver submitted by Intel → Leaf cert CN = Intel Corporation
  • Driver submitted by Dell → Leaf cert CN = Dell Inc.

The WHQLPublisher rule exploits this CN to achieve vendor-specific trust.

Why the WHQL Signing Model Makes This Possible#

Unlike standard Authenticode where each vendor has their own private key and their own certificate, WHQL drivers are all signed by Microsoft’s private key. The differentiation between vendors comes from the subject name on the Microsoft-issued leaf certificate for that specific vendor’s submission.

Standard Authenticode chain:
Root CA → Vendor's Intermediate CA → Vendor's Leaf Cert → File
(Vendor controls their own private key)
WHQL signing chain:
Microsoft Root → Microsoft WHQL PCA → Microsoft-issued Leaf (CN=Vendor Name) → File
(Microsoft controls the private key; vendor name is in the CN)

This is why WHQLPublisher can meaningfully distinguish between vendors even though Microsoft signs everything: the CN in the Microsoft-issued leaf cert identifies who submitted the driver.


3. The Dual Trust Check#

graph LR
subgraph "WHQLPublisher = Two Checks Must Both Pass"
DRIVER["nvlddmkm.sys\n(NVIDIA Driver)"]:::file
subgraph "Check 1: WHQL EKU"
EKU_FIND["Walk cert chain\nlooking for EKU:\n1.3.6.1.4.1.311.10.3.5"]:::node
EKU_PASS["WHQL EKU Found\n✓ Microsoft certified this driver"]:::allow
EKU_FAIL["WHQL EKU Absent\n✗ Not WHQL-certified"]:::block
end
subgraph "Check 2: Leaf CN Match"
CN_READ["Read leaf cert CN\nfrom signing certificate"]:::node
CN_PASS["CN = 'NVIDIA Corporation'\nmatches rule value\n✓ Correct vendor"]:::allow
CN_FAIL["CN = 'Intel Corporation'\ndoes not match rule value\n✗ Wrong vendor"]:::block
end
subgraph "Result"
BOTH_PASS["BOTH checks pass\n→ ALLOWED"]:::allow
ONE_FAIL["Either check fails\n→ Not matched (falls through)"]:::block
end
end
DRIVER --> EKU_FIND
EKU_FIND -->|"EKU present"| EKU_PASS
EKU_FIND -->|"EKU absent"| EKU_FAIL
EKU_PASS --> CN_READ
EKU_FAIL --> ONE_FAIL
CN_READ -->|"CN matches rule"| CN_PASS
CN_READ -->|"CN different"| CN_FAIL
CN_PASS --> BOTH_PASS
CN_FAIL --> ONE_FAIL
classDef file fill:#162032,stroke:#1e3a5f,color:#e2e8f0
classDef node fill:#162032,stroke:#1e3a5f,color:#e2e8f0
classDef allow fill:#0d1f12,stroke:#1a5c2a,color:#86efac
classDef block fill:#1f0d0d,stroke:#7f1d1d,color:#fca5a5

Both conditions must be satisfied simultaneously. A file that is WHQL-signed but from a different vendor fails the CN check. A file that has the correct CN but lacks the WHQL EKU fails the EKU check. Only files meeting both conditions are allowed by a WHQLPublisher rule.


4. Certificate Chain / Trust Anatomy#

graph TB
subgraph "Certificate Chain for WHQL-Signed Driver"
ROOT["Microsoft Product Root 2010\n(Self-Signed)"]:::root
WHQL_PCA["Microsoft Windows Hardware\nCompatibility PCA 2021\n(Intermediate CA — Issues WHQL leaf certs)"]:::pca
LEAF_NVIDIA["Microsoft-issued Leaf Certificate\nCN=NVIDIA Corporation\nSerial: AB:CD:EF:...\nEKU includes: 1.3.6.1.4.1.311.10.3.5\n← WHQLPublisher checks THIS cert's CN"]:::pca
LEAF_INTEL["Microsoft-issued Leaf Certificate\nCN=Intel Corporation\nSerial: 12:34:56:...\nEKU includes: 1.3.6.1.4.1.311.10.3.5\n(Different CN — different WHQLPublisher rule needed)"]:::node
NVIDIA_DRV["nvlddmkm.sys (NVIDIA GPU driver)\nSigned by NVIDIA leaf cert"]:::file
INTEL_DRV["e1d68x64.sys (Intel NIC driver)\nSigned by Intel leaf cert"]:::file
end
subgraph "WDAC WHQLPublisher Rules"
RULE_NVIDIA["WHQLPublisher Rule #1\nEKU: WHQL OID\nCN: 'NVIDIA Corporation'\n→ Allows nvlddmkm.sys"]:::allow
RULE_INTEL["WHQLPublisher Rule #2\nEKU: WHQL OID\nCN: 'Intel Corporation'\n→ Allows e1d68x64.sys"]:::allow
NO_RULE["No rule for other vendors\n→ Their drivers are not matched\nby these WHQLPublisher rules"]:::block
end
ROOT --> WHQL_PCA
WHQL_PCA --> LEAF_NVIDIA
WHQL_PCA --> LEAF_INTEL
LEAF_NVIDIA --> NVIDIA_DRV
LEAF_INTEL --> INTEL_DRV
NVIDIA_DRV -.->|"matched by"| RULE_NVIDIA
INTEL_DRV -.->|"matched by"| RULE_INTEL
classDef root fill:#1a0d2e,stroke:#6b21a8,color:#d8b4fe
classDef pca fill:#162032,stroke:#1e3a5f,color:#e2e8f0
classDef node fill:#162032,stroke:#1e3a5f,color:#e2e8f0
classDef file fill:#162032,stroke:#1e3a5f,color:#e2e8f0
classDef allow fill:#0d1f12,stroke:#1a5c2a,color:#86efac
classDef block fill:#1f0d0d,stroke:#7f1d1d,color:#fca5a5

Important: Even though NVIDIA and Intel drivers both chain through the same Microsoft Windows Hardware Compatibility PCA, their leaf certificates have different CNs. This is the binding point for WHQLPublisher rules. A separate rule is needed for each vendor whose drivers you want to allow.


5. Where in the Evaluation Stack#

flowchart TD
START(["Kernel Driver Load Request"]):::node
HASH_CHECK{"Hash rule match?"}:::node
HASH_ALLOW(["ALLOWED — Hash match"]):::allow
WHQL_FP_CHECK{"WHQLFilePublisher rule?\n(EKU + CN + filename + version)"}:::node
WHQL_FP_ALLOW(["ALLOWED — WHQLFilePublisher match"]):::allow
WHQL_PUB_CHECK{"WHQLPublisher rule?\n(EKU check + CN check)"}:::node
WHQL_PUB_ALLOW(["ALLOWED — WHQLPublisher match\nBoth WHQL EKU AND vendor CN confirmed"]):::allow
WHQL_CHECK{"WHQL rule?\n(EKU check only)"}:::node
WHQL_ALLOW(["ALLOWED — WHQL match"]):::allow
PCA_CHECK{"PcaCertificate rule?"}:::node
PCA_ALLOW(["ALLOWED — PcaCertificate match"]):::allow
DEFAULT{"Default action?"}:::node
BLOCK(["BLOCKED"]):::block
START --> HASH_CHECK
HASH_CHECK -->|"Yes"| HASH_ALLOW
HASH_CHECK -->|"No"| WHQL_FP_CHECK
WHQL_FP_CHECK -->|"Yes"| WHQL_FP_ALLOW
WHQL_FP_CHECK -->|"No"| WHQL_PUB_CHECK
WHQL_PUB_CHECK -->|"Yes (both EKU + CN match)"| WHQL_PUB_ALLOW
WHQL_PUB_CHECK -->|"No"| WHQL_CHECK
WHQL_CHECK -->|"Yes"| WHQL_ALLOW
WHQL_CHECK -->|"No"| PCA_CHECK
PCA_CHECK -->|"Yes"| PCA_ALLOW
PCA_CHECK -->|"No"| DEFAULT
DEFAULT -->|"Deny"| BLOCK
classDef node fill:#162032,stroke:#1e3a5f,color:#e2e8f0
classDef allow fill:#0d1f12,stroke:#1a5c2a,color:#86efac
classDef block fill:#1f0d0d,stroke:#7f1d1d,color:#fca5a5

WHQLPublisher sits at a middle position in the WHQL family evaluation order: checked after the more specific WHQLFilePublisher and before the broader WHQL. If a file matches WHQLFilePublisher, evaluation stops there. If WHQLPublisher matches, evaluation stops. Only if WHQLPublisher does not match does evaluation continue to bare WHQL.


6. XML Representation#

A WHQLPublisher rule requires three coordinated elements in the WDAC XML:

  1. An <EKU> element defining the WHQL OID
  2. A <Signer> element referencing both the WHQL EKU and the WHQL PCA
  3. A <CertPublisher> child element specifying the vendor’s CN
<?xml version="1.0" encoding="utf-8"?>
<SiPolicy xmlns="urn:schemas-microsoft-com:sipolicy">
<EKUs>
<EKU ID="ID_EKU_WHQL" Value="010A2B0601040182370A0305" />
</EKUs>
<Signers>
<!--
WHQLPublisher Rule for NVIDIA Corporation.
Allows WHQL-certified drivers where leaf cert CN = "NVIDIA Corporation".
Does NOT allow non-NVIDIA WHQL drivers or non-WHQL NVIDIA-branded binaries.
-->
<Signer ID="ID_SIGNER_WHQL_NVIDIA" Name="WHQLPublisher - NVIDIA Corporation">
<CertRoot Type="TBS" Value="3085A90B03EE71B6B33F5EA8A07DBBD40B5B7A89" />
<CertEKU ID="ID_EKU_WHQL" />
<CertPublisher Value="NVIDIA Corporation" />
</Signer>
<!--
WHQLPublisher Rule for Intel Corporation.
Separate rule needed per vendor.
-->
<Signer ID="ID_SIGNER_WHQL_INTEL" Name="WHQLPublisher - Intel Corporation">
<CertRoot Type="TBS" Value="3085A90B03EE71B6B33F5EA8A07DBBD40B5B7A89" />
<CertEKU ID="ID_EKU_WHQL" />
<CertPublisher Value="Intel Corporation" />
</Signer>
<!--
WHQLPublisher Rule for Realtek Semiconductor Corp.
-->
<Signer ID="ID_SIGNER_WHQL_REALTEK" Name="WHQLPublisher - Realtek Semiconductor Corp.">
<CertRoot Type="TBS" Value="3085A90B03EE71B6B33F5EA8A07DBBD40B5B7A89" />
<CertEKU ID="ID_EKU_WHQL" />
<CertPublisher Value="Realtek Semiconductor Corp." />
</Signer>
</Signers>
<SigningScenarios>
<SigningScenario Value="131" ID="ID_SIGNINGSCENARIO_DRIVERS" FriendlyName="Kernel Mode Drivers">
<ProductSigners>
<AllowedSigner SignerID="ID_SIGNER_WHQL_NVIDIA" />
<AllowedSigner SignerID="ID_SIGNER_WHQL_INTEL" />
<AllowedSigner SignerID="ID_SIGNER_WHQL_REALTEK" />
</ProductSigners>
</SigningScenario>
</SigningScenarios>
</SiPolicy>

Key XML Elements Explained#

ElementPurpose in WHQLPublisher
<EKU ID="..." Value="...">Defines the WHQL OID value (shared across all WHQL-family rules)
<CertRoot Type="TBS" Value="...">Specifies the WHQL intermediate CA TBS hash (Microsoft’s PCA)
<CertEKU ID="...">Links to the EKU definition — requires WHQL EKU in chain
<CertPublisher Value="...">The vendor CN from the leaf certificate — this is what makes it WHQLPublisher

Removing <CertPublisher> from a WHQLPublisher rule degrades it to a WHQL rule (any WHQL vendor). Adding <FileAttrib> elements and linking them via <FileAttribRef> upgrades it to WHQLFilePublisher.


7. PowerShell Examples#

Generating WHQLPublisher Rules#

Terminal window
# Generate WHQLPublisher rules by scanning a specific vendor's drivers
# ConfigCI will extract the leaf CN and create WHQLPublisher rules
New-CIPolicy `
-ScanPath "C:\Windows\System32\drivers\" `
-Level WHQLPublisher `
-Fallback Hash `
-FilePath "C:\Policies\WHQLPublisher-Policy.xml" `
-Drivers
# The output XML will contain Signer elements with CertPublisher child elements
# Each unique vendor CN found in WHQL-signed drivers gets its own Signer rule
Terminal window
# Scan only NVIDIA drivers specifically
# Useful for building a policy that explicitly covers only one vendor
$nvidiaDrivers = Get-ChildItem "C:\Windows\System32\DriverStore\FileRepository" `
-Recurse -Filter "*.sys" | Where-Object {
(Get-AuthenticodeSignature $_.FullName).SignerCertificate.Subject -like "*NVIDIA*"
}
# Build policy from just those files
New-CIPolicy `
-Level WHQLPublisher `
-Fallback Hash `
-FilePath "C:\Policies\NVIDIA-WHQL-Policy.xml" `
-ScanPath ($nvidiaDrivers | Select-Object -First 1).DirectoryName

Inspecting the Leaf CN of a WHQL-Signed Driver#

Terminal window
function Get-WHQLPublisherInfo {
param([string]$DriverPath)
$whqlOid = "1.3.6.1.4.1.311.10.3.5"
$sig = Get-AuthenticodeSignature -FilePath $DriverPath
if ($sig.Status -ne "Valid") {
Write-Warning "Not validly signed: $DriverPath"
return
}
$chain = New-Object System.Security.Cryptography.X509Certificates.X509Chain
$chain.Build($sig.SignerCertificate) | Out-Null
# Check for WHQL EKU
$isWhql = $false
foreach ($el in $chain.ChainElements) {
foreach ($ext in $el.Certificate.Extensions) {
if ($ext -is [System.Security.Cryptography.X509Certificates.X509EnhancedKeyUsageExtension]) {
if ($ext.EnhancedKeyUsages | Where-Object { $_.Value -eq $whqlOid }) {
$isWhql = $true
}
}
}
}
if (-not $isWhql) {
Write-Host "Not WHQL-signed: $DriverPath" -ForegroundColor Yellow
return
}
# Extract leaf cert CN (this is the CertPublisher value in WHQLPublisher rules)
$leafCert = $chain.ChainElements[0].Certificate
$cnMatch = $leafCert.Subject -match "CN=([^,]+)"
$cn = if ($cnMatch) { $Matches[1].Trim() } else { "Unknown" }
Write-Host "WHQLPublisher Info for: $([System.IO.Path]::GetFileName($DriverPath))" -ForegroundColor Cyan
Write-Host " WHQL EKU: Present" -ForegroundColor Green
Write-Host " Leaf CN (CertPublisher value): $cn" -ForegroundColor Green
Write-Host " Leaf Thumbprint: $($leafCert.Thumbprint)"
Write-Host ""
Write-Host " WDAC WHQLPublisher rule would use:"
Write-Host " <CertPublisher Value=`"$cn`" />" -ForegroundColor Yellow
}
# Examples
Get-WHQLPublisherInfo -DriverPath "C:\Windows\System32\drivers\nvlddmkm.sys"
Get-WHQLPublisherInfo -DriverPath "C:\Windows\System32\drivers\e1d68x64.sys"

Building a Multi-Vendor WHQLPublisher Policy for a Dell Enterprise Fleet#

Terminal window
# Scenario: Dell workstation fleet with NVIDIA GPU, Intel NIC, Realtek audio
# Build a policy allowing only these specific vendors' WHQL drivers
$vendorDriverPaths = @(
"C:\Windows\System32\drivers\nvlddmkm.sys", # NVIDIA GPU
"C:\Windows\System32\drivers\e1d68x64.sys", # Intel NIC
"C:\Windows\System32\drivers\RTKVHD64.sys" # Realtek Audio
)
# Create a temp directory with just these representative drivers
$tempDir = New-Item -ItemType Directory -Path "C:\Temp\VendorDriverScan" -Force
foreach ($driver in $vendorDriverPaths) {
if (Test-Path $driver) {
Copy-Item $driver $tempDir.FullName
}
}
# Generate WHQLPublisher rules from these representative drivers
New-CIPolicy `
-ScanPath $tempDir.FullName `
-Level WHQLPublisher `
-Fallback Hash `
-FilePath "C:\Policies\Dell-VendorDrivers.xml" `
-Drivers
Write-Host "Generated WHQLPublisher policy with vendor-specific rules"
Write-Host "Review C:\Policies\Dell-VendorDrivers.xml before deploying"
# Clean up
Remove-Item $tempDir.FullName -Recurse -Force

Validating WHQLPublisher XML Output#

Terminal window
function Validate-WHQLPublisherPolicy {
param([string]$PolicyXmlPath)
[xml]$policy = Get-Content -Path $PolicyXmlPath -Raw
$ns = New-Object System.Xml.XmlNamespaceManager($policy.NameTable)
$ns.AddNamespace("si", "urn:schemas-microsoft-com:sipolicy")
$signers = $policy.SelectNodes("//si:Signer", $ns)
$whqlSigners = @()
foreach ($signer in $signers) {
$hasCertEKU = $signer.SelectSingleNode("si:CertEKU", $ns) -ne $null
$hasCertPublisher = $signer.SelectSingleNode("si:CertPublisher", $ns) -ne $null
$hasCertRoot = $signer.SelectSingleNode("si:CertRoot", $ns) -ne $null
if ($hasCertEKU -and $hasCertPublisher -and $hasCertRoot) {
$publisherValue = $signer.SelectSingleNode("si:CertPublisher", $ns).GetAttribute("Value")
$whqlSigners += [PSCustomObject]@{
SignerID = $signer.GetAttribute("ID")
Name = $signer.GetAttribute("Name")
Publisher = $publisherValue
Level = "WHQLPublisher"
}
} elseif ($hasCertEKU -and $hasCertRoot -and -not $hasCertPublisher) {
$whqlSigners += [PSCustomObject]@{
SignerID = $signer.GetAttribute("ID")
Name = $signer.GetAttribute("Name")
Publisher = "(Any — WHQL level)"
Level = "WHQL"
}
}
}
Write-Host "WHQL-related Signers in: $PolicyXmlPath" -ForegroundColor Cyan
$whqlSigners | Format-Table -AutoSize
}

8. Comparison Table: WHQL vs. WHQLPublisher vs. WHQLFilePublisher#

AttributeWHQLWHQLPublisherWHQLFilePublisher
EKU checkYesYesYes
Vendor CN checkNoYesYes
Filename checkNoNoYes
Version floorNoNoYes
Trust scopeAll WHQL vendorsOne specific vendorOne specific file from one vendor
Vendors coveredHundredsOne per ruleOne per rule
Files covered per ruleAll files from all WHQL vendorsAll WHQL files from one vendorOne specific driver file from one vendor
Maintenance on new driverAuto-coveredAuto-covered (if same vendor)Auto-covered (if same filename, same vendor, version ≥ minimum)
Maintenance on vendor renameAuto-coveredRULE BREAKSRULE BREAKS
XML complexityLowMediumHigh
Attack surfaceLargest of WHQL familyVendor-boundedFile-and-version-bounded
BYOVD riskHighestVendor-scopedLowest
Typical use caseBroad enterprise driver coverageOEM-specific fleet managementProduction-hardened driver control

9. Pros & Cons Table#

AttributeAssessment
Security improvement over WHQLSignificant — eliminates drivers from unrelated vendors
Trust scopeAll WHQL-certified drivers from named vendor
Maintenance burdenLow per-vendor — new certified drivers from same vendor automatically match
ScalabilityModerate — one rule per vendor; 5-10 rules typical for enterprise fleets
PrecisionMedium — still allows all driver versions from the vendor
BYOVD riskReduced (vendor-scoped) but still present if vendor has vulnerable old drivers
Vendor rename riskRule breaks silently if vendor CN changes (company merger, rebranding)
OEM fleet suitabilityExcellent — natural fit for “trust Dell hardware drivers on Dell machines”
XML verbosityModerate — one <Signer> block per vendor
PowerShell supportFull — New-CIPolicy -Level WHQLPublisher works natively

10. Attack Resistance Analysis#

graph TD
subgraph "Threat Scenarios Against WHQLPublisher Policy"
ATK_A["Scenario A: Attacker tries to load\na driver from a different vendor\nnot in the WHQLPublisher rules\n(e.g., Gigabyte WHQL driver used in BYOVD)"]:::warn
CHECK_A{"Driver's leaf CN\nmatches any WHQLPublisher rule?"}:::node
BLOCK_A(["BLOCKED — CN doesn't match\nWHQLPublisher rule\nVendor not in allowed list"]):::allow
ATK_B["Scenario B: Attacker uses a\nlegitimate but OLD vulnerable\ndriver from an allowed vendor\n(e.g., old NVIDIA driver with CVE)"]:::warn
CHECK_B{"WHQL EKU present\nAND CN = NVIDIA Corporation?"}:::node
PASS_B(["ALLOWED — WHQLPublisher matches\nVulnerable old driver loads\nMitigate with block rules\nor upgrade to WHQLFilePublisher"]):::block
ATK_C["Scenario C: Attacker fabricates\na certificate with CN=NVIDIA Corporation\nbut without Microsoft's WHQL root chain"]:::warn
CHECK_C{"Does cert chain root in\nMicrosoft's WHQL root?"}:::node
BLOCK_C(["BLOCKED — Chain doesn't root\nin Microsoft WHQL root CA\nEKU check fails"]):::allow
ATK_D["Scenario D: Attacker submits\na malicious driver to Microsoft\nfor WHQL certification"]:::warn
CHECK_D{"Does malicious driver pass\nMicrosoft's HLK test suite?"}:::node
BLOCK_D(["BLOCKED at process level\nMicrosoft's HLK testing and\nsecurity review prevents\nmalicious drivers from being certified"]):::allow
PASS_D(["In theory, a sophisticated attacker\ncould get a benign-looking driver\ncertified that contains a later-\nactivated payload — extremely rare"]):::warn
end
ATK_A --> CHECK_A
CHECK_A -->|"No match"| BLOCK_A
ATK_B --> CHECK_B
CHECK_B -->|"Yes"| PASS_B
ATK_C --> CHECK_C
CHECK_C -->|"No"| BLOCK_C
ATK_D --> CHECK_D
CHECK_D -->|"Usually no"| BLOCK_D
CHECK_D -->|"Extremely rare"| PASS_D
classDef node fill:#162032,stroke:#1e3a5f,color:#e2e8f0
classDef allow fill:#0d1f12,stroke:#1a5c2a,color:#86efac
classDef block fill:#1f0d0d,stroke:#7f1d1d,color:#fca5a5
classDef warn fill:#1a1a0d,stroke:#7a6a00,color:#fde68a

The key security improvement of WHQLPublisher over WHQL is illustrated in Scenario A: a common BYOVD attack using a vulnerable Gigabyte or other vendor’s WHQL driver is stopped simply because that vendor’s CN is not in the allowed list. This significantly reduces the BYOVD attack surface without requiring a frequently-updated block list.

However, Scenario B remains: if an allowed vendor (e.g., NVIDIA or Intel) has released a WHQL driver that later received a CVE, that driver still matches the WHQLPublisher rule. Mitigations:

  • Apply Microsoft’s vendor-specific driver block rules
  • Upgrade critical drivers to WHQLFilePublisher with a minimum version floor
  • Monitor vendor security advisories

11. When to Use vs. When to Avoid — Decision Flowchart#

flowchart TD
Q1["Need to allow kernel drivers\non enterprise systems"]:::node
Q2{"Do you know exactly\nwhich hardware vendors'\ndrivers will be deployed?"}:::node
Q3{"How many distinct\nvendors?"}:::node
Q4{"Security level\nrequirement?"}:::node
YES_VENDORS_FEW["1-10 vendors (typical OEM fleet)"]:::node
YES_VENDORS_MANY["More than 10-15 vendors\n(diverse hardware inventory)"]:::node
USE_WHQL_PUB(["Use WHQLPublisher\nOne rule per vendor\nExact fit for known-hardware fleets\nBetter security than WHQL\nLower maintenance than WHQLFilePublisher"]):::allow
USE_WHQL(["Consider WHQL instead\nToo many rules to manage\nBut add Microsoft block rules\nMonitor for CVEs"]):::warn
CONSIDER_FP(["Consider WHQLFilePublisher\nfor highest-risk drivers\n(kernel security components)\nFor everything else WHQLPublisher is fine"]):::allow
USE_FP_HIGH(["Use WHQLFilePublisher\nHigh-security environment\nProduction hardened policy\nSpecific driver file + version control"]):::allow
NO_KNOW(["Don't know specific vendors\n→ Use WHQL level as starting point\n→ Deploy in audit mode\n→ Observe which vendors appear\n→ Migrate to WHQLPublisher after inventory"]):::warn
Q1 --> Q2
Q2 -->|"Yes"| Q3
Q2 -->|"No"| NO_KNOW
Q3 -->|"Few vendors"| YES_VENDORS_FEW
Q3 -->|"Many vendors"| YES_VENDORS_MANY
YES_VENDORS_FEW --> Q4
YES_VENDORS_MANY --> USE_WHQL
Q4 -->|"Standard enterprise"| USE_WHQL_PUB
Q4 -->|"High security"| USE_FP_HIGH
USE_WHQL_PUB --> CONSIDER_FP
classDef node fill:#162032,stroke:#1e3a5f,color:#e2e8f0
classDef allow fill:#0d1f12,stroke:#1a5c2a,color:#86efac
classDef block fill:#1f0d0d,stroke:#7f1d1d,color:#fca5a5
classDef warn fill:#1a1a0d,stroke:#7a6a00,color:#fde68a

12. Real-World Scenario: OEM-Specific Driver Allowlisting#

Scenario: A healthcare organization runs a fleet of identical Dell workstations. Each machine has:

  • NVIDIA Quadro GPU (medical imaging workloads)
  • Intel I219 NIC
  • Realtek HD Audio

The organization wants to allow only drivers from these three vendors, blocking drivers from all other vendors (including well-known ones like AMD, Broadcom, etc.) because those drivers are not on these machines and represent unnecessary attack surface.

sequenceDiagram
participant Admin as IT Admin
participant PS as PowerShell
participant Scan as Representative Machine
participant XML as Policy XML
participant MDM as Intune
participant WS as Dell Workstation (ci.dll)
participant GoodDrv as nvlddmkm.sys (NVIDIA, WHQL)
participant BadDrv as kevp64.sys (Gigabyte BYOVD, WHQL)
Note over Admin,BadDrv: Phase 1 — Inventory Hardware Drivers
Admin->>Scan: Run Get-WHQLPublisherInfo on all drivers
Scan-->>Admin: NVIDIA Corporation, Intel Corporation, Realtek Semiconductor Corp.
Admin->>Admin: Confirms: only 3 vendors needed
Note over Admin,BadDrv: Phase 2 — Build WHQLPublisher Policy
Admin->>PS: New-CIPolicy -Level WHQLPublisher -ScanPath C:\Windows\drivers -Fallback Hash
PS-->>XML: Generates 3 WHQLPublisher Signer rules (one per vendor)
Admin->>XML: Review: 3 Signers (NVIDIA, Intel, Realtek) + Hash fallbacks
Admin->>PS: Add Option 02 (Required:WHQL) to policy
Admin->>PS: Merge with Microsoft block rules
Admin->>PS: ConvertFrom-CIPolicy → policy.p7b
Note over Admin,BadDrv: Phase 3 — Deploy in Audit Mode First
Admin->>MDM: Deploy policy.p7b in Audit mode (Option 03: Enabled:Audit Mode)
MDM-->>WS: Policy active in audit mode
WS->>WS: Observes driver loads — logs allowed/blocked (no actual blocking)
WS-->>Admin: Audit events — all 3 vendor drivers log as "would allow"
Admin->>Admin: No unexpected blocks in audit mode → promote to enforce
Note over Admin,BadDrv: Phase 4 — Enforce Mode
Admin->>MDM: Redeploy policy without Audit Mode option
MDM-->>WS: Policy enforced
Note over Admin,BadDrv: Phase 5 — Normal Operation
GoodDrv->>WS: nvlddmkm.sys attempts to load (NVIDIA driver update)
WS->>WS: ci.dll: WHQL EKU present? Yes
WS->>WS: WHQLPublisher check: CN = "NVIDIA Corporation"? Yes — matches rule
WS-->>GoodDrv: ALLOWED — NVIDIA driver loads successfully
Note over Admin,BadDrv: Phase 6 — BYOVD Attempt
BadDrv->>WS: Attacker drops kevp64.sys (Gigabyte WHQL driver with kernel R/W vulnerability)
WS->>WS: ci.dll: WHQL EKU present? Yes
WS->>WS: WHQLPublisher check: CN = "Gigabyte Technology Co., Ltd"? NOT in allowed list
WS->>WS: WHQL check (no CN): No WHQL rule without CN restriction
WS->>WS: Hash check: Not in any hash rule
WS-->>BadDrv: BLOCKED — No rule matches this vendor
WS->>WS: Event ID 3077 logged — admin alerted

This scenario demonstrates the key operational advantage of WHQLPublisher: the BYOVD attack is stopped without needing to explicitly block the Gigabyte driver by hash. It is blocked simply because Gigabyte is not in the allowlist. This is a default-deny posture for driver vendors that is practical and maintainable.


13. OS Version & Compatibility#

OS VersionWHQLPublisher SupportNotes
Windows 10 1507+Full supportKernel mode driver control
Windows 10 1709+Full supportDual-policy capability (audit + enforce)
Windows 11 21H2+Full supportHVCI integration
Windows Server 2016+Full supportRecommended for server deployments
Windows Server 2019+Full support
Windows Server 2022+Full supportSecured-Core Server integration

WHQLPublisher shares the same compatibility profile as WHQL since it is an extension of the same EKU-based mechanism.


14. Common Mistakes & Gotchas#

Mistake 1: Vendor Name Mismatch — Exact String Match Required#

The <CertPublisher Value="..."> element requires an exact string match with the CN in the leaf certificate. Common errors:

What You TypeActual CN in CertMatch?
NVIDIANVIDIA CorporationNo
IntelIntel CorporationNo
RealtekRealtek Semiconductor Corp.No
NVIDIA CorporationNVIDIA CorporationYes

Always use the Get-WHQLPublisherInfo function (or equivalent) to read the exact CN from the actual certificate before writing the XML rule.

Mistake 2: Company Rebrand / Acquisition Breaking Rules#

If a hardware vendor changes their certificate CN (due to merger, acquisition, or rebrand), existing WHQLPublisher rules break silently:

  • New WHQL drivers signed with the new CN will not match old rules
  • Old drivers may still work (old CN), but new drivers from the same company (now different CN) will be blocked
  • Example: “XYZ Graphics Inc.” is acquired by “MegaCorp” and re-files WHQL submissions as “MegaCorp XYZ Division” — rule CN=XYZ Graphics Inc. no longer matches new drivers

Mitigation: Monitor vendor security bulletins and WHQL certificate changes, especially for hardware from companies with known merger/acquisition activity. Consider WHQLFilePublisher for stability (filename-based, less affected by CN changes for the same driver file).

Mistake 3: Using WHQLPublisher for Broad Trust (Should Use WHQL)#

If your hardware inventory spans 15+ vendors, managing 15+ WHQLPublisher rules becomes complex. For environments with highly diverse hardware, the broad WHQL level combined with Microsoft’s block rules is more maintainable. Use WHQLPublisher when you can enumerate your vendor list (typically 3-8 vendors for a homogeneous fleet).

Mistake 4: Forgetting That WHQL Level Rules and WHQLPublisher Rules Coexist#

If your policy contains both a broad WHQL rule and specific WHQLPublisher rules, the WHQLPublisher rules are evaluated first (as they are more specific), but the WHQL rule provides a fallback that allows all WHQL vendors anyway. If you intend to restrict to specific vendors only, you must not include a bare WHQL rule — only WHQLPublisher rules.

Mistake 5: WHQLPublisher in User-Mode Scenario#

Like WHQL, WHQLPublisher is primarily meaningful in the kernel-mode signing scenario. Adding WHQLPublisher rules to the user-mode signing scenario (12) is generally ineffective, as user-mode binaries from hardware vendors are typically signed with standard Authenticode certificates (not WHQL certificates). Use Publisher or FilePublisher levels for user-mode vendor software.


15. Summary Table#

PropertyValue
Level NameWHQLPublisher
Trust MechanismWHQL EKU (OID 1.3.6.1.4.1.311.10.3.5) AND leaf cert CN match
SpecificityVendor-specific (all WHQL drivers from one vendor)
More Specific ThanWHQL (any vendor)
Less Specific ThanWHQLFilePublisher (specific file + version)
Primary Use CaseOEM-specific WHQL driver allowlisting
XML Key Element<CertPublisher Value="[Vendor CN]" />
CN SourceLeaf certificate Subject CN from Microsoft’s WHQL signing cert
BYOVD RiskVendor-scoped — other vendor’s vulnerable drivers are blocked
CN Change RiskRule breaks if vendor renames/rebrands their certificate CN
PowerShell Level NameWHQLPublisher
Signing ScenarioKernel mode (131)
Kernel Componentci.dll
OS SupportWindows 10 1507+ / Server 2016+
Typical Rule CountOne Signer rule per hardware vendor (3-8 for OEM fleets)
Best Paired WithOption 02 (Required) + Microsoft block rules
WDAC File Rule Level: WHQLPublisher
https://mranv.pages.dev/posts/app-control-file-rule-level-whqlpublisher/
Author
Anubhav Gain
Published at
2026-05-02
License
CC BY-NC-SA 4.0