Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,6 +105,7 @@ FILEOS
FILESINUSE
FILESUBTYPE
FILEVERSION
florelis
FLUSHEACHLINE
forcerestart
gdi
Expand Down
98 changes: 98 additions & 0 deletions doc/specs/#190 - Proxy Support.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
---
author: Flor Chacon @florelis
created on: 2024-02-07
last updated: 2024-02-07
issue id: 190
---

# Proxy support

For [#190](https://github.com/microsoft/winget-cli/issues/190)

## Abstract

This spec describes a feature to specify a proxy for winget to use when connecting to the internet.

## Solution Design

A new command line argument will be added to specify a proxy to use during a particular invocation of winget.
This functionality will first need to be enabled through an admin setting, similar to local manifests or hash override.

An option to set a default proxy to use on every flow will be added, but it will require administrator permissions to be set.

New Group Policy will also be added for IT admins to control the use of proxies.
The policies will be similar to those we already have for sources, so that a specific proxy can be required or only a predefined set of proxies can be allowed.

Proxies will not be used for the configuration features for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we do the proxy configuration at wininet, DO, restclient level, then winget configuration should already be covered. Is there something I missed?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the configuration code so I may be wrong, but the way I understand it is that that part of the code is mostly independent of the "package manager" side of things and some of it is written in .net. That's why I didn't include it in this.

I also don't know what network connections are done on that side. The only one that comes to mind is downloading the PS modules for each resource. If that's the only one, I don't see much case on going through the work of making it available on that side

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If PowerShell allows control over a proxy, then we could tunnel settings along to it. Currently, the proxy would only affect the ability to retrieve a configuration document from the internet.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with extending the use of proxies to configuration, but it doesn't make much sense to me if it will only affect retrieving the configuration file.

The Install-Module cmdlet has a -Proxy argument but it "ignores this parameter since it's not supported by Install-PSResource," so it doesn't really help.

Apparently we could also set the WebRequest.DefaultWebProxy property to set it for the whole PSSession, but we'd need to try it to be sure it works for this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, I'm fine with leaving configuration as future. I was just asking a naive question and I did not mean to add scope on this work.

Proxy settings in winget will not affect the behavior of installers themselves, so an installation may still generate traffic outside of the proxy.

The proxy will be used to download the installers and access the sources.

Since the APIs used for Delivery Optimization and MSIX deployment do not provide a way to specify a custom proxy, if a proxy is specified, we will change the use of those APIs to accomodate the proxy.
For Delivery Optimization, a proxy will force use of WinINet instead.
For MSIX deployment, the packages will be fully downloaded before deploying; this will require more network traffic than a streaming install of only the required bits.

## UI/UX Design

We will add a command line argument taking the URI to the proxy.
A separate argument will be available to disable the use of proxy if there is a default set.
Both of these arguments will be disabled by default and require admin privileges to enable.

```
> winget settings --enable ProxyCommandLineArgument
Comment thread
florelis marked this conversation as resolved.
> winget install Contoso.App --proxy https://127.0.0.1:2345
> winget install Contoso.App --no-proxy
```

To configure the default proxy, new `set` and `reset` subcommands will be added to the `settings` command.
This will require admin privileges and does not require `ProxyCommandLineArgument` to be enabled.

```
> winget settings set DefaultProxy https://127.0.0.1:2345
> winget settings reset DefaultProxy
```

The current default proxy will be added to the output `winget --info`.

## Capabilities

### Accessibility

This should have no direct impact on accessibility.

### Security

There is a possibility of an attacker using a malicious proxy to tamper with the data received from the source, or with the contents of the installer file.
This is not much different from the risks of using a public network.
The following mitigating factors will be in place:
* (New) The ability to set a default proxy will be restricted to administrators, to prevent attackers from adding a proxy without the user realizing.
* (New) A Group Policy will be available to block the use of proxies, require the use of a specific proxy, or limit them to an approved list.
* Pre-indexed sources need to be signed, and the publisher is required to match during source update.
When initially adding the source, administrator privileges are already required to limit misuse.
* Pre-indexed sources include manifest hashes in the local database, to ensure that the manifest downloaded later is as expected.
* For the Microsoft Store source, we use certificate pinning to ensure we are talking to the right server.
* When communicating with REST sources, the certificate used by the source for HTTPS needs to match the domain.
* Manifests include a hash of the installer that is validated before executing it.
The ability to ignore installer hash mismatches is disabled by default, and enabling it requires administrator privileges.

Comment thread
florelis marked this conversation as resolved.
### Compatibility

No breaking changes to existing behavior.

### Performance, Power, and Efficiency

There should not be any notable performance changes.

## Potential Issues

A faulty or misconfigured proxy could impact most of winget's functionality, but it can be worked around by disabling the use of the proxy.

## Future considerations
Comment thread
florelis marked this conversation as resolved.

Things we may want to consider in the future:
* Extend support for proxies to the Configuration feature
* Add proxy support to the COM API
* Add support for proxies that require authentication

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is an option to use DefaultNetworkCredentials when creating a proxy connection. Will this / should this be used in the initial implementation to enable domain-joined accounts to use their domain proxy? Just thinking that it may reduce the need to fully support authentication while providing a solution that addresses many enterprise security items

* Add the ability for admins to set multiple allowed proxies that a user can use
* Add the ability to specify a different default proxy for each source
* Use proxies with Delivery Optimization. This requires changes to the Delivery Optimization APIs.
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,6 +105,7 @@ FILEOS
FILESINUSE
FILESUBTYPE
FILEVERSION
florelis
FLUSHEACHLINE
forcerestart
gdi
Expand Down
98 changes: 98 additions & 0 deletions doc/specs/#190 - Proxy Support.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
---
author: Flor Chacon @florelis
created on: 2024-02-07
last updated: 2024-02-07
issue id: 190
---

# Proxy support

For [#190](https://github.com/microsoft/winget-cli/issues/190)

## Abstract

This spec describes a feature to specify a proxy for winget to use when connecting to the internet.

## Solution Design

A new command line argument will be added to specify a proxy to use during a particular invocation of winget.
This functionality will first need to be enabled through an admin setting, similar to local manifests or hash override.

An option to set a default proxy to use on every flow will be added, but it will require administrator permissions to be set.

New Group Policy will also be added for IT admins to control the use of proxies.
The policies will be similar to those we already have for sources, so that a specific proxy can be required or only a predefined set of proxies can be allowed.

Proxies will not be used for the configuration features for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we do the proxy configuration at wininet, DO, restclient level, then winget configuration should already be covered. Is there something I missed?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the configuration code so I may be wrong, but the way I understand it is that that part of the code is mostly independent of the "package manager" side of things and some of it is written in .net. That's why I didn't include it in this.

I also don't know what network connections are done on that side. The only one that comes to mind is downloading the PS modules for each resource. If that's the only one, I don't see much case on going through the work of making it available on that side

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If PowerShell allows control over a proxy, then we could tunnel settings along to it. Currently, the proxy would only affect the ability to retrieve a configuration document from the internet.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with extending the use of proxies to configuration, but it doesn't make much sense to me if it will only affect retrieving the configuration file.

The Install-Module cmdlet has a -Proxy argument but it "ignores this parameter since it's not supported by Install-PSResource," so it doesn't really help.

Apparently we could also set the WebRequest.DefaultWebProxy property to set it for the whole PSSession, but we'd need to try it to be sure it works for this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, I'm fine with leaving configuration as future. I was just asking a naive question and I did not mean to add scope on this work.

Proxy settings in winget will not affect the behavior of installers themselves, so an installation may still generate traffic outside of the proxy.

The proxy will be used to download the installers and access the sources.

Since the APIs used for Delivery Optimization and MSIX deployment do not provide a way to specify a custom proxy, if a proxy is specified, we will change the use of those APIs to accomodate the proxy.
For Delivery Optimization, a proxy will force use of WinINet instead.
For MSIX deployment, the packages will be fully downloaded before deploying; this will require more network traffic than a streaming install of only the required bits.

## UI/UX Design

We will add a command line argument taking the URI to the proxy.
A separate argument will be available to disable the use of proxy if there is a default set.
Both of these arguments will be disabled by default and require admin privileges to enable.

```
> winget settings --enable ProxyCommandLineArgument
Comment thread
florelis marked this conversation as resolved.
> winget install Contoso.App --proxy https://127.0.0.1:2345
> winget install Contoso.App --no-proxy
```

To configure the default proxy, new `set` and `reset` subcommands will be added to the `settings` command.
This will require admin privileges and does not require `ProxyCommandLineArgument` to be enabled.

```
> winget settings set DefaultProxy https://127.0.0.1:2345
> winget settings reset DefaultProxy
```

The current default proxy will be added to the output `winget --info`.

## Capabilities

### Accessibility

This should have no direct impact on accessibility.

### Security

There is a possibility of an attacker using a malicious proxy to tamper with the data received from the source, or with the contents of the installer file.
This is not much different from the risks of using a public network.
The following mitigating factors will be in place:
* (New) The ability to set a default proxy will be restricted to administrators, to prevent attackers from adding a proxy without the user realizing.
* (New) A Group Policy will be available to block the use of proxies, require the use of a specific proxy, or limit them to an approved list.
* Pre-indexed sources need to be signed, and the publisher is required to match during source update.
When initially adding the source, administrator privileges are already required to limit misuse.
* Pre-indexed sources include manifest hashes in the local database, to ensure that the manifest downloaded later is as expected.
* For the Microsoft Store source, we use certificate pinning to ensure we are talking to the right server.
* When communicating with REST sources, the certificate used by the source for HTTPS needs to match the domain.
* Manifests include a hash of the installer that is validated before executing it.
The ability to ignore installer hash mismatches is disabled by default, and enabling it requires administrator privileges.

Comment thread
florelis marked this conversation as resolved.
### Compatibility

No breaking changes to existing behavior.

### Performance, Power, and Efficiency

There should not be any notable performance changes.

## Potential Issues

A faulty or misconfigured proxy could impact most of winget's functionality, but it can be worked around by disabling the use of the proxy.

## Future considerations
Comment thread
florelis marked this conversation as resolved.

Things we may want to consider in the future:
* Extend support for proxies to the Configuration feature
* Add proxy support to the COM API
* Add support for proxies that require authentication

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is an option to use DefaultNetworkCredentials when creating a proxy connection. Will this / should this be used in the initial implementation to enable domain-joined accounts to use their domain proxy? Just thinking that it may reduce the need to fully support authentication while providing a solution that addresses many enterprise security items

* Add the ability for admins to set multiple allowed proxies that a user can use
* Add the ability to specify a different default proxy for each source
* Use proxies with Delivery Optimization. This requires changes to the Delivery Optimization APIs.
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,6 +105,7 @@ FILEOS
FILESINUSE
FILESUBTYPE
FILEVERSION
florelis
FLUSHEACHLINE
forcerestart
gdi
Expand Down
98 changes: 98 additions & 0 deletions doc/specs/#190 - Proxy Support.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
---
author: Flor Chacon @florelis
created on: 2024-02-07
last updated: 2024-02-07
issue id: 190
---

# Proxy support

For [#190](https://github.com/microsoft/winget-cli/issues/190)

## Abstract

This spec describes a feature to specify a proxy for winget to use when connecting to the internet.

## Solution Design

A new command line argument will be added to specify a proxy to use during a particular invocation of winget.
This functionality will first need to be enabled through an admin setting, similar to local manifests or hash override.

An option to set a default proxy to use on every flow will be added, but it will require administrator permissions to be set.

New Group Policy will also be added for IT admins to control the use of proxies.
The policies will be similar to those we already have for sources, so that a specific proxy can be required or only a predefined set of proxies can be allowed.

Proxies will not be used for the configuration features for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we do the proxy configuration at wininet, DO, restclient level, then winget configuration should already be covered. Is there something I missed?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the configuration code so I may be wrong, but the way I understand it is that that part of the code is mostly independent of the "package manager" side of things and some of it is written in .net. That's why I didn't include it in this.

I also don't know what network connections are done on that side. The only one that comes to mind is downloading the PS modules for each resource. If that's the only one, I don't see much case on going through the work of making it available on that side

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If PowerShell allows control over a proxy, then we could tunnel settings along to it. Currently, the proxy would only affect the ability to retrieve a configuration document from the internet.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with extending the use of proxies to configuration, but it doesn't make much sense to me if it will only affect retrieving the configuration file.

The Install-Module cmdlet has a -Proxy argument but it "ignores this parameter since it's not supported by Install-PSResource," so it doesn't really help.

Apparently we could also set the WebRequest.DefaultWebProxy property to set it for the whole PSSession, but we'd need to try it to be sure it works for this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, I'm fine with leaving configuration as future. I was just asking a naive question and I did not mean to add scope on this work.

Proxy settings in winget will not affect the behavior of installers themselves, so an installation may still generate traffic outside of the proxy.

The proxy will be used to download the installers and access the sources.

Since the APIs used for Delivery Optimization and MSIX deployment do not provide a way to specify a custom proxy, if a proxy is specified, we will change the use of those APIs to accomodate the proxy.
For Delivery Optimization, a proxy will force use of WinINet instead.
For MSIX deployment, the packages will be fully downloaded before deploying; this will require more network traffic than a streaming install of only the required bits.

## UI/UX Design

We will add a command line argument taking the URI to the proxy.
A separate argument will be available to disable the use of proxy if there is a default set.
Both of these arguments will be disabled by default and require admin privileges to enable.

```
> winget settings --enable ProxyCommandLineArgument
Comment thread
florelis marked this conversation as resolved.
> winget install Contoso.App --proxy https://127.0.0.1:2345
> winget install Contoso.App --no-proxy
```

To configure the default proxy, new `set` and `reset` subcommands will be added to the `settings` command.
This will require admin privileges and does not require `ProxyCommandLineArgument` to be enabled.

```
> winget settings set DefaultProxy https://127.0.0.1:2345
> winget settings reset DefaultProxy
```

The current default proxy will be added to the output `winget --info`.

## Capabilities

### Accessibility

This should have no direct impact on accessibility.

### Security

There is a possibility of an attacker using a malicious proxy to tamper with the data received from the source, or with the contents of the installer file.
This is not much different from the risks of using a public network.
The following mitigating factors will be in place:
* (New) The ability to set a default proxy will be restricted to administrators, to prevent attackers from adding a proxy without the user realizing.
* (New) A Group Policy will be available to block the use of proxies, require the use of a specific proxy, or limit them to an approved list.
* Pre-indexed sources need to be signed, and the publisher is required to match during source update.
When initially adding the source, administrator privileges are already required to limit misuse.
* Pre-indexed sources include manifest hashes in the local database, to ensure that the manifest downloaded later is as expected.
* For the Microsoft Store source, we use certificate pinning to ensure we are talking to the right server.
* When communicating with REST sources, the certificate used by the source for HTTPS needs to match the domain.
* Manifests include a hash of the installer that is validated before executing it.
The ability to ignore installer hash mismatches is disabled by default, and enabling it requires administrator privileges.

Comment thread
florelis marked this conversation as resolved.
### Compatibility

No breaking changes to existing behavior.

### Performance, Power, and Efficiency

There should not be any notable performance changes.

## Potential Issues

A faulty or misconfigured proxy could impact most of winget's functionality, but it can be worked around by disabling the use of the proxy.

## Future considerations
Comment thread
florelis marked this conversation as resolved.

Things we may want to consider in the future:
* Extend support for proxies to the Configuration feature
* Add proxy support to the COM API
* Add support for proxies that require authentication

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is an option to use DefaultNetworkCredentials when creating a proxy connection. Will this / should this be used in the initial implementation to enable domain-joined accounts to use their domain proxy? Just thinking that it may reduce the need to fully support authentication while providing a solution that addresses many enterprise security items

* Add the ability for admins to set multiple allowed proxies that a user can use
* Add the ability to specify a different default proxy for each source
* Use proxies with Delivery Optimization. This requires changes to the Delivery Optimization APIs.
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,6 +105,7 @@ FILEOS
FILESINUSE
FILESUBTYPE
FILEVERSION
florelis
FLUSHEACHLINE
forcerestart
gdi
Expand Down
98 changes: 98 additions & 0 deletions doc/specs/#190 - Proxy Support.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
---
author: Flor Chacon @florelis
created on: 2024-02-07
last updated: 2024-02-07
issue id: 190
---

# Proxy support

For [#190](https://github.com/microsoft/winget-cli/issues/190)

## Abstract

This spec describes a feature to specify a proxy for winget to use when connecting to the internet.

## Solution Design

A new command line argument will be added to specify a proxy to use during a particular invocation of winget.
This functionality will first need to be enabled through an admin setting, similar to local manifests or hash override.

An option to set a default proxy to use on every flow will be added, but it will require administrator permissions to be set.

New Group Policy will also be added for IT admins to control the use of proxies.
The policies will be similar to those we already have for sources, so that a specific proxy can be required or only a predefined set of proxies can be allowed.

Proxies will not be used for the configuration features for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we do the proxy configuration at wininet, DO, restclient level, then winget configuration should already be covered. Is there something I missed?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the configuration code so I may be wrong, but the way I understand it is that that part of the code is mostly independent of the "package manager" side of things and some of it is written in .net. That's why I didn't include it in this.

I also don't know what network connections are done on that side. The only one that comes to mind is downloading the PS modules for each resource. If that's the only one, I don't see much case on going through the work of making it available on that side

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If PowerShell allows control over a proxy, then we could tunnel settings along to it. Currently, the proxy would only affect the ability to retrieve a configuration document from the internet.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with extending the use of proxies to configuration, but it doesn't make much sense to me if it will only affect retrieving the configuration file.

The Install-Module cmdlet has a -Proxy argument but it "ignores this parameter since it's not supported by Install-PSResource," so it doesn't really help.

Apparently we could also set the WebRequest.DefaultWebProxy property to set it for the whole PSSession, but we'd need to try it to be sure it works for this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, I'm fine with leaving configuration as future. I was just asking a naive question and I did not mean to add scope on this work.

Proxy settings in winget will not affect the behavior of installers themselves, so an installation may still generate traffic outside of the proxy.

The proxy will be used to download the installers and access the sources.

Since the APIs used for Delivery Optimization and MSIX deployment do not provide a way to specify a custom proxy, if a proxy is specified, we will change the use of those APIs to accomodate the proxy.
For Delivery Optimization, a proxy will force use of WinINet instead.
For MSIX deployment, the packages will be fully downloaded before deploying; this will require more network traffic than a streaming install of only the required bits.

## UI/UX Design

We will add a command line argument taking the URI to the proxy.
A separate argument will be available to disable the use of proxy if there is a default set.
Both of these arguments will be disabled by default and require admin privileges to enable.

```
> winget settings --enable ProxyCommandLineArgument
Comment thread
florelis marked this conversation as resolved.
> winget install Contoso.App --proxy https://127.0.0.1:2345
> winget install Contoso.App --no-proxy
```

To configure the default proxy, new `set` and `reset` subcommands will be added to the `settings` command.
This will require admin privileges and does not require `ProxyCommandLineArgument` to be enabled.

```
> winget settings set DefaultProxy https://127.0.0.1:2345
> winget settings reset DefaultProxy
```

The current default proxy will be added to the output `winget --info`.

## Capabilities

### Accessibility

This should have no direct impact on accessibility.

### Security

There is a possibility of an attacker using a malicious proxy to tamper with the data received from the source, or with the contents of the installer file.
This is not much different from the risks of using a public network.
The following mitigating factors will be in place:
* (New) The ability to set a default proxy will be restricted to administrators, to prevent attackers from adding a proxy without the user realizing.
* (New) A Group Policy will be available to block the use of proxies, require the use of a specific proxy, or limit them to an approved list.
* Pre-indexed sources need to be signed, and the publisher is required to match during source update.
When initially adding the source, administrator privileges are already required to limit misuse.
* Pre-indexed sources include manifest hashes in the local database, to ensure that the manifest downloaded later is as expected.
* For the Microsoft Store source, we use certificate pinning to ensure we are talking to the right server.
* When communicating with REST sources, the certificate used by the source for HTTPS needs to match the domain.
* Manifests include a hash of the installer that is validated before executing it.
The ability to ignore installer hash mismatches is disabled by default, and enabling it requires administrator privileges.

Comment thread
florelis marked this conversation as resolved.
### Compatibility

No breaking changes to existing behavior.

### Performance, Power, and Efficiency

There should not be any notable performance changes.

## Potential Issues

A faulty or misconfigured proxy could impact most of winget's functionality, but it can be worked around by disabling the use of the proxy.

## Future considerations
Comment thread
florelis marked this conversation as resolved.

Things we may want to consider in the future:
* Extend support for proxies to the Configuration feature
* Add proxy support to the COM API
* Add support for proxies that require authentication

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is an option to use DefaultNetworkCredentials when creating a proxy connection. Will this / should this be used in the initial implementation to enable domain-joined accounts to use their domain proxy? Just thinking that it may reduce the need to fully support authentication while providing a solution that addresses many enterprise security items

* Add the ability for admins to set multiple allowed proxies that a user can use
* Add the ability to specify a different default proxy for each source
* Use proxies with Delivery Optimization. This requires changes to the Delivery Optimization APIs.
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,6 +105,7 @@ FILEOS
FILESINUSE
FILESUBTYPE
FILEVERSION
florelis
FLUSHEACHLINE
forcerestart
gdi
Expand Down
98 changes: 98 additions & 0 deletions doc/specs/#190 - Proxy Support.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
---
author: Flor Chacon @florelis
created on: 2024-02-07
last updated: 2024-02-07
issue id: 190
---

# Proxy support

For [#190](https://github.com/microsoft/winget-cli/issues/190)

## Abstract

This spec describes a feature to specify a proxy for winget to use when connecting to the internet.

## Solution Design

A new command line argument will be added to specify a proxy to use during a particular invocation of winget.
This functionality will first need to be enabled through an admin setting, similar to local manifests or hash override.

An option to set a default proxy to use on every flow will be added, but it will require administrator permissions to be set.

New Group Policy will also be added for IT admins to control the use of proxies.
The policies will be similar to those we already have for sources, so that a specific proxy can be required or only a predefined set of proxies can be allowed.

Proxies will not be used for the configuration features for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we do the proxy configuration at wininet, DO, restclient level, then winget configuration should already be covered. Is there something I missed?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the configuration code so I may be wrong, but the way I understand it is that that part of the code is mostly independent of the "package manager" side of things and some of it is written in .net. That's why I didn't include it in this.

I also don't know what network connections are done on that side. The only one that comes to mind is downloading the PS modules for each resource. If that's the only one, I don't see much case on going through the work of making it available on that side

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If PowerShell allows control over a proxy, then we could tunnel settings along to it. Currently, the proxy would only affect the ability to retrieve a configuration document from the internet.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with extending the use of proxies to configuration, but it doesn't make much sense to me if it will only affect retrieving the configuration file.

The Install-Module cmdlet has a -Proxy argument but it "ignores this parameter since it's not supported by Install-PSResource," so it doesn't really help.

Apparently we could also set the WebRequest.DefaultWebProxy property to set it for the whole PSSession, but we'd need to try it to be sure it works for this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, I'm fine with leaving configuration as future. I was just asking a naive question and I did not mean to add scope on this work.

Proxy settings in winget will not affect the behavior of installers themselves, so an installation may still generate traffic outside of the proxy.

The proxy will be used to download the installers and access the sources.

Since the APIs used for Delivery Optimization and MSIX deployment do not provide a way to specify a custom proxy, if a proxy is specified, we will change the use of those APIs to accomodate the proxy.
For Delivery Optimization, a proxy will force use of WinINet instead.
For MSIX deployment, the packages will be fully downloaded before deploying; this will require more network traffic than a streaming install of only the required bits.

## UI/UX Design

We will add a command line argument taking the URI to the proxy.
A separate argument will be available to disable the use of proxy if there is a default set.
Both of these arguments will be disabled by default and require admin privileges to enable.

```
> winget settings --enable ProxyCommandLineArgument
Comment thread
florelis marked this conversation as resolved.
> winget install Contoso.App --proxy https://127.0.0.1:2345
> winget install Contoso.App --no-proxy
```

To configure the default proxy, new `set` and `reset` subcommands will be added to the `settings` command.
This will require admin privileges and does not require `ProxyCommandLineArgument` to be enabled.

```
> winget settings set DefaultProxy https://127.0.0.1:2345
> winget settings reset DefaultProxy
```

The current default proxy will be added to the output `winget --info`.

## Capabilities

### Accessibility

This should have no direct impact on accessibility.

### Security

There is a possibility of an attacker using a malicious proxy to tamper with the data received from the source, or with the contents of the installer file.
This is not much different from the risks of using a public network.
The following mitigating factors will be in place:
* (New) The ability to set a default proxy will be restricted to administrators, to prevent attackers from adding a proxy without the user realizing.
* (New) A Group Policy will be available to block the use of proxies, require the use of a specific proxy, or limit them to an approved list.
* Pre-indexed sources need to be signed, and the publisher is required to match during source update.
When initially adding the source, administrator privileges are already required to limit misuse.
* Pre-indexed sources include manifest hashes in the local database, to ensure that the manifest downloaded later is as expected.
* For the Microsoft Store source, we use certificate pinning to ensure we are talking to the right server.
* When communicating with REST sources, the certificate used by the source for HTTPS needs to match the domain.
* Manifests include a hash of the installer that is validated before executing it.
The ability to ignore installer hash mismatches is disabled by default, and enabling it requires administrator privileges.

Comment thread
florelis marked this conversation as resolved.
### Compatibility

No breaking changes to existing behavior.

### Performance, Power, and Efficiency

There should not be any notable performance changes.

## Potential Issues

A faulty or misconfigured proxy could impact most of winget's functionality, but it can be worked around by disabling the use of the proxy.

## Future considerations
Comment thread
florelis marked this conversation as resolved.

Things we may want to consider in the future:
* Extend support for proxies to the Configuration feature
* Add proxy support to the COM API
* Add support for proxies that require authentication

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is an option to use DefaultNetworkCredentials when creating a proxy connection. Will this / should this be used in the initial implementation to enable domain-joined accounts to use their domain proxy? Just thinking that it may reduce the need to fully support authentication while providing a solution that addresses many enterprise security items

* Add the ability for admins to set multiple allowed proxies that a user can use
* Add the ability to specify a different default proxy for each source
* Use proxies with Delivery Optimization. This requires changes to the Delivery Optimization APIs.
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,6 +105,7 @@ FILEOS
FILESINUSE
FILESUBTYPE
FILEVERSION
florelis
FLUSHEACHLINE
forcerestart
gdi
Expand Down
98 changes: 98 additions & 0 deletions doc/specs/#190 - Proxy Support.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
---
author: Flor Chacon @florelis
created on: 2024-02-07
last updated: 2024-02-07
issue id: 190
---

# Proxy support

For [#190](https://github.com/microsoft/winget-cli/issues/190)

## Abstract

This spec describes a feature to specify a proxy for winget to use when connecting to the internet.

## Solution Design

A new command line argument will be added to specify a proxy to use during a particular invocation of winget.
This functionality will first need to be enabled through an admin setting, similar to local manifests or hash override.

An option to set a default proxy to use on every flow will be added, but it will require administrator permissions to be set.

New Group Policy will also be added for IT admins to control the use of proxies.
The policies will be similar to those we already have for sources, so that a specific proxy can be required or only a predefined set of proxies can be allowed.

Proxies will not be used for the configuration features for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we do the proxy configuration at wininet, DO, restclient level, then winget configuration should already be covered. Is there something I missed?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the configuration code so I may be wrong, but the way I understand it is that that part of the code is mostly independent of the "package manager" side of things and some of it is written in .net. That's why I didn't include it in this.

I also don't know what network connections are done on that side. The only one that comes to mind is downloading the PS modules for each resource. If that's the only one, I don't see much case on going through the work of making it available on that side

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If PowerShell allows control over a proxy, then we could tunnel settings along to it. Currently, the proxy would only affect the ability to retrieve a configuration document from the internet.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with extending the use of proxies to configuration, but it doesn't make much sense to me if it will only affect retrieving the configuration file.

The Install-Module cmdlet has a -Proxy argument but it "ignores this parameter since it's not supported by Install-PSResource," so it doesn't really help.

Apparently we could also set the WebRequest.DefaultWebProxy property to set it for the whole PSSession, but we'd need to try it to be sure it works for this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, I'm fine with leaving configuration as future. I was just asking a naive question and I did not mean to add scope on this work.

Proxy settings in winget will not affect the behavior of installers themselves, so an installation may still generate traffic outside of the proxy.

The proxy will be used to download the installers and access the sources.

Since the APIs used for Delivery Optimization and MSIX deployment do not provide a way to specify a custom proxy, if a proxy is specified, we will change the use of those APIs to accomodate the proxy.
For Delivery Optimization, a proxy will force use of WinINet instead.
For MSIX deployment, the packages will be fully downloaded before deploying; this will require more network traffic than a streaming install of only the required bits.

## UI/UX Design

We will add a command line argument taking the URI to the proxy.
A separate argument will be available to disable the use of proxy if there is a default set.
Both of these arguments will be disabled by default and require admin privileges to enable.

```
> winget settings --enable ProxyCommandLineArgument
Comment thread
florelis marked this conversation as resolved.
> winget install Contoso.App --proxy https://127.0.0.1:2345
> winget install Contoso.App --no-proxy
```

To configure the default proxy, new `set` and `reset` subcommands will be added to the `settings` command.
This will require admin privileges and does not require `ProxyCommandLineArgument` to be enabled.

```
> winget settings set DefaultProxy https://127.0.0.1:2345
> winget settings reset DefaultProxy
```

The current default proxy will be added to the output `winget --info`.

## Capabilities

### Accessibility

This should have no direct impact on accessibility.

### Security

There is a possibility of an attacker using a malicious proxy to tamper with the data received from the source, or with the contents of the installer file.
This is not much different from the risks of using a public network.
The following mitigating factors will be in place:
* (New) The ability to set a default proxy will be restricted to administrators, to prevent attackers from adding a proxy without the user realizing.
* (New) A Group Policy will be available to block the use of proxies, require the use of a specific proxy, or limit them to an approved list.
* Pre-indexed sources need to be signed, and the publisher is required to match during source update.
When initially adding the source, administrator privileges are already required to limit misuse.
* Pre-indexed sources include manifest hashes in the local database, to ensure that the manifest downloaded later is as expected.
* For the Microsoft Store source, we use certificate pinning to ensure we are talking to the right server.
* When communicating with REST sources, the certificate used by the source for HTTPS needs to match the domain.
* Manifests include a hash of the installer that is validated before executing it.
The ability to ignore installer hash mismatches is disabled by default, and enabling it requires administrator privileges.

Comment thread
florelis marked this conversation as resolved.
### Compatibility

No breaking changes to existing behavior.

### Performance, Power, and Efficiency

There should not be any notable performance changes.

## Potential Issues

A faulty or misconfigured proxy could impact most of winget's functionality, but it can be worked around by disabling the use of the proxy.

## Future considerations
Comment thread
florelis marked this conversation as resolved.

Things we may want to consider in the future:
* Extend support for proxies to the Configuration feature
* Add proxy support to the COM API
* Add support for proxies that require authentication

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is an option to use DefaultNetworkCredentials when creating a proxy connection. Will this / should this be used in the initial implementation to enable domain-joined accounts to use their domain proxy? Just thinking that it may reduce the need to fully support authentication while providing a solution that addresses many enterprise security items

* Add the ability for admins to set multiple allowed proxies that a user can use
* Add the ability to specify a different default proxy for each source
* Use proxies with Delivery Optimization. This requires changes to the Delivery Optimization APIs.
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,6 +105,7 @@ FILEOS
FILESINUSE
FILESUBTYPE
FILEVERSION
florelis
FLUSHEACHLINE
forcerestart
gdi
Expand Down
98 changes: 98 additions & 0 deletions doc/specs/#190 - Proxy Support.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
---
author: Flor Chacon @florelis
created on: 2024-02-07
last updated: 2024-02-07
issue id: 190
---

# Proxy support

For [#190](https://github.com/microsoft/winget-cli/issues/190)

## Abstract

This spec describes a feature to specify a proxy for winget to use when connecting to the internet.

## Solution Design

A new command line argument will be added to specify a proxy to use during a particular invocation of winget.
This functionality will first need to be enabled through an admin setting, similar to local manifests or hash override.

An option to set a default proxy to use on every flow will be added, but it will require administrator permissions to be set.

New Group Policy will also be added for IT admins to control the use of proxies.
The policies will be similar to those we already have for sources, so that a specific proxy can be required or only a predefined set of proxies can be allowed.

Proxies will not be used for the configuration features for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we do the proxy configuration at wininet, DO, restclient level, then winget configuration should already be covered. Is there something I missed?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the configuration code so I may be wrong, but the way I understand it is that that part of the code is mostly independent of the "package manager" side of things and some of it is written in .net. That's why I didn't include it in this.

I also don't know what network connections are done on that side. The only one that comes to mind is downloading the PS modules for each resource. If that's the only one, I don't see much case on going through the work of making it available on that side

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If PowerShell allows control over a proxy, then we could tunnel settings along to it. Currently, the proxy would only affect the ability to retrieve a configuration document from the internet.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with extending the use of proxies to configuration, but it doesn't make much sense to me if it will only affect retrieving the configuration file.

The Install-Module cmdlet has a -Proxy argument but it "ignores this parameter since it's not supported by Install-PSResource," so it doesn't really help.

Apparently we could also set the WebRequest.DefaultWebProxy property to set it for the whole PSSession, but we'd need to try it to be sure it works for this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, I'm fine with leaving configuration as future. I was just asking a naive question and I did not mean to add scope on this work.

Proxy settings in winget will not affect the behavior of installers themselves, so an installation may still generate traffic outside of the proxy.

The proxy will be used to download the installers and access the sources.

Since the APIs used for Delivery Optimization and MSIX deployment do not provide a way to specify a custom proxy, if a proxy is specified, we will change the use of those APIs to accomodate the proxy.
For Delivery Optimization, a proxy will force use of WinINet instead.
For MSIX deployment, the packages will be fully downloaded before deploying; this will require more network traffic than a streaming install of only the required bits.

## UI/UX Design

We will add a command line argument taking the URI to the proxy.
A separate argument will be available to disable the use of proxy if there is a default set.
Both of these arguments will be disabled by default and require admin privileges to enable.

```
> winget settings --enable ProxyCommandLineArgument
Comment thread
florelis marked this conversation as resolved.
> winget install Contoso.App --proxy https://127.0.0.1:2345
> winget install Contoso.App --no-proxy
```

To configure the default proxy, new `set` and `reset` subcommands will be added to the `settings` command.
This will require admin privileges and does not require `ProxyCommandLineArgument` to be enabled.

```
> winget settings set DefaultProxy https://127.0.0.1:2345
> winget settings reset DefaultProxy
```

The current default proxy will be added to the output `winget --info`.

## Capabilities

### Accessibility

This should have no direct impact on accessibility.

### Security

There is a possibility of an attacker using a malicious proxy to tamper with the data received from the source, or with the contents of the installer file.
This is not much different from the risks of using a public network.
The following mitigating factors will be in place:
* (New) The ability to set a default proxy will be restricted to administrators, to prevent attackers from adding a proxy without the user realizing.
* (New) A Group Policy will be available to block the use of proxies, require the use of a specific proxy, or limit them to an approved list.
* Pre-indexed sources need to be signed, and the publisher is required to match during source update.
When initially adding the source, administrator privileges are already required to limit misuse.
* Pre-indexed sources include manifest hashes in the local database, to ensure that the manifest downloaded later is as expected.
* For the Microsoft Store source, we use certificate pinning to ensure we are talking to the right server.
* When communicating with REST sources, the certificate used by the source for HTTPS needs to match the domain.
* Manifests include a hash of the installer that is validated before executing it.
The ability to ignore installer hash mismatches is disabled by default, and enabling it requires administrator privileges.

Comment thread
florelis marked this conversation as resolved.
### Compatibility

No breaking changes to existing behavior.

### Performance, Power, and Efficiency

There should not be any notable performance changes.

## Potential Issues

A faulty or misconfigured proxy could impact most of winget's functionality, but it can be worked around by disabling the use of the proxy.

## Future considerations
Comment thread
florelis marked this conversation as resolved.

Things we may want to consider in the future:
* Extend support for proxies to the Configuration feature
* Add proxy support to the COM API
* Add support for proxies that require authentication

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is an option to use DefaultNetworkCredentials when creating a proxy connection. Will this / should this be used in the initial implementation to enable domain-joined accounts to use their domain proxy? Just thinking that it may reduce the need to fully support authentication while providing a solution that addresses many enterprise security items

* Add the ability for admins to set multiple allowed proxies that a user can use
* Add the ability to specify a different default proxy for each source
* Use proxies with Delivery Optimization. This requires changes to the Delivery Optimization APIs.
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/actions/spelling/allow.txt
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,6 +105,7 @@ FILEOS
FILESINUSE
FILESUBTYPE
FILEVERSION
florelis
FLUSHEACHLINE
forcerestart
gdi
Expand Down
98 changes: 98 additions & 0 deletions doc/specs/#190 - Proxy Support.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
---
author: Flor Chacon @florelis
created on: 2024-02-07
last updated: 2024-02-07
issue id: 190
---

# Proxy support

For [#190](https://github.com/microsoft/winget-cli/issues/190)

## Abstract

This spec describes a feature to specify a proxy for winget to use when connecting to the internet.

## Solution Design

A new command line argument will be added to specify a proxy to use during a particular invocation of winget.
This functionality will first need to be enabled through an admin setting, similar to local manifests or hash override.

An option to set a default proxy to use on every flow will be added, but it will require administrator permissions to be set.

New Group Policy will also be added for IT admins to control the use of proxies.
The policies will be similar to those we already have for sources, so that a specific proxy can be required or only a predefined set of proxies can be allowed.

Proxies will not be used for the configuration features for now.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we do the proxy configuration at wininet, DO, restclient level, then winget configuration should already be covered. Is there something I missed?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not familiar with the configuration code so I may be wrong, but the way I understand it is that that part of the code is mostly independent of the "package manager" side of things and some of it is written in .net. That's why I didn't include it in this.

I also don't know what network connections are done on that side. The only one that comes to mind is downloading the PS modules for each resource. If that's the only one, I don't see much case on going through the work of making it available on that side

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If PowerShell allows control over a proxy, then we could tunnel settings along to it. Currently, the proxy would only affect the ability to retrieve a configuration document from the internet.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with extending the use of proxies to configuration, but it doesn't make much sense to me if it will only affect retrieving the configuration file.

The Install-Module cmdlet has a -Proxy argument but it "ignores this parameter since it's not supported by Install-PSResource," so it doesn't really help.

Apparently we could also set the WebRequest.DefaultWebProxy property to set it for the whole PSSession, but we'd need to try it to be sure it works for this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, I'm fine with leaving configuration as future. I was just asking a naive question and I did not mean to add scope on this work.

Proxy settings in winget will not affect the behavior of installers themselves, so an installation may still generate traffic outside of the proxy.

The proxy will be used to download the installers and access the sources.

Since the APIs used for Delivery Optimization and MSIX deployment do not provide a way to specify a custom proxy, if a proxy is specified, we will change the use of those APIs to accomodate the proxy.
For Delivery Optimization, a proxy will force use of WinINet instead.
For MSIX deployment, the packages will be fully downloaded before deploying; this will require more network traffic than a streaming install of only the required bits.

## UI/UX Design

We will add a command line argument taking the URI to the proxy.
A separate argument will be available to disable the use of proxy if there is a default set.
Both of these arguments will be disabled by default and require admin privileges to enable.

```
> winget settings --enable ProxyCommandLineArgument
Comment thread
florelis marked this conversation as resolved.
> winget install Contoso.App --proxy https://127.0.0.1:2345
> winget install Contoso.App --no-proxy
```

To configure the default proxy, new `set` and `reset` subcommands will be added to the `settings` command.
This will require admin privileges and does not require `ProxyCommandLineArgument` to be enabled.

```
> winget settings set DefaultProxy https://127.0.0.1:2345
> winget settings reset DefaultProxy
```

The current default proxy will be added to the output `winget --info`.

## Capabilities

### Accessibility

This should have no direct impact on accessibility.

### Security

There is a possibility of an attacker using a malicious proxy to tamper with the data received from the source, or with the contents of the installer file.
This is not much different from the risks of using a public network.
The following mitigating factors will be in place:
* (New) The ability to set a default proxy will be restricted to administrators, to prevent attackers from adding a proxy without the user realizing.
* (New) A Group Policy will be available to block the use of proxies, require the use of a specific proxy, or limit them to an approved list.
* Pre-indexed sources need to be signed, and the publisher is required to match during source update.
When initially adding the source, administrator privileges are already required to limit misuse.
* Pre-indexed sources include manifest hashes in the local database, to ensure that the manifest downloaded later is as expected.
* For the Microsoft Store source, we use certificate pinning to ensure we are talking to the right server.
* When communicating with REST sources, the certificate used by the source for HTTPS needs to match the domain.
* Manifests include a hash of the installer that is validated before executing it.
The ability to ignore installer hash mismatches is disabled by default, and enabling it requires administrator privileges.

Comment thread
florelis marked this conversation as resolved.
### Compatibility

No breaking changes to existing behavior.

### Performance, Power, and Efficiency

There should not be any notable performance changes.

## Potential Issues

A faulty or misconfigured proxy could impact most of winget's functionality, but it can be worked around by disabling the use of the proxy.

## Future considerations
Comment thread
florelis marked this conversation as resolved.

Things we may want to consider in the future:
* Extend support for proxies to the Configuration feature
* Add proxy support to the COM API
* Add support for proxies that require authentication

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe there is an option to use DefaultNetworkCredentials when creating a proxy connection. Will this / should this be used in the initial implementation to enable domain-joined accounts to use their domain proxy? Just thinking that it may reduce the need to fully support authentication while providing a solution that addresses many enterprise security items

* Add the ability for admins to set multiple allowed proxies that a user can use
* Add the ability to specify a different default proxy for each source
* Use proxies with Delivery Optimization. This requires changes to the Delivery Optimization APIs.