-
-
Notifications
You must be signed in to change notification settings - Fork 289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
v4.2 Development Branch #523
Conversation
Merge main into bsd support
Merging latest v4.1.1 changes into v4.2.0 branch
Replace `ifcfg` with socket to get default interface address
Fixing `auth_req` is not working
- Disabled `EmailSender` for now
- Fixed message blocking element behind - Adjusted message UI - Allow to dismiss, will not dismiss when mouse hover on it
@return: Boolean indicate if the text match the regex pattern | ||
""" | ||
pattern = re.compile(regex) | ||
return pattern.search(text) is not None |
Check failure
Code scanning / CodeQL
Polynomial regular expression used on uncontrolled data High
regular expression
user-provided value
This
regular expression
user-provided value
self.__createDatabase() | ||
with open(self.__configPath, "w+") as configFile: | ||
self.createDatabase() | ||
with open(self.configPath, "w+") as configFile: |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to validate the user-provided ConfigurationName
before using it to construct the file path. We can use os.path.normpath
to normalize the path and ensure it is within a safe directory. Additionally, we can use werkzeug.utils.secure_filename
to sanitize the filename.
- Import
secure_filename
fromwerkzeug.utils
. - Normalize the constructed path using
os.path.normpath
. - Ensure the normalized path starts with the intended base directory.
-
Copy modified line R2 -
Copy modified lines R475-R479 -
Copy modified lines R496-R500
@@ -1,2 +1,3 @@ | ||
import itertools, random, shutil, sqlite3, configparser, hashlib, ipaddress, json, traceback, os, secrets, subprocess | ||
from werkzeug.utils import secure_filename | ||
import smtplib | ||
@@ -473,3 +474,7 @@ | ||
self.Protocol = "wg" if wg else "awg" | ||
self.configPath = os.path.join(self.__getProtocolPath(), f'{self.Name}.conf') if wg else os.path.join(DashboardConfig.GetConfig("Server", "awg_conf_path")[1], f'{self.Name}.conf') | ||
safe_name = secure_filename(self.Name) | ||
base_path = self.__getProtocolPath() if wg else DashboardConfig.GetConfig("Server", "awg_conf_path")[1] | ||
self.configPath = os.path.normpath(os.path.join(base_path, f'{safe_name}.conf')) | ||
if not self.configPath.startswith(base_path): | ||
raise ValueError("Invalid configuration name resulting in path traversal") | ||
|
||
@@ -490,3 +495,7 @@ | ||
self.Name = data["ConfigurationName"] | ||
self.configPath = os.path.join(self.__getProtocolPath(), f'{self.Name}.conf') | ||
safe_name = secure_filename(self.Name) | ||
base_path = self.__getProtocolPath() | ||
self.configPath = os.path.normpath(os.path.join(base_path, f'{safe_name}.conf')) | ||
if not self.configPath.startswith(base_path): | ||
raise ValueError("Invalid configuration name resulting in path traversal") | ||
|
if self.PrivateKey: | ||
self.PublicKey = self.__getPublicKey() | ||
self.Status = self.getStatus() | ||
with open(self.configPath, 'r') as f: |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to ensure that the constructed file path is contained within a safe root folder. We can achieve this by normalizing the path using os.path.normpath
and then checking that the normalized path starts with the root folder. This will prevent any path traversal attacks.
- Normalize the
configPath
usingos.path.normpath
. - Check that the normalized path starts with the expected root directory.
- Raise an exception if the path is not within the expected directory.
-
Copy modified lines R474-R477 -
Copy modified lines R494-R497
@@ -473,3 +473,6 @@ | ||
self.Protocol = "wg" if wg else "awg" | ||
self.configPath = os.path.join(self.__getProtocolPath(), f'{self.Name}.conf') if wg else os.path.join(DashboardConfig.GetConfig("Server", "awg_conf_path")[1], f'{self.Name}.conf') | ||
base_path = self.__getProtocolPath() if wg else DashboardConfig.GetConfig("Server", "awg_conf_path")[1] | ||
self.configPath = os.path.normpath(os.path.join(base_path, f'{self.Name}.conf')) | ||
if not self.configPath.startswith(base_path): | ||
raise ValueError("Invalid configuration path") | ||
|
||
@@ -490,3 +493,6 @@ | ||
self.Name = data["ConfigurationName"] | ||
self.configPath = os.path.join(self.__getProtocolPath(), f'{self.Name}.conf') | ||
base_path = self.__getProtocolPath() | ||
self.configPath = os.path.normpath(os.path.join(base_path, f'{self.Name}.conf')) | ||
if not self.configPath.startswith(base_path): | ||
raise ValueError("Invalid configuration path") | ||
|
self.RestrictedPeers = [] | ||
restricted = sqlSelect("SELECT * FROM '%s_restrict_access'" % self.Name).fetchall() | ||
for i in restricted: | ||
self.RestrictedPeers.append(Peer(i, self)) | ||
|
||
def configurationFileChanged(self) : | ||
mt = os.path.getmtime(os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], f'{self.Name}.conf')) | ||
mt = os.path.getmtime(self.configPath) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to ensure that the constructed file path is safe and does not allow path traversal attacks. We can achieve this by normalizing the path and ensuring it is contained within a predefined safe directory. We will use os.path.normpath
to normalize the path and then check if the resulting path starts with the expected base directory.
- Normalize the
configPath
usingos.path.normpath
. - Ensure the normalized path starts with the base directory.
- Raise an exception if the path is not within the expected directory.
-
Copy modified lines R474-R477 -
Copy modified lines R494-R497
@@ -473,3 +473,6 @@ | ||
self.Protocol = "wg" if wg else "awg" | ||
self.configPath = os.path.join(self.__getProtocolPath(), f'{self.Name}.conf') if wg else os.path.join(DashboardConfig.GetConfig("Server", "awg_conf_path")[1], f'{self.Name}.conf') | ||
base_path = self.__getProtocolPath() if wg else DashboardConfig.GetConfig("Server", "awg_conf_path")[1] | ||
self.configPath = os.path.normpath(os.path.join(base_path, f'{self.Name}.conf')) | ||
if not self.configPath.startswith(base_path): | ||
raise Exception("Invalid configuration path") | ||
|
||
@@ -490,3 +493,6 @@ | ||
self.Name = data["ConfigurationName"] | ||
self.configPath = os.path.join(self.__getProtocolPath(), f'{self.Name}.conf') | ||
base_path = self.__getProtocolPath() | ||
self.configPath = os.path.normpath(os.path.join(base_path, f'{self.Name}.conf')) | ||
if not self.configPath.startswith(base_path): | ||
raise Exception("Invalid configuration path") | ||
|
if self.configurationFileChanged(): | ||
self.Peers = [] | ||
with open(os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], f'{self.Name}.conf'), 'r') as configFile: | ||
with open(self.configPath, 'r') as configFile: |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to validate the user-provided file path to ensure it does not lead to path traversal attacks. We can achieve this by normalizing the path and ensuring it is contained within a safe root directory. This involves the following steps:
- Normalize the path using
os.path.normpath
. - Check that the normalized path starts with the expected base directory.
- Raise an exception or return an error response if the path is invalid.
-
Copy modified lines R491-R494
@@ -490,3 +490,6 @@ | ||
self.Name = data["ConfigurationName"] | ||
self.configPath = os.path.join(self.__getProtocolPath(), f'{self.Name}.conf') | ||
base_path = self.__getProtocolPath() | ||
self.configPath = os.path.normpath(os.path.join(base_path, f'{self.Name}.conf')) | ||
if not self.configPath.startswith(base_path): | ||
raise ValueError("Invalid configuration name resulting in path traversal") | ||
|
} | ||
|
||
if (os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"])) and | ||
os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to validate and sanitize the user-provided data["Backup"]
value before using it to construct file paths. We can use os.path.normpath
to normalize the path and ensure it does not contain any path traversal sequences. Additionally, we should check that the resulting path is within the intended backup directory.
- Normalize the
data["Backup"]
value usingos.path.normpath
. - Ensure the normalized path is within the
WGDashboard_Backup
directory. - Update the file path construction to use the validated and sanitized path.
-
Copy modified lines R2223-R2231 -
Copy modified lines R2233-R2234 -
Copy modified line R2240
@@ -2222,8 +2222,14 @@ | ||
} | ||
|
||
if (os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"])) and | ||
os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): | ||
|
||
backup_file = os.path.normpath(data["Backup"]) | ||
backup_sql_file = os.path.normpath(data["Backup"].replace('.conf', '.sql')) | ||
|
||
wg_backup_path = os.path.join(path['wg'], 'WGDashboard_Backup') | ||
awg_backup_path = os.path.join(path['awg'], 'WGDashboard_Backup') | ||
|
||
if (backup_file.startswith(wg_backup_path) and os.path.exists(os.path.join(wg_backup_path, backup_file)) and | ||
os.path.exists(os.path.join(wg_backup_path, backup_sql_file))): | ||
protocol = "wg" | ||
elif (os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"])) and | ||
os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): | ||
elif (backup_file.startswith(awg_backup_path) and os.path.exists(os.path.join(awg_backup_path, backup_file)) and | ||
os.path.exists(os.path.join(awg_backup_path, backup_sql_file))): | ||
protocol = "awg" | ||
@@ -2233,3 +2239,3 @@ | ||
shutil.copy( | ||
os.path.join(path[protocol], 'WGDashboard_Backup', data["Backup"]), | ||
os.path.join(path[protocol], 'WGDashboard_Backup', backup_file), | ||
os.path.join(path[protocol], f'{data["ConfigurationName"]}.conf') |
if (os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"])) and | ||
os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): | ||
protocol = "wg" | ||
elif (os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"])) and |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to validate and sanitize the user-provided Backup
value before using it in the os.path.join
function. We can use the os.path.normpath
function to normalize the path and ensure it does not contain any directory traversal sequences. Additionally, we should check that the resulting path is within the intended directory.
- Normalize the
Backup
value usingos.path.normpath
. - Ensure the normalized path is within the
WGDashboard_Backup
directory. - Update the code to use the validated and sanitized path.
-
Copy modified lines R2224-R2230 -
Copy modified lines R2232-R2233 -
Copy modified line R2239
@@ -2223,7 +2223,12 @@ | ||
|
||
if (os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"])) and | ||
os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): | ||
backup_path_wg = os.path.normpath(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"])) | ||
backup_path_wg_sql = os.path.normpath(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql'))) | ||
backup_path_awg = os.path.normpath(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"])) | ||
backup_path_awg_sql = os.path.normpath(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql'))) | ||
|
||
if (backup_path_wg.startswith(os.path.join(path['wg'], 'WGDashboard_Backup')) and os.path.exists(backup_path_wg) and | ||
backup_path_wg_sql.startswith(os.path.join(path['wg'], 'WGDashboard_Backup')) and os.path.exists(backup_path_wg_sql)): | ||
protocol = "wg" | ||
elif (os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"])) and | ||
os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): | ||
elif (backup_path_awg.startswith(os.path.join(path['awg'], 'WGDashboard_Backup')) and os.path.exists(backup_path_awg) and | ||
backup_path_awg_sql.startswith(os.path.join(path['awg'], 'WGDashboard_Backup')) and os.path.exists(backup_path_awg_sql)): | ||
protocol = "awg" | ||
@@ -2233,3 +2238,3 @@ | ||
shutil.copy( | ||
os.path.join(path[protocol], 'WGDashboard_Backup', data["Backup"]), | ||
backup_path_wg if protocol == "wg" else backup_path_awg, | ||
os.path.join(path[protocol], f'{data["ConfigurationName"]}.conf') |
os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): | ||
protocol = "wg" | ||
elif (os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"])) and | ||
os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to validate and sanitize the user-provided data["Backup"]
value before using it in file path operations. We can use os.path.normpath
to normalize the path and ensure it does not contain any directory traversal sequences. Additionally, we can check that the resulting path is within a predefined safe directory.
- Normalize the
data["Backup"]
value usingos.path.normpath
. - Ensure the normalized path is within the
WGDashboard_Backup
directory. - Use the sanitized path for file operations.
-
Copy modified lines R2224-R2231 -
Copy modified lines R2233-R2235
@@ -2223,7 +2223,14 @@ | ||
|
||
if (os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"])) and | ||
os.path.exists(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): | ||
backup_path_wg = os.path.normpath(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"])) | ||
backup_sql_path_wg = os.path.normpath(os.path.join(path['wg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql'))) | ||
backup_path_awg = os.path.normpath(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"])) | ||
backup_sql_path_awg = os.path.normpath(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql'))) | ||
|
||
if (backup_path_wg.startswith(os.path.join(path['wg'], 'WGDashboard_Backup')) and | ||
backup_sql_path_wg.startswith(os.path.join(path['wg'], 'WGDashboard_Backup')) and | ||
os.path.exists(backup_path_wg) and os.path.exists(backup_sql_path_wg)): | ||
protocol = "wg" | ||
elif (os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"])) and | ||
os.path.exists(os.path.join(path['awg'], 'WGDashboard_Backup', data["Backup"].replace('.conf', '.sql')))): | ||
elif (backup_path_awg.startswith(os.path.join(path['awg'], 'WGDashboard_Backup')) and | ||
backup_sql_path_awg.startswith(os.path.join(path['awg'], 'WGDashboard_Backup')) and | ||
os.path.exists(backup_path_awg) and os.path.exists(backup_sql_path_awg)): | ||
protocol = "awg" |
|
||
shutil.copy( | ||
os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], 'WGDashboard_Backup', data["Backup"]), | ||
os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], f'{data["ConfigurationName"]}.conf') | ||
os.path.join(path[protocol], 'WGDashboard_Backup', data["Backup"]), |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to ensure that the user-provided Backup
value is validated and sanitized before being used in file path operations. We can achieve this by normalizing the path and ensuring it is contained within a safe root directory. This will prevent directory traversal attacks and ensure that only intended files are accessed.
- Normalize the
Backup
path usingos.path.normpath
. - Ensure the normalized path starts with the intended root directory.
- Raise an exception or return an error response if the validation fails.
-
Copy modified lines R2233-R2235 -
Copy modified line R2237
@@ -2232,4 +2232,7 @@ | ||
|
||
backup_path = os.path.normpath(os.path.join(path[protocol], 'WGDashboard_Backup', data["Backup"])) | ||
if not backup_path.startswith(os.path.join(path[protocol], 'WGDashboard_Backup')): | ||
return ResponseObject(False, "Invalid backup path") | ||
shutil.copy( | ||
os.path.join(path[protocol], 'WGDashboard_Backup', data["Backup"]), | ||
backup_path, | ||
os.path.join(path[protocol], f'{data["ConfigurationName"]}.conf') |
os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], 'WGDashboard_Backup', data["Backup"]), | ||
os.path.join(DashboardConfig.GetConfig("Server", "wg_conf_path")[1], f'{data["ConfigurationName"]}.conf') | ||
os.path.join(path[protocol], 'WGDashboard_Backup', data["Backup"]), | ||
os.path.join(path[protocol], f'{data["ConfigurationName"]}.conf') |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to ensure that the ConfigurationName
provided by the user does not contain any malicious input that could lead to path traversal attacks. We can achieve this by normalizing the path and ensuring it stays within a predefined safe directory. Additionally, we can use a library function like werkzeug.utils.secure_filename
to sanitize the filename.
- Import the
secure_filename
function fromwerkzeug.utils
. - Use
secure_filename
to sanitize theConfigurationName
before using it in the file path. - Normalize the path and ensure it stays within the intended directory.
-
Copy modified line R2 -
Copy modified lines R2234-R2239
@@ -1,2 +1,3 @@ | ||
import itertools, random, shutil, sqlite3, configparser, hashlib, ipaddress, json, traceback, os, secrets, subprocess | ||
from werkzeug.utils import secure_filename | ||
import smtplib | ||
@@ -2232,6 +2233,8 @@ | ||
|
||
shutil.copy( | ||
os.path.join(path[protocol], 'WGDashboard_Backup', data["Backup"]), | ||
os.path.join(path[protocol], f'{data["ConfigurationName"]}.conf') | ||
) | ||
safe_configuration_name = secure_filename(data["ConfigurationName"]) | ||
backup_path = os.path.join(path[protocol], 'WGDashboard_Backup', data["Backup"]) | ||
config_path = os.path.join(path[protocol], f'{safe_configuration_name}.conf') | ||
if not os.path.commonpath([config_path, path[protocol]]) == path[protocol]: | ||
return ResponseObject(False, "Invalid configuration name.") | ||
shutil.copy(backup_path, config_path) | ||
WireguardConfigurations[data['ConfigurationName']] = WireguardConfiguration(data=data, name=data['ConfigurationName']) if protocol == 'wg' else AmneziaWireguardConfiguration(data=data, name=data['ConfigurationName']) |
- Used IntersectionObserver to better render peer list, in case of too many peers will slow down browser
file = request.args.get('file') | ||
if file is None or len(file) == 0: | ||
return ResponseObject(False, "Please specify a file") | ||
if os.path.exists(os.path.join('download', file)): |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to validate the file
parameter to ensure it does not contain any malicious input that could lead to path traversal attacks. The best way to do this is to normalize the path and ensure it is contained within the intended directory. We can use os.path.normpath
to remove any ..
segments and then check that the resulting path starts with the intended directory.
-
Copy modified lines R2802-R2807
@@ -2801,4 +2801,8 @@ | ||
return ResponseObject(False, "Please specify a file") | ||
if os.path.exists(os.path.join('download', file)): | ||
return send_file(os.path.join('download', file), as_attachment=True) | ||
safe_base_path = os.path.abspath('download') | ||
full_path = os.path.abspath(os.path.join(safe_base_path, file)) | ||
if not full_path.startswith(safe_base_path): | ||
return ResponseObject(False, "Invalid file path") | ||
if os.path.exists(full_path): | ||
return send_file(full_path, as_attachment=True) | ||
else: |
if file is None or len(file) == 0: | ||
return ResponseObject(False, "Please specify a file") | ||
if os.path.exists(os.path.join('download', file)): | ||
return send_file(os.path.join('download', file), as_attachment=True) |
Check failure
Code scanning / CodeQL
Uncontrolled data used in path expression High
user-provided value
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix AI about 2 months ago
To fix the problem, we need to ensure that the file path constructed from user input is safe and does not allow access to files outside the intended directory. We can achieve this by normalizing the path and ensuring it starts with the intended base directory.
- Normalize the path using
os.path.normpath
to remove any ".." segments. - Check that the normalized path starts with the 'download' directory.
-
Copy modified lines R2802-R2807
@@ -2801,4 +2801,8 @@ | ||
return ResponseObject(False, "Please specify a file") | ||
if os.path.exists(os.path.join('download', file)): | ||
return send_file(os.path.join('download', file), as_attachment=True) | ||
base_path = os.path.abspath('download') | ||
full_path = os.path.normpath(os.path.join(base_path, file)) | ||
if not full_path.startswith(base_path): | ||
return ResponseObject(False, "Invalid file path") | ||
if os.path.exists(full_path): | ||
return send_file(full_path, as_attachment=True) | ||
else: |
No description provided.