mirror of
https://github.com/naruxde/revpipyload.git
synced 2026-07-02 01:37:04 +02:00
fix: Ensure file operations are restricted to PLC working directory
- Added checks to validate if file paths reside within the PLC working directory. - Logs a warning and prevents operations when paths fall outside the permissible directory. Signed-off-by: Sven Sager <akira@narux.de> Signed-off-by: Sven Sager <s.sager@kunbus.com>
This commit is contained in:
@@ -1064,11 +1064,19 @@ class RevPiPyLoad:
|
|||||||
:param file_name: File with full path relative to work directory
|
:param file_name: File with full path relative to work directory
|
||||||
:return: True on success
|
:return: True on success
|
||||||
"""
|
"""
|
||||||
file_name = os.path.join(self.plcworkdir, file_name)
|
plcworkdir = os.path.realpath(self.plcworkdir)
|
||||||
if os.path.exists(file_name):
|
file_path = os.path.realpath(os.path.join(plcworkdir, file_name))
|
||||||
os.remove(file_name)
|
|
||||||
dirname = os.path.dirname(file_name)
|
if os.path.commonpath([plcworkdir, file_path]) != plcworkdir:
|
||||||
if dirname != self.plcworkdir:
|
proginit.logger.warning(
|
||||||
|
"file path is not in plc working directory"
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
if os.path.exists(file_path):
|
||||||
|
os.remove(file_path)
|
||||||
|
dirname = os.path.dirname(file_path)
|
||||||
|
if dirname != plcworkdir:
|
||||||
try:
|
try:
|
||||||
# Try to remove directory, which will work if it is empty
|
# Try to remove directory, which will work if it is empty
|
||||||
os.rmdir(dirname)
|
os.rmdir(dirname)
|
||||||
@@ -1104,9 +1112,17 @@ class RevPiPyLoad:
|
|||||||
:param file_name: File with full path relative to work directory
|
:param file_name: File with full path relative to work directory
|
||||||
:return: Binary object in gzip format
|
:return: Binary object in gzip format
|
||||||
"""
|
"""
|
||||||
file_name = os.path.join(self.plcworkdir, file_name)
|
plcworkdir = os.path.realpath(self.plcworkdir)
|
||||||
if os.path.exists(file_name):
|
file_path = os.path.realpath(os.path.join(plcworkdir, file_name))
|
||||||
with open(file_name, "rb") as fh:
|
|
||||||
|
if os.path.commonpath([plcworkdir, file_path]) != plcworkdir:
|
||||||
|
proginit.logger.warning(
|
||||||
|
"file path is not in plc working directory"
|
||||||
|
)
|
||||||
|
return Binary()
|
||||||
|
|
||||||
|
if os.path.exists(file_path):
|
||||||
|
with open(file_path, "rb") as fh:
|
||||||
xmldata = Binary(gzip.compress(fh.read()))
|
xmldata = Binary(gzip.compress(fh.read()))
|
||||||
return xmldata
|
return xmldata
|
||||||
return Binary()
|
return Binary()
|
||||||
@@ -1169,7 +1185,7 @@ class RevPiPyLoad:
|
|||||||
else:
|
else:
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
def xml_plcupload(self, filedata, filename):
|
def xml_plcupload(self, filedata: Binary, filename:str):
|
||||||
"""Empfaengt Dateien fuer das PLC Programm einzeln.
|
"""Empfaengt Dateien fuer das PLC Programm einzeln.
|
||||||
|
|
||||||
@param filedata GZIP Binary data der Datei
|
@param filedata GZIP Binary data der Datei
|
||||||
@@ -1185,14 +1201,18 @@ class RevPiPyLoad:
|
|||||||
# Windowszeichen prüfen
|
# Windowszeichen prüfen
|
||||||
filename = filename.replace("\\", "/")
|
filename = filename.replace("\\", "/")
|
||||||
|
|
||||||
# Build absolut path, join will return last element, if absolute
|
|
||||||
dirname = os.path.join(self.plcworkdir, os.path.dirname(filename))
|
plcworkdir = os.path.realpath(self.plcworkdir)
|
||||||
if os.path.abspath(dirname).find(self.plcworkdir) != 0:
|
file_path = os.path.realpath(os.path.join(plcworkdir, filename))
|
||||||
|
|
||||||
|
if os.path.commonpath([plcworkdir, file_path]) != plcworkdir:
|
||||||
proginit.logger.warning(
|
proginit.logger.warning(
|
||||||
"file path is not in plc working directory"
|
"file path is not in plc working directory"
|
||||||
)
|
)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
dirname = os.path.dirname(file_path)
|
||||||
|
|
||||||
set_uid = self.plcuid if self.plcworkdir_set_uid else 0
|
set_uid = self.plcuid if self.plcworkdir_set_uid else 0
|
||||||
set_gid = self.plcgid if self.plcworkdir_set_uid else 0
|
set_gid = self.plcgid if self.plcworkdir_set_uid else 0
|
||||||
|
|
||||||
@@ -1210,9 +1230,9 @@ class RevPiPyLoad:
|
|||||||
|
|
||||||
# Datei erzeugen
|
# Datei erzeugen
|
||||||
try:
|
try:
|
||||||
with open(filename, "wb") as fh:
|
with open(file_path, "wb") as fh:
|
||||||
fh.write(gzip.decompress(filedata.data))
|
fh.write(gzip.decompress(filedata.data))
|
||||||
os.chown(filename, set_uid, set_gid)
|
os.chown(file_path, set_uid, set_gid)
|
||||||
return True
|
return True
|
||||||
except Exception:
|
except Exception:
|
||||||
return False
|
return False
|
||||||
|
|||||||
Reference in New Issue
Block a user