@ -7,9 +7,60 @@ const childProcess = require("child_process");
const path = require ( "path" ) ;
const Database = require ( "../database" ) ;
const jwt = require ( "jsonwebtoken" ) ;
const config = require ( "../config" ) ;
let browser = null ;
let allowedList = [ ] ;
let lastAutoDetectChromeExecutable = null ;
if ( process . platform === "win32" ) {
allowedList . push ( process . env . LOCALAPPDATA + "\\Google\\Chrome\\Application\\chrome.exe" ) ;
allowedList . push ( process . env . PROGRAMFILES + "\\Google\\Chrome\\Application\\chrome.exe" ) ;
allowedList . push ( process . env [ "ProgramFiles(x86)" ] + "\\Google\\Chrome\\Application\\chrome.exe" ) ;
// Allow Chromium too
allowedList . push ( process . env . LOCALAPPDATA + "\\Chromium\\Application\\chrome.exe" ) ;
allowedList . push ( process . env . PROGRAMFILES + "\\Chromium\\Application\\chrome.exe" ) ;
allowedList . push ( process . env [ "ProgramFiles(x86)" ] + "\\Chromium\\Application\\chrome.exe" ) ;
// For Loop A to Z
for ( let i = 65 ; i <= 90 ; i ++ ) {
let drive = String . fromCharCode ( i ) ;
allowedList . push ( drive + ":\\Program Files\\Google\\Chrome\\Application\\chrome.exe" ) ;
allowedList . push ( drive + ":\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" ) ;
}
} else if ( process . platform === "linux" ) {
allowedList = [
"chromium" ,
"chromium-browser" ,
"google-chrome" ,
"/usr/bin/chromium" ,
"/usr/bin/chromium-browser" ,
"/usr/bin/google-chrome" ,
] ;
} else if ( process . platform === "darwin" ) {
// TODO: Generated by GitHub Copilot, but not sure if it's correct
allowedList = [
"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" ,
"/Applications/Chromium.app/Contents/MacOS/Chromium" ,
] ;
}
log . debug ( "chrome" , allowedList ) ;
async function isAllowedChromeExecutable ( executablePath ) {
console . log ( config . args ) ;
if ( config . args [ "allow-all-chrome-exec" ] || process . env . UPTIME _KUMA _ALLOW _ALL _CHROME _EXEC === "1" ) {
return true ;
}
// Check if the executablePath is in the list of allowed executables
return allowedList . includes ( executablePath ) ;
}
async function getBrowser ( ) {
if ( ! browser ) {
let executablePath = await Settings . get ( "chromeExecutable" ) ;
@ -27,6 +78,7 @@ async function getBrowser() {
async function prepareChromeExecutable ( executablePath ) {
// Special code for using the playwright_chromium
if ( typeof executablePath === "string" && executablePath . toLocaleLowerCase ( ) === "#playwright_chromium" ) {
// Set to undefined = use playwright_chromium
executablePath = undefined ;
} else if ( ! executablePath ) {
if ( process . env . UPTIME _KUMA _IS _CONTAINER ) {
@ -56,30 +108,30 @@ async function prepareChromeExecutable(executablePath) {
} ) ;
}
} else if ( process . platform === "win32" ) {
executablePath = findChrome ( [
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" ,
"C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" ,
"D:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" ,
"D:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" ,
"E:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" ,
"E:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe" ,
] ) ;
} else if ( process . platform === "linux" ) {
executablePath = findChrome ( [
"chromium-browser" ,
"chromium" ,
"google-chrome" ,
] ) ;
} else {
executablePath = findChrome ( allowedList ) ;
}
} else {
// User specified a path
// Check if the executablePath is in the list of allowed
if ( ! await isAllowedChromeExecutable ( executablePath ) ) {
throw new Error ( "This Chromium executable path is not allowed by default. If you are sure this is safe, please add an environment variable UPTIME_KUMA_ALLOW_ALL_CHROME_EXEC=1 to allow it." ) ;
}
// TODO: Mac??
}
return executablePath ;
}
function findChrome ( executables ) {
// Use the last working executable, so we don't have to search for it again
if ( lastAutoDetectChromeExecutable ) {
if ( commandExistsSync ( lastAutoDetectChromeExecutable ) ) {
return lastAutoDetectChromeExecutable ;
}
}
for ( let executable of executables ) {
if ( commandExistsSync ( executable ) ) {
lastAutoDetectChromeExecutable = executable ;
return executable ;
}
}