Remediation Guides

How to Fix CVE-2013-3900: Set EnableCertPaddingCheck (Nessus 166555, Qualys QID 378332)

26 September 2026 9 min read

CVE-2013-3900 is a WinVerifyTrust flaw that lets an attacker add code to a signed Windows executable without breaking its Authenticode signature. Nessus and Qualys flag it when the opt-in EnableCertPaddingCheck value is missing. Fix it by setting EnableCertPaddingCheck to 1 under HKLMSoftwareMicrosoftCryptographyWintrustConfig (plus the Wow6432Node path on 64-bit Windows), then restart.

What the scanner is actually detecting

This is a configuration finding, not a missing patch. Microsoft shipped the stricter check in December 2013 with MS13-098, planned to enable it by default in 2014, then cancelled that plan over compatibility. The code has sat dormant ever since, including on Windows 10 and 11, where Microsoft says no security update is required but the registry value must be set. That is why fully patched hosts still fail this check.

Scanner Finding ID
Nessus (Tenable) WinVerifyTrust Signature Validation CVE-2013-3900 Mitigation (EnableCertPaddingCheck) Plugin 166555
Qualys WinVerifyTrust Signature Validation Vulnerability QID 378332

Nessus plugin 166555, in the “Windows : Microsoft Bulletins” family, is a local check that runs in credentialed (SMB registry) scans and on Nessus Agents for Windows. It looks for EnableCertPaddingCheck in the native path and, on 64-bit systems, the Wow6432Node path. In April 2023 Qualys replaced its informational QID 45526 with vulnerability QID 378332.

How serious is it in practice?

The flaw is in how WinVerifyTrust checks the file digest of a signed PE file: content appended to unverified parts of the signature structure goes unnoticed, so a tampered executable or DLL still reports as validly signed. Microsoft marks it as exploited, and Qualys cited its use in the 2023 3CX supply chain attack as the reason it upgraded the detection.

Tenable rates the plugin High (CVSS v3 8.8), while Microsoft’s current Security Update Guide entry scores it 5.5 with a local attack vector and user interaction required. Nobody exploits this over the network on its own: a user or application has to run the tampered file. The real value of the mitigation is that tampered binaries stop looking trusted, so publisher-based trust decisions are harder to fool. Treat it as a cheap hardening control worth deploying everywhere, not an emergency.

Confirm it on the host

Check both locations from an elevated command prompt:

reg query "HKLMSoftwareMicrosoftCryptographyWintrustConfig" /v EnableCertPaddingCheck
reg query "HKLMSoftwareWow6432NodeMicrosoftCryptographyWintrustConfig" /v EnableCertPaddingCheck

If the value is missing you will see “ERROR: The system was unable to find the specified registry key or value.” The Config subkey often does not exist on a default install. To see the data and value type in one pass, run this from 64-bit PowerShell:

$paths = 'HKLM:SOFTWAREMicrosoftCryptographyWintrustConfig',
         'HKLM:SOFTWAREWow6432NodeMicrosoftCryptographyWintrustConfig'
foreach ($p in $paths) {
    $k = Get-Item -Path $p -ErrorAction SilentlyContinue
    if ($k -and ($k.GetValueNames() -contains 'EnableCertPaddingCheck')) {
        '{0} = {1} ({2})' -f $p, $k.GetValue('EnableCertPaddingCheck'), $k.GetValueKind('EnableCertPaddingCheck')
    } else {
        '{0} : EnableCertPaddingCheck not set' -f $p
    }
}

How to fix it

Single host with reg.exe

On 64-bit Windows, set both values. On 32-bit Windows, only the first line applies.

reg add "HKLMSoftwareMicrosoftCryptographyWintrustConfig" /v EnableCertPaddingCheck /t REG_DWORD /d 1 /f
reg add "HKLMSoftwareWow6432NodeMicrosoftCryptographyWintrustConfig" /v EnableCertPaddingCheck /t REG_DWORD /d 1 /f

If an RMM or deployment agent runs these as a 32-bit process, the first command is redirected into Wow6432Node and the native path is never written. Append /reg:64 to both to force the 64-bit view.

PowerShell

The same 32-bit trap applies here: agents often launch 32-bit PowerShell, whose HKLM:SOFTWARE writes on 64-bit Windows are redirected into Wow6432Node, so a New-ItemProperty script never creates the native value. Opening the registry through the 64-bit view avoids that. Both scripts below require PowerShell 3.0 or later; on PowerShell 2.0 hosts, use the reg.exe commands with /reg:64.

# Registry64 forces the native view, even from 32-bit PowerShell.
# On 32-bit Windows it falls back to the only view there is.
$base = [Microsoft.Win32.RegistryKey]::OpenBaseKey('LocalMachine', 'Registry64')
$keys = @('SOFTWAREMicrosoftCryptographyWintrustConfig')
if ([Environment]::Is64BitOperatingSystem) {
    $keys += 'SOFTWAREWow6432NodeMicrosoftCryptographyWintrustConfig'
}
foreach ($k in $keys) {
    $key = $base.CreateSubKey($k)
    $key.SetValue('EnableCertPaddingCheck', 1, 'DWord')
    $key.Close()
}
$base.Close()

CreateSubKey opens Config if it exists and creates it if not, leaving other values alone. If you prefer New-Item and New-ItemProperty, start the .ps1 file with a guard that relaunches it under 64-bit PowerShell:

if ([Environment]::Is64BitOperatingSystem -and -not [Environment]::Is64BitProcess) {
    & "$env:WINDIRsysnativeWindowsPowerShellv1.0powershell.exe" -NoProfile -ExecutionPolicy Bypass -File $PSCommandPath
    exit $LASTEXITCODE
}

The guard only works from a .ps1 file, since $PSCommandPath is empty for inline commands. Check Test-Path before New-Item: New-Item -Force on an existing key recreates it and wipes its other values and subkeys.

.reg file

This follows Microsoft’s current 64-bit example (drop the second block on 32-bit Windows):

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINESoftwareMicrosoftCryptographyWintrustConfig]
"EnableCertPaddingCheck"=dword:00000001

[HKEY_LOCAL_MACHINESoftwareWow6432NodeMicrosoftCryptographyWintrustConfig]
"EnableCertPaddingCheck"=dword:00000001

If you apply the file through a 32-bit agent, use reg import enableAuthenticodeVerification.reg /reg:64. Without /reg:64, the first block is redirected into Wow6432Node.

Group Policy for many hosts

Microsoft’s documented route is the “MS Security Guide” administrative template. Copy SecGuide.admx and SecGuide.adml from the latest Windows security baseline in the Microsoft Security Compliance Toolkit into your Central Store, with the .adml in a language subfolder such as en-US (if you have no Central Store, copy the files to C:WindowsPolicyDefinitions on the management workstation). Then enable Computer Configuration > Policies > Administrative Templates > MS Security Guide > Enable Certificate Padding. Confirm both registry paths on a pilot host afterwards, because the scanner checks both.

If you would rather not import templates, the simplest way to deploy the value through an EnableCertPaddingCheck GPO is a Group Policy Preferences registry item. In the Group Policy Management Editor go to Computer Configuration > Preferences > Windows Settings > Registry, then New > Registry Item:

  • Action: Update
  • Hive: HKEY_LOCAL_MACHINE
  • Key Path: SOFTWAREMicrosoftCryptographyWintrustConfig
  • Value name: EnableCertPaddingCheck, Value type: REG_DWORD, Value data: 1

Create a second item with the Key Path SOFTWAREWow6432NodeMicrosoftCryptographyWintrustConfig. The same thing from PowerShell on a machine with the GroupPolicy module:

$gpo = 'CVE-2013-3900 EnableCertPaddingCheck'
New-GPO -Name $gpo | Out-Null
foreach ($key in 'HKLMSOFTWAREMicrosoftCryptographyWintrustConfig',
                 'HKLMSOFTWAREWow6432NodeMicrosoftCryptographyWintrustConfig') {
    Set-GPPrefRegistryValue -Name $gpo -Context Computer -Action Update -Key $key `
        -ValueName 'EnableCertPaddingCheck' -Type DWord -Value 1
}
New-GPLink -Name $gpo -Target 'OU=Pilot-CVE-2013-3900,OU=Workstations,DC=example,DC=com'

The sample links to a pilot OU on purpose; widen it only after pilot machines pass the signature checks described under rollback below. If the value never shows up on clients, work through our guide to GPOs that are not applying because of precedence before assuming the setting is wrong.

REG_DWORD or REG_SZ?

Both work. Microsoft’s original 2013 advisory used a string (“EnableCertPaddingCheck”=”1”), which is why older scripts create REG_SZ. The MSRC entry then flipped between string and DWORD guidance during 2024 before settling on this rule: Windows treats the value as a DWORD, but the stored type does not matter as long as the value exists, its data is 1 to 4 bytes long, and at least one byte is non-zero. REG_SZ “1” meets that rule. Use REG_DWORD 1 for new deployments: it matches Microsoft’s current example and is least ambiguous for scanners.

Verify the fix and rescan

  1. Re-run the reg query commands. Each path should return a line like EnableCertPaddingCheck REG_DWORD 0x1. Through a 32-bit agent, append /reg:64 to both; otherwise the first query reads the Wow6432Node value and can confirm a fix that did not happen.
  2. Restart the host. Microsoft says the change takes effect only after a restart.
  3. Run a credentialed Nessus scan or Nessus Agent scan, or an authenticated Qualys scan or Cloud Agent scan, against the host. Plugin 166555 or QID 378332 should no longer be reported.

Both checks read the registry, so a clean rescan proves the value is present, not that the host has rebooted. Track the restart through your normal patch window. If the plugin never runs at all, look at registry access first; our Windows credentialed scan failures guide covers the usual causes.

What can break and how to roll back

With the check on, Windows treats non-conforming signed files as unsigned. Microsoft lists where that shows up:

  • Installers customized at download time, which embed extra data in the signature block. Users may see unsigned-publisher warnings during installation.
  • AppLocker and Software Restriction Policies rules that depend on a file being signed or on a specific publisher may stop matching those files.
  • Binaries signed with non-Microsoft signing tools carry a higher risk of being judged non-compliant.

Microsoft states Windows Defender Application Control (WDAC) is not affected. On a pilot machine with the setting enabled and restarted, run Get-AuthenticodeSignature against the installers you deploy and investigate anything that no longer reports Valid. The long-term fix is for the vendor to re-sign the file correctly.

To roll back, delete the value (or set it to REG_DWORD 0) and restart:

reg delete "HKLMSoftwareMicrosoftCryptographyWintrustConfig" /v EnableCertPaddingCheck /f
reg delete "HKLMSoftwareWow6432NodeMicrosoftCryptographyWintrustConfig" /v EnableCertPaddingCheck /f

From a 32-bit agent, append /reg:64 to both; otherwise the first command deletes the Wow6432Node value and leaves the native one.

Do not roll back by writing a string “0”. Under Microsoft’s length and non-zero rule, the character “0” is itself a non-zero byte, so a REG_SZ “0” still enables the check.

If the value came from the MS Security Guide policy (for example a CIS Benchmark GPO; Microsoft’s own baselines ship the setting in SecGuide.admx but do not enable it), set that policy to Disabled, per Microsoft’s revert instructions. Deleting the value locally is only temporary. The policy writes it back the next time registry policy is processed (after any GPO change, on gpupdate /force, or at every refresh if “Process even if the Group Policy objects have not changed” is enabled).

A GPP Update item stays on clients after the GPO is unlinked. Change its action to Delete and let it apply, or tick “Remove this item when it is no longer applied” on the Common tab before deploying (this switches the action to Replace).

Common false positive reasons

  • Only one path set. Someone applied the 32-bit instructions to a 64-bit host, or a 32-bit agent wrote both values into Wow6432Node. Check both paths with the commands above.
  • Wrong location or name. The value sits under Wintrust instead of WintrustConfig, or the name has a typo.
  • Data outside Microsoft’s rule. A REG_QWORD is 8 bytes, and multi-character strings exceed 4 bytes, so neither counts as enabled.
  • Type mismatch in the scanner logic. If a host with REG_SZ “1” is still flagged, convert it to REG_DWORD 1 rather than arguing the exception.
  • Assuming patches fix it. The latest cumulative update will not clear this finding. Only the registry value does.

Once the fleet is clean, add the value to your baseline, for example in a Windows Server hardening checklist, so rebuilt servers do not reintroduce it.

FAQ

Does installing Windows updates fix CVE-2013-3900?

No. The code has shipped since MS13-098, including in Windows 10 and 11, but stays dormant until EnableCertPaddingCheck is set.

Do I need the Wow6432Node value on 64-bit Windows?

Yes. Microsoft’s 64-bit instructions set both paths, and Nessus plugin 166555 checks both on 64-bit hosts.

Is a reboot required?

Yes. Microsoft says you must restart for the change to take effect, and a clean scan does not prove that a restart happened.

Can I remove the setting later?

Yes. Delete the value or set it to REG_DWORD 0, then restart. If the value comes from the MS Security Guide policy, set that policy to Disabled instead. The finding will return on the next scan.

Tracking this finding across many hosts

When the same finding sits on hundreds of hosts, the hard part is proving every one of them closed. SITEY, a self-hosted vulnerability management platform, imports findings from 16 scanners (Nessus results arrive as uploaded .nessus exports), can have its AI draft a host-specific registry script that its Windows agents deploy only after human approval, and supports per-finding retest for Nessus findings such as plugin 166555. Duplicates are merged per scanner, not across scanners, so a host flagged by two different scanners still appears as two findings.

Sources

SITEY closes the loop, not just the report.Discover, validate, fix and verify in your own infrastructure.

See pricing