Overview
An API to modify the proxy settings used by chromium.
- Flip between system proxy settings and custom proxy settings.
- Ability to read (but not write) the system proxy settings.
- Full control when using custom proxy settings (PAC script, bypass regexps, SOCKS options, etc.).
Use cases
Many users have requested wanting separate proxy settings for Chromium than for other applications
(http://crbug.com/266).
On Windows, Chromium uses the WinInet proxy settings — these are the settings used by
Internet Explorer, and are the closest thing to "system proxy settings".
A particular limitation of these WinInet proxy settings, is that they are not location aware —
one common workaround seems to be users run Internet Explorer at work (configured with the corp proxy settings),
and then run Firefox at home (using a different set of proxy settings). This workflow is not
currently supported by Chromium (without resorting to some recent command line overrides).
This API would:
- Enable implementing a FoxyProxy-like extensions (not all functionality is covered by just the proxy settings though).
- Solve http://crbug.com/266
- Extensions could create UIs for setting non-system proxy settings
- Allow exposing advanced proxy customizations, without the need for extra Chromium-side UI.
- For example, exposing the equivalent of Firefox's network.proxy.socks_remote_dns option.
Could this API be part of the web platform?
No.
This is really a network-setup customization, and wouldn't make sense as part of the web platform.
Do you expect this API to be fairly stable?
Yes.
The basics of proxy settings are not changing any time soon.
New features will surely be added, but it will
be possible to maintain backwards-compatibility in the API (more on this later).
What UI does this API expose
One consequence of this API, is it requires addressing http://crbug.com/266 (which is blocked on an unwillingness to add a proxy settings UI).
At the very least, Chromium's options dialog will need to be changed to indicate if we are using the system proxy settings, or a custom set of proxy settings. This could be as simple as a radio button:
How could this API be abused
Being able to change the proxy settings should be a priviledge the extension needs to ask for, since it
has a number of security/privacy implications:
- [privacy] Extension can read your system proxy settings (which may reveal names of internal hosts).
- Currently, Chromium's proxy settings DOES NOT allow encoding identities (username/password) in the individual proxy servers selectsion... so extensions WOULD NOT be able to read username/passwords by virtue of being able to read the system proxy settings.
- [privacy / security]: An evil extension can send all of your network traffic through the attacker's own proxy server.
- Meaning they can see where you browse to, and substitute the contents of (non-encrypted) HTTP/FTP responses.
- [security] Can compromise the browser process by setting a PAC script that exploits V8.
- This attack is mitigated by http://crbug.com/11746 which moves PAC execution out of the browser process.
- We SHOULD wait until PAC runs out of process before letting extensions change it.
Are you willing and able to develop and maintain this API?
Yes
Persistence model
Custom proxy settings (set using chrome.proxy.useCustomProxySettings()), are persisted by the browser across restarts.
Draft API spec
chrome.proxy.
// Specifies a proxy server (and its protocol + options).
//
// We use a class rather than a simple spec string, to make it easier to
// extend this in the future in a backwards-compatible way (by introducing
// new optional properties).
//
// For example, we may want to add authentication fields
// as part
http://crbug.com/16709.
class ProxyServer {
// |scheme| is one of "http", "socks", "socks4", "socks5".
constructor(string scheme, string hostname, int port)
// Convenience constructors.
constructor(string spec)
constructor(string hostname, int port)
string scheme
string host
int port
}
// Specifies the value of a PAC script (either by URL, or by bytes).
// Only one of |url| or |data| should be given.
//
// Alternatively, we could have defined |url| as supporting "data:" format,
// but this is clumsy since caller needs to transform their PAC data.
struct PacScript {
string url;
string data;
}
// Specifies the manual (non-automatic) proxy settings.
// * per-url-scheme proxy servers.
// * bypass options.
// * SOCKS proxy server.
struct ProxyRules {
// Proxy server that applies to all URL schemes.
// (can be used in place of per-url scheme settings).
ProxyServer singleProxy;
// Per-url-scheme settings.
ProxyServer proxyForHttp;
ProxyServer proxyForHttps;
ProxyServer proxyForFtp;
ProxyServer socksProxy;
// True if "local" names should bypass the above proxy servers.
bool bypassLocal;
// List of patterns of URLs to bypass..
string[] bypassList;
}
struct ProxyConfig {
bool autoDetect;
PacScript pacScript;
ProxyRules rules;
}
// Used as the return type from getCurrentProxySettings().
struct ProxySettings {
bool isSystemSettings;
ProxyConfig config;
}
// Retrieves the current proxy settings.
//
// If Chromium is using a custom set of proxy settings,
// |isSystemSettings| will be false. Otherwise |isSystemSettings| will
// be true.
//
// In either case, |config| will be populated with the actual values.
//
// (If |isSystemSettings|, you can obtain the same value of |config|
// by calling getSystemProxySettings()).
void getCurrentProxySettings(void callback(ProxySettings))
// Retrieves the system's proxy settings.
void getSystemProxySettings(void callback(ProxyConfig))
// Sets |config| as the active proxy settings.
// The browser-side will silently handle any errors in |config|'s specification.
//
// Calling getCurrentProxySettings() immediately after this, will see the
// new proxy configuration.
void useCustomProxySettings(ProxyConfig config)
void useSystemProxySettings()
Example 1: Use a custom PAC script (by data) to blackhole "foobar.com"
var config = {
customPacScript: {
data:
"function FindProxyForURL(url, host) {\n" +
" if (host == 'foobar.com')\n" +
" return 'PROXY blackhole:80';\n" +
" return 'DIRECT';\n" +
"}"
}
};
chrome.proxy.useCustomProxySettings(config);
Example 2: Use a custom PAC script (by URL), in conjunction with auto detect
var config = {
autoDetect: true,
customPacScript: {
url: "http://i-am-is-the-awesome/bite-me.pac"
}
};
chrome.proxy.useCustomProxySettings(config);
Example 3: Use a tweaked version of the system proxy settings.
chrome.proxy.getSystemProxySettings(function(config) {
// Remove the bypass list and SOCKS proxy (if there is any).
if (config.rules) {
config.socksProxy = null;
config.rules.bypassList = null;
}
config.useCustomProxySettings(config);
});
Planning