-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
URI validation for winget cli commands #4707
base: master
Are you sure you want to change the base?
Conversation
auto isAllowed = configurationPolicies->at(zone); | ||
if(!isAllowed) | ||
{ | ||
context.Reporter.Error() << "Configuration is disabled for Zone: " << zone << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO:
- Finalizing strings
- Move to resource file
@@ -122,6 +122,10 @@ If you disable this setting, users will not be able to use the Windows Package M | |||
If you disable or do not configure this setting, no proxy will be used by default. | |||
|
|||
If you enable this setting, the specified proxy will be used by default.</string> | |||
<string id="EnableDSCAllowedZones">Enable App Installer Allowed Zones for DSC</string> | |||
<string id="EnableDSCAllowedZonesExplanation"></string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Waiting for PM input?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but also, we're still thinking about the scope that this policy should cover (DSC only, or more ... )
switch (response.Decision()) | ||
{ | ||
case AppInstaller::UriValidation::UriValidationDecision::Block: | ||
context.Reporter.Error() << std::endl << "Blocked by smart screen" << std::endl << "Feedback: " << response.Feedback() << std::endl; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If Feedback
isn't localized, it should probably only be sent to the log and not stdout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All strings are not finalized/localized yet, there's an email thread for deciding on a couple things including localization
// The decision made based on the Uri validation. | ||
enum class UriValidationDecision | ||
{ | ||
Allow, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't there also a Warn
response that SmartScreen can return?
https://learn.microsoft.com/en-us/defender-endpoint/web-protection-overview#order-of-precedence
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, there's a PUA response as well. However, PUA/Warn will also be treated as Blocked, but the details will be communicated in the logs instead and the logic will be in the injected code. I can potentially reduce this enum to a bool. I will revisit this later once things are a little bit more finalized.
// Uri to give feedback to smart screen about the decision. | ||
std::string m_feedback; | ||
public: | ||
UriValidationResult(UriValidationDecision decision) : m_decision(decision), m_feedback(std::string()) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a default (enpty) constructor?
<None Include="packages.config" Condition="Exists('$(MSBuildProjectDirectory)\packages.config')" /> | ||
</ItemGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Windows.CppWinRT" Version="2.0.230706.1" TargetFramework="native" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesnt seem to match the version of cppwinrt in NOTICE.txt. Does the version need to be bumped across all the solution files, or is there something I’m missing?
Line 769 in 2306d08
Microsoft.Windows.CppWinRT 2.0.210503.1 - MIT |
<string id="EnableWindowsPackageManagerAllowedSecurityZones">Enable App Installer Allowed Zones for the Windows Package Manager</string> | ||
<string id="EnableWindowsPackageManagerAllowedSecurityZonesExplanation"></string> | ||
<string id="EnableWindowsPackageManagerSmartScreenCheck">Enable Microsoft SmartScreen checks for the Windows Package Manager</string> | ||
<string id="EnableWindowsPackageManagerSmartScreenCheckExplanation"></string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding @RDMacLachlan to help with the strings for the new group policies in the ADML
@@ -2685,6 +2685,14 @@ Please specify one of them using the --source option to proceed.</value> | |||
<value>Uri not well formed: {0}</value> | |||
<comment>{Locked="{0}"} Error message displayed when the provided uri is not well formed. {0} is a placeholder replaced by the provided uri.</comment> | |||
</data> | |||
<data name="UriBlockedBySmartScreen" xml:space="preserve"> | |||
<value>This operation was blocked as unsafe by Microsoft Defender SmartScreen.</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding @RDMacLachlan to help with the displayed messages (I copied the messages from App Installer with some modifications)
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Microsoft.Management.Deployment.OutOfProc", "Microsoft.Management.Deployment.OutOfProc\Microsoft.Management.Deployment.OutOfProc.vcxproj", "{0BA531C8-CF0C-405B-8221-0FE51BA529D1}" | ||
ProjectSection(ProjectDependencies) = postProject | ||
{2B00D362-AC92-41F3-A8D2-5B1599BDCA01} = {2B00D362-AC92-41F3-A8D2-5B1599BDCA01} | ||
EndProjectSection | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|ARM = Debug|ARM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We're building for ARM now?
@@ -390,6 +390,7 @@ | |||
<ClInclude Include="ContextOrchestrator.h" /> | |||
<ClInclude Include="COMContext.h" /> | |||
<ClInclude Include="Public\ConfigurationSetProcessorFactoryRemoting.h" /> | |||
<ClInclude Include="Workflows\UriValidationFlow.h" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Move this next to all other Workflows files
@@ -257,6 +257,9 @@ | |||
<ClInclude Include="Commands\ConfigureListCommand.h"> | |||
<Filter>Commands</Filter> | |||
</ClInclude> | |||
<ClInclude Include="Workflows\UriValidationFlow.h"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
class UriValidationResult | ||
{ | ||
public: | ||
UriValidationResult(UriValidationDecision decision) : m_decision(decision), m_feedback(std::string()) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you don't need to pass the empty string for m_feedback
because that's what the default constructor does
UriValidationResult(UriValidationDecision decision) : m_decision(decision), m_feedback(std::string()) {} | |
UriValidationResult(UriValidationDecision decision) : m_decision(decision), m_feedback() {} |
Or you could initialize it to empty in the declaration and not mention it here
{ | ||
public: | ||
UriValidationResult(UriValidationDecision decision) : m_decision(decision), m_feedback(std::string()) {} | ||
UriValidationResult(UriValidationDecision decision, std::string feedback) : m_decision(decision), m_feedback(feedback) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
feedback
should probably be a std::string_view
or a std::string&&
to avoid a copy. Not that it would make much difference in this case
auto progressScope = context.Reporter.BeginAsyncProgress(true); | ||
progressScope->Callback().SetProgressMessage(Resource::String::ConfigurationInitializing()); | ||
|
||
anon::ConfigureProcessorForUse(context, ConfigurationProcessor{ anon::CreateConfigurationSetProcessorFactory(context) }); | ||
} | ||
|
||
void CreateConfigurationProcessor(Context& context) | ||
{ | ||
context << | ||
ExecuteUriValidation(UriValidationSource::ConfigurationSource) << |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could ExecuteUriValidation
happen after we set up the progress reporting and message? Just in case it takes a while
@@ -2834,6 +2842,14 @@ Please specify one of them using the --source option to proceed.</value> | |||
<value>Enable Windows Package Manager proxy command line options</value> | |||
<comment>Describes a Group Policy that can enable the use of the --proxy option to set a proxy</comment> | |||
</data> | |||
<data name="PolicyEnableSmartScreenValidation" xml:space="preserve"> | |||
<value>Enable Windows Package Manager smart screen validation</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<value>Enable Windows Package Manager smart screen validation</value> | |
<value>Enable Windows Package Manager SmartScreen validation</value> |
<comment></comment> | ||
</data> | ||
<data name="PolicyEnableAllowedSecurityZones" xml:space="preserve"> | ||
<value>Enable Windows App Installer Allowed Security Zones</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<value>Enable Windows App Installer Allowed Security Zones</value> | |
<value>Enable Windows Package Manager Allowed Security Zones</value> |
<comment>Error message displayed when an operation is using a URI that was blocked by Microsoft Defender SmartScreen.</comment> | ||
</data> | ||
<data name="UriSecurityZoneBlockedByPolicy" xml:space="preserve"> | ||
<value>The operation you are attempting to apply has been blocked by your administrator.</value> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message could probably be more specific to zones. I think we already have a generic "not allowed by policy" string
#define REQUIRE_OUTPUT_HAS_LOC(_output_, _resource_) \ | ||
REQUIRE(_output_.str().find(Resource::LocString(_resource_).get()) != std::string::npos); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this, we should use it everywhere we do this check
{ | ||
// Check if smart screen is required for a given zone. | ||
bool IsSmartScreenRequired(Settings::SecurityZoneOptions zone) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We generally put all the internal helpers inside an anonymous namespace
namespace AppInstaller::CLI::Workflow
{
namespace
{
// Helpers here
}
}
I think we should add a command line flag to bypass SmartScreen if it fails, and an admin setting to disable the SmartScreen checks without needing to use group policy. |
Description
TODO
Follow ups
Microsoft Reviewers: Open in CodeFlow