Integrate DNS over HTTPS (DoH) into the Chromium Embedded Framework (CEF) to encrypt DNS queries and prevent hijacking in embedded browser applications.
1. Introduction
The Chromium Embedded Framework (CEF) is an open-source framework based on Chromium, widely used in desktop applications that require embedded web browsing. In scenarios that handle sensitive data or require high security, traditional DNS resolution may not meet security requirements. DoH transmits DNS queries and responses over an encrypted HTTPS channel, effectively preventing man-in-the-middle attacks, DNS hijacking, and traffic sniffing. By integrating DoH into the CEF framework, developers can enhance the security and privacy of the embedded browser without changing existing application logic.
2. Prerequisites
Before you integrate DoH into the CEF framework, make sure that you have completed the steps in Configure the DoH service.
-
CEF uses the built-in probe domain name
google.comto check DoH availability. Before the probe is complete, DoH availability is considered undetermined. To ensure that the DoH service works correctly, make sure that you add thegoogle.comdomain name to the resolution list or allow resolution for all domain names. -
CEF version requirement: Version 115 or later is recommended (corresponding to Chromium 115+).
3. Integration steps
Integrating DoH into the CEF framework involves three core steps: configure an independent application-level cache path to avoid conflicts, use the Preferences API to set the DoH template and mode, and implement an automatic fallback mechanism for service stability.
3.1 Configure the CEF application cache path
You must configure an independent application-level cache path. If you use the default path, other CEF applications might contaminate your cache, causing the DoH configuration to fail or be overwritten.
When you initialize CEF, set the cache path by using the CefSettings object. Make sure that the application has permission to access this path. The following code provides an example:
void ConfigureCachePath(CefSettings& settings) {
// Set the root cache path
std::string cache_path;
#if defined(OS_MAC)
cache_path = std::string("/Users/") + getenv("USER") + "/Library/Application Support/YourAppName/cache";
#elif defined(OS_WIN)
cache_path = std::string(getenv("LOCALAPPDATA")) + "\\YourAppName\\cache";
#else
cache_path = std::string(getenv("HOME")) + "/.cache/YourAppName";
#endif
CefString(&settings.root_cache_path) = cache_path;
CefString(&settings.cache_path) = cache_path;
}
// Use in the main function
int main(int argc, char* argv[]) {
CefSettings settings;
// Other parameter configurations
// ...
ConfigureCachePath(settings);
// Initialize CEF
CefInitialize(main_args, settings, app.get(), nullptr);
// ...
}
3.2 Configure DoH using Preferences
Use CefPreferenceManager to configure DoH. The following code provides an example:
void UpdateDnsOverHttpsTemplate(const std::string& new_template) {
// Get the global CefPreferenceManager instance
CefRefPtr<CefPreferenceManager> pref_manager =
CefPreferenceManager::GetGlobalPreferenceManager();
// Set the DoH template
CefRefPtr<CefValue> template_value = CefValue::Create();
template_value->SetString(new_template);
// Set the DoH mode to "secure"
CefRefPtr<CefValue> mode_value = CefValue::Create();
mode_value->SetString("secure");
// Apply the settings
CefString error;
pref_manager->SetPreference("dns_over_https.mode", mode_value, error);
pref_manager->SetPreference("dns_over_https.templates", template_value, error);
}
// Call during application initialization
void OnContextInitialized(CefRefPtr<ClientAppBrowser> app) override {
// Replace this with your own dedicated DoH endpoint
UpdateDnsOverHttpsTemplate("https://1xxxx3.aliyunhttpdns.com/dns-query");
}
3.3 Implement an automatic fallback mechanism
CEF supports the following DoH modes:
-
secure: Forces the use of DoH. Fallback to standard DNS is not allowed. -
automatic: Automatic mode. Allows fallback to standard DNS if DoH fails. -
off: Disables DoH.
To improve availability, you can implement an automatic fallback mechanism that switches to local DNS if DoH resolution fails. The following code provides an example:
void ClientHandler::OnLoadError(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
ErrorCode errorCode,
const CefString& errorText,
const CefString& failedUrl) {
// Check for DNS-related errors
if (errorCode == ERR_NAME_NOT_RESOLVED ||
errorCode == ERR_NAME_RESOLUTION_FAILED) {
LOG(ERROR) << "DNS resolution failed for URL: " << failedUrl.ToString()
<< ". Error code: " << errorCode
<< ". Switching to Local DNS...";
// Get the global preference manager
CefRefPtr<CefPreferenceManager> pref_manager =
CefPreferenceManager::GetGlobalPreferenceManager();
// Switch to automatic mode to allow the use of local DNS
CefRefPtr<CefValue> new_mode = CefValue::Create();
new_mode->SetString("automatic");
CefString error;
if (pref_manager->SetPreference("dns_over_https.mode", new_mode, error)) {
// Retry loading the failed page
frame->LoadURL(failedUrl);
return;
}
}
// Handle other errors...
}
4. Summary
After you complete the preceding steps, DoH is integrated into the CEF framework. You can verify the integration by capturing network packets to view HTTPS requests, checking DNS logs, or performing network fault tests. For stability in production environments, use the automatic mode and configure multiple DoH servers.