Security Issues: Unintended application execution
package main
import "github.com/toqueteos/webbrowser"
func main() {
webbrowser.Open("file:///C:/Users/{name}/Desktop/calc.exe")
}
On Windows, if you use a command like start file://a.exe, it is treated the same as start a.exe. Therefore, this can be exploited to execute malicious programs. To avoid this risk, you should structure the command as start [browser path] [URL] to ensure it launches the browser safely.
Valid concern but this library doesn't know:
- Which browser(s) does the user have installed
- Which is their default browser
The best I can do is:
- Add a note to the README stating that this is possible
- Add a new
webbrowser.Openvariant that checks URL scheme and maybe file extension if any?
Anything else is way out of scope of this library.
import winreg
import shlex
import os
def get_default_browser_exe_path_windows():
try:
user_choice_path = r"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice"
with winreg.OpenKey(winreg.HKEY_CURRENT_USER, user_choice_path) as key:
prog_id, _ = winreg.QueryValueEx(key, "ProgId")
command_path = fr"{prog_id}\shell\open\command"
with winreg.OpenKey(winreg.HKEY_CLASSES_ROOT, command_path) as key:
command, _ = winreg.QueryValueEx(key, None)
parts = shlex.split(command)
exe_path = parts[0]
exe_path = exe_path.strip('"')
if not os.path.exists(exe_path):
return f"Executable not found: {exe_path}"
return exe_path
except Exception as e:
return f"Error: {e}"
if __name__ == "__main__":
print(get_default_browser_exe_path_windows())
by python
package main
import (
"fmt"
"golang.org/x/sys/windows/registry"
"log"
"strings"
)
func getDefaultBrowserPath() (string, error) {
userChoiceKey, err := registry.OpenKey(registry.CURRENT_USER,
`Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice`,
registry.QUERY_VALUE)
if err != nil {
return "", err
}
defer userChoiceKey.Close()
progId, _, err := userChoiceKey.GetStringValue("ProgId")
if err != nil {
return "", err
}
commandKey, err := registry.OpenKey(registry.CLASSES_ROOT,
fmt.Sprintf(`%s\shell\open\command`, progId),
registry.QUERY_VALUE)
if err != nil {
return "", err
}
defer commandKey.Close()
command, _, err := commandKey.GetStringValue("")
if err != nil {
return "", err
}
command = strings.TrimSpace(command)
if strings.HasPrefix(command, "\"") {
endIndex := strings.Index(command[1:], "\"") + 1
if endIndex > 0 {
return command[1:endIndex], nil
}
}
parts := strings.SplitN(command, " ", 2)
return parts[0], nil
}
func main() {
path, err := getDefaultBrowserPath()
if err != nil {
log.Fatal(err)
}
fmt.Println(path)
}
by go
Although I'm not very familiar with Go, I found an example for retrieving the default browser path, and it seems like this should work. Would adding such a feature also be out of scope?
Sorry, forgot about this. I just published v1.2.1 adding the note to Open.