diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 78abe9ed6..15d870b10 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -663,13 +663,22 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if the provided URL is safe -// A user could craft a malicious string performing another action -// Avoid calling this function with user input non-validated strings +// WARNING: This function is only safe to use if you control the URL given, +// a user could craft a malicious string to perform and undesired action +// NOTE: Some safety checks have been added to mitigate security issues void OpenURL(const char *url) { // Security check to (partially) avoid malicious code - if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); + if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL)) + { + // Filter characters: ' and " + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters"); + } + else if ((strncmp(url, "http://", 7) != 0) && (strncmp(protocol, "https://", 8) != 0)) + { + // Only allow URL starting with "http://" or "https://" protocols + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols"); + } else { JNIEnv *env = NULL; diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index b0bdf70f3..88e02993a 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1181,17 +1181,25 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if you control the URL given -// A user could craft a malicious string performing another action -// Only call this function yourself not with user input or make sure to check the string yourself -// REF: https://github.com/raysan5/raylib/issues/686 +// WARNING: This function is only safe to use if you control the URL given, +// a user could craft a malicious string to perform and undesired action +// NOTE: Some safety checks have been added to mitigate security issues void OpenURL(const char *url) { // Security check to (partially) avoid malicious code - if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); - else + if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL)) { - char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char)); + // Filter characters: ' and " + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters"); + } + else if ((strncmp(url, "http://", 7) != 0) && (strncmp(protocol, "https://", 8) != 0)) + { + // Only allow URL starting with "http://" or "https://" protocols + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols"); + } + else + { + char *cmd = (char *)RL_CALLOC(strlen(url) + 16, sizeof(char)); #if defined(_WIN32) sprintf(cmd, "explorer \"%s\"", url); #endif @@ -1201,7 +1209,9 @@ void OpenURL(const char *url) #if defined(__APPLE__) sprintf(cmd, "open '%s'", url); #endif + // TODO: Replace system() call by custom process int result = system(cmd); + if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created"); RL_FREE(cmd); } diff --git a/src/platforms/rcore_desktop_rgfw.c b/src/platforms/rcore_desktop_rgfw.c index 2e973108b..1c1797c48 100644 --- a/src/platforms/rcore_desktop_rgfw.c +++ b/src/platforms/rcore_desktop_rgfw.c @@ -1471,15 +1471,25 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if you control the URL given -// A user could craft a malicious string performing another action +// WARNING: This function is only safe to use if you control the URL given, +// a user could craft a malicious string to perform and undesired action +// NOTE: Some safety checks have been added to mitigate security issues void OpenURL(const char *url) { - // Security check to (partially) avoid malicious code on target platform - if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); - else + // Security check to (partially) avoid malicious code + if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL)) { - char *cmd = (char *)RL_CALLOC(strlen(url) + 32, sizeof(char)); + // Filter characters: ' and " + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters"); + } + else if ((strncmp(url, "http://", 7) != 0) && (strncmp(protocol, "https://", 8) != 0)) + { + // Only allow URL starting with "http://" or "https://" protocols + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols"); + } + else + { + char *cmd = (char *)RL_CALLOC(strlen(url) + 16, sizeof(char)); #if defined(_WIN32) sprintf(cmd, "explorer \"%s\"", url); #endif diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 130d0c184..378f9892b 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -1341,14 +1341,22 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if the provided URL is safe -// A user could craft a malicious string performing another action -// Avoid calling this function with user input non-validated strings -// REF: https://github.com/raysan5/raylib/issues/686 +// WARNING: This function is only safe to use if you control the URL given, +// a user could craft a malicious string to perform and undesired action +// NOTE: Some safety checks have been added to mitigate security issues void OpenURL(const char *url) { // Security check to (partially) avoid malicious code - if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); + if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL)) + { + // Filter characters: ' and " + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters"); + } + else if ((strncmp(url, "http://", 7) != 0) && (strncmp(protocol, "https://", 8) != 0)) + { + // Only allow URL starting with "http://" or "https://" protocols + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols"); + } else SDL_OpenURL(url); } diff --git a/src/platforms/rcore_desktop_win32.c b/src/platforms/rcore_desktop_win32.c index 35347023d..efe1cb42d 100644 --- a/src/platforms/rcore_desktop_win32.c +++ b/src/platforms/rcore_desktop_win32.c @@ -1247,19 +1247,28 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if the provided URL is safe -// A user could craft a malicious string performing another action -// Avoid calling this function with user input non-validated strings -// REF: https://github.com/raysan5/raylib/issues/686 +// WARNING: This function is only safe to use if you control the URL given, +// a user could craft a malicious string to perform and undesired action +// NOTE: Some safety checks have been added to mitigate security issues void OpenURL(const char *url) { - // Security check to (partially) avoid malicious code on target platform - if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); - else + // Security check to (partially) avoid malicious code + if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL)) { - int len = strlen(url) + 32; + // Filter characters: ' and " + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters"); + } + else if ((strncmp(url, "http://", 7) != 0) && (strncmp(protocol, "https://", 8) != 0)) + { + // Only allow URL starting with "http://" or "https://" protocols + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols"); + } + else + { + int len = strlen(url) + 16; char *cmd = (char *)RL_CALLOC(len, sizeof(char)); snprintf(cmd, len, "explorer \"%s\"", url); + int result = system(cmd); if (result == -1) TRACELOG(LOG_WARNING, "OpenURL() child process could not be created"); RL_FREE(cmd); diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 659c80011..5f04a6612 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -1014,9 +1014,8 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if the provided URL is safe -// A user could craft a malicious string performing another action -// Avoid calling this function with user input non-validated strings +// WARNING: This function is only safe to use if you control the URL given, +// a user could craft a malicious string to perform and undesired action void OpenURL(const char *url) { TRACELOG(LOG_WARNING, "OpenURL() not implemented on target platform"); diff --git a/src/platforms/rcore_template.c b/src/platforms/rcore_template.c index 353d32d11..24fd1ecab 100644 --- a/src/platforms/rcore_template.c +++ b/src/platforms/rcore_template.c @@ -352,14 +352,22 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if you control the URL given. -// A user could craft a malicious string performing another action. -// Only call this function yourself not with user input or make sure to check the string yourself. -// Ref: https://github.com/raysan5/raylib/issues/686 +// WARNING: This function is only safe to use if you control the URL given, +// a user could craft a malicious string to perform and undesired action +// NOTE: Some safety checks have been added to mitigate security issues void OpenURL(const char *url) { - // Security check to (partially) avoid malicious code on target platform - if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); + // Security check to (partially) avoid malicious code + if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL)) + { + // Filter characters: ' and " + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters"); + } + else if ((strncmp(url, "http://", 7) != 0) && (strncmp(protocol, "https://", 8) != 0)) + { + // Only allow URL starting with "http://" or "https://" protocols + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols"); + } else { // TODO: Load url using default browser diff --git a/src/platforms/rcore_web_emscripten.c b/src/platforms/rcore_web_emscripten.c index 28f26f861..a7052c206 100644 --- a/src/platforms/rcore_web_emscripten.c +++ b/src/platforms/rcore_web_emscripten.c @@ -968,13 +968,22 @@ double GetTime(void) } // Open URL with default system browser (if available) -// NOTE: This function is only safe to use if the provided URL is safe -// A user could craft a malicious string performing another action -// Avoid calling this function with user input non-validated strings +// WARNING: This function is only safe to use if you control the URL given, +// a user could craft a malicious string to perform and undesired action +// NOTE: Some safety checks have been added to mitigate security issues void OpenURL(const char *url) { - // Security check to (partially) avoid malicious code on target platform - if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); + // Security check to (partially) avoid malicious code + if ((strchr(url, '\'') != NULL) || (strchr(url, '\"') != NULL)) + { + // Filter characters: ' and " + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'\"] characters"); + } + else if ((strncmp(url, "http://", 7) != 0) && (strncmp(protocol, "https://", 8) != 0)) + { + // Only allow URL starting with "http://" or "https://" protocols + TRACELOG(LOG_WARNING, "SYSTEM: Provided URL must start with 'http://' or 'https://' protocols"); + } else emscripten_run_script(TextFormat("window.open('%s', '_blank')", url)); } diff --git a/src/rcore.c b/src/rcore.c index d84d58b8b..00eca6eb1 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -1844,8 +1844,6 @@ void SetConfigFlags(unsigned int flags) FLAG_SET(CORE.Window.flags, flags); } -// void OpenURL(const char *url); // Defined per platform - //---------------------------------------------------------------------------------- // Module Functions Definition: Logging system //----------------------------------------------------------------------------------