Oddly it worked if I turned off DLL Rule Enforcement, but not when I enabled it again. My immediate thought might be the virus checking was trying to map the executable and somehow it was hitting the DLL verification callback and failing as the file was in my Downloads folder which is not in the default rule set. That seemed pretty unlikely, however clearly something was being blocked from running. Fortunately AppLocker maintains an Audit Log under "Applications and Services Logs -> Microsoft -> Windows -> AppLocker -> EXE and DLL" so we can quickly diagnose the failure.
The failing DLL load was for "%OSDRIVE%\PROGRAMDATA\MICROSOFT\WINDOWS DEFENDER\PLATFORM\4.18.1910.4-0\MPOAV.DLL". This makes sense, the default rules only permit %WINDOWS% and %PROGRAMFILES% for normal users, however %OSDRIVE%\ProgramData is not allowed. This is intentional as you don't want to grant access to locations a normal user could write to, so generally allowing all of %ProgramData% would be asking for trouble. [update:20191206] of course this is known about (I'm not suggesting otherwise), AaronLocker should allow this DLL by default.
I thought it'd at least be interesting to see why it fails and what MPOAV is doing. As the same failure occurred in both Edge (I didn't test IE) and Chrome it was clearly some common API they were calling. As Chrome is open source it made more sense to look there. Tracking down the resource string for the error lead me to this code. The code was using the Attachment Services API. Which is a common interface to verify downloaded files and attachments, apply MOTW and check for viruses.
When the IAttachmentExecute::Save method is called the file is checked for viruses using the currently registered anti-virus COM object which implements the IOfficeAntiVirus interface. The implementation for that COM class is in MPOAV.DLL, which as we saw is blocked so the COM object creation fails. And a failure to create the object causes the Save method to fail and the Attachment Services code to automatically delete the file so the browser can't even do anything about it such as ask the user. Ultra rude!
You might wonder how is this COM class is registered? An implementor needs to register their COM object with a Category ID of "{56FFCC30-D398-11d0-B2AE-00A0C908FA49}". If you have OleViewDotNet setup (note there are other tools) you can dump all registered classes using the following PowerShell command:
Get-ComCategory -CatId '56FFCC30-D398-11d0-B2AE-00A0C908FA49' | Select -ExpandProperty ClassEntries
On a default installation of Windows 10 you should find a single class, "Windows Defender IOfficeAntiVirus implementation" registered which is implemented in the MPOAV DLL. We can try and create the class with DLL enforcement to convince ourselves that's the problem:
No doubt this has been documented before (
This issue does demonstrate a common weakness with any application allow-listing solution. You've got to add a rule to allow this (probably undocumented) folder in your DLL rules. Or you could allow-list all Microsoft Defender certificates I suppose. Potentially both of these criteria could change and you end up having to fix random breakage which wouldn't be fun across a large fleet of machines. It also demonstrates a weird issue with attachment scanning, if your AV is somehow misconfigured things will break and there's no obvious reason why. Perhaps we need to move on from using outdated APIs to do this process or at least handle failure better.