Skip to content

Commit 4a66002

Browse files
committed
fix: block path traversal in runtime file I/O paths
1 parent dccbcd4 commit 4a66002

21 files changed

Lines changed: 336 additions & 72 deletions

File tree

0mq/comm_node.dir/concore2.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ def unchanged():
130130
olds = s
131131
return False
132132

133+
def _resolve_port_file_path(base_path, port_num, name):
134+
port_dir = os.path.abspath(base_path + str(port_num))
135+
file_path = os.path.abspath(os.path.join(port_dir, name))
136+
try:
137+
if os.path.commonpath([port_dir, file_path]) != port_dir:
138+
raise ValueError
139+
except ValueError:
140+
raise ValueError(f"Invalid file name '{name}' for port {port_num}")
141+
return file_path
142+
133143
def read(port_identifier, name, initstr_val):
134144
global s, simtime, retrycount
135145

@@ -154,12 +164,12 @@ def read(port_identifier, name, initstr_val):
154164

155165
try:
156166
file_port_num = int(port_identifier)
167+
file_path = _resolve_port_file_path(inpath, file_port_num, name)
157168
except ValueError:
158-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
169+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
159170
return default_return_val
160171

161172
time.sleep(delay)
162-
file_path = os.path.join(inpath+str(file_port_num), name)
163173
ins = ""
164174

165175
try:
@@ -220,9 +230,9 @@ def write(port_identifier, name, val, delta=0):
220230
file_path = os.path.join("../"+port_identifier, name)
221231
else:
222232
file_port_num = int(port_identifier)
223-
file_path = os.path.join(outpath+str(file_port_num), name)
233+
file_path = _resolve_port_file_path(outpath, file_port_num, name)
224234
except ValueError:
225-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
235+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
226236
return
227237

228238
if isinstance(val, str):

0mq/funbody.dir/concore2.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ def unchanged():
130130
olds = s
131131
return False
132132

133+
def _resolve_port_file_path(base_path, port_num, name):
134+
port_dir = os.path.abspath(base_path + str(port_num))
135+
file_path = os.path.abspath(os.path.join(port_dir, name))
136+
try:
137+
if os.path.commonpath([port_dir, file_path]) != port_dir:
138+
raise ValueError
139+
except ValueError:
140+
raise ValueError(f"Invalid file name '{name}' for port {port_num}")
141+
return file_path
142+
133143
def read(port_identifier, name, initstr_val):
134144
global s, simtime, retrycount
135145

@@ -154,12 +164,12 @@ def read(port_identifier, name, initstr_val):
154164

155165
try:
156166
file_port_num = int(port_identifier)
167+
file_path = _resolve_port_file_path(inpath, file_port_num, name)
157168
except ValueError:
158-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
169+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
159170
return default_return_val
160171

161172
time.sleep(delay)
162-
file_path = os.path.join(inpath+str(file_port_num), name)
163173
ins = ""
164174

165175
try:
@@ -220,9 +230,9 @@ def write(port_identifier, name, val, delta=0):
220230
file_path = os.path.join("../"+port_identifier, name)
221231
else:
222232
file_port_num = int(port_identifier)
223-
file_path = os.path.join(outpath+str(file_port_num), name)
233+
file_path = _resolve_port_file_path(outpath, file_port_num, name)
224234
except ValueError:
225-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
235+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
226236
return
227237

228238
if isinstance(val, str):

0mq/funbody2.dir/concore2.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ def unchanged():
130130
olds = s
131131
return False
132132

133+
def _resolve_port_file_path(base_path, port_num, name):
134+
port_dir = os.path.abspath(base_path + str(port_num))
135+
file_path = os.path.abspath(os.path.join(port_dir, name))
136+
try:
137+
if os.path.commonpath([port_dir, file_path]) != port_dir:
138+
raise ValueError
139+
except ValueError:
140+
raise ValueError(f"Invalid file name '{name}' for port {port_num}")
141+
return file_path
142+
133143
def read(port_identifier, name, initstr_val):
134144
global s, simtime, retrycount
135145

@@ -154,12 +164,12 @@ def read(port_identifier, name, initstr_val):
154164

155165
try:
156166
file_port_num = int(port_identifier)
167+
file_path = _resolve_port_file_path(inpath, file_port_num, name)
157168
except ValueError:
158-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
169+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
159170
return default_return_val
160171

161172
time.sleep(delay)
162-
file_path = os.path.join(inpath+str(file_port_num), name)
163173
ins = ""
164174

165175
try:
@@ -220,9 +230,9 @@ def write(port_identifier, name, val, delta=0):
220230
file_path = os.path.join("../"+port_identifier, name)
221231
else:
222232
file_port_num = int(port_identifier)
223-
file_path = os.path.join(outpath+str(file_port_num), name)
233+
file_path = _resolve_port_file_path(outpath, file_port_num, name)
224234
except ValueError:
225-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
235+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
226236
return
227237

228238
if isinstance(val, str):

0mq/funbody_distributed.dir/concore2.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ def unchanged():
130130
olds = s
131131
return False
132132

133+
def _resolve_port_file_path(base_path, port_num, name):
134+
port_dir = os.path.abspath(base_path + str(port_num))
135+
file_path = os.path.abspath(os.path.join(port_dir, name))
136+
try:
137+
if os.path.commonpath([port_dir, file_path]) != port_dir:
138+
raise ValueError
139+
except ValueError:
140+
raise ValueError(f"Invalid file name '{name}' for port {port_num}")
141+
return file_path
142+
133143
def read(port_identifier, name, initstr_val):
134144
global s, simtime, retrycount
135145

@@ -154,12 +164,12 @@ def read(port_identifier, name, initstr_val):
154164

155165
try:
156166
file_port_num = int(port_identifier)
167+
file_path = _resolve_port_file_path(inpath, file_port_num, name)
157168
except ValueError:
158-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
169+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
159170
return default_return_val
160171

161172
time.sleep(delay)
162-
file_path = os.path.join(inpath+str(file_port_num), name)
163173
ins = ""
164174

165175
try:
@@ -220,9 +230,9 @@ def write(port_identifier, name, val, delta=0):
220230
file_path = os.path.join("../"+port_identifier, name)
221231
else:
222232
file_port_num = int(port_identifier)
223-
file_path = os.path.join(outpath+str(file_port_num), name)
233+
file_path = _resolve_port_file_path(outpath, file_port_num, name)
224234
except ValueError:
225-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
235+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
226236
return
227237

228238
if isinstance(val, str):

0mq/funbody_zmq.dir/concore2.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ def unchanged():
130130
olds = s
131131
return False
132132

133+
def _resolve_port_file_path(base_path, port_num, name):
134+
port_dir = os.path.abspath(base_path + str(port_num))
135+
file_path = os.path.abspath(os.path.join(port_dir, name))
136+
try:
137+
if os.path.commonpath([port_dir, file_path]) != port_dir:
138+
raise ValueError
139+
except ValueError:
140+
raise ValueError(f"Invalid file name '{name}' for port {port_num}")
141+
return file_path
142+
133143
def read(port_identifier, name, initstr_val):
134144
global s, simtime, retrycount
135145

@@ -154,12 +164,12 @@ def read(port_identifier, name, initstr_val):
154164

155165
try:
156166
file_port_num = int(port_identifier)
167+
file_path = _resolve_port_file_path(inpath, file_port_num, name)
157168
except ValueError:
158-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
169+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
159170
return default_return_val
160171

161172
time.sleep(delay)
162-
file_path = os.path.join(inpath+str(file_port_num), name)
163173
ins = ""
164174

165175
try:
@@ -220,9 +230,9 @@ def write(port_identifier, name, val, delta=0):
220230
file_path = os.path.join("../"+port_identifier, name)
221231
else:
222232
file_port_num = int(port_identifier)
223-
file_path = os.path.join(outpath+str(file_port_num), name)
233+
file_path = _resolve_port_file_path(outpath, file_port_num, name)
224234
except ValueError:
225-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
235+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
226236
return
227237

228238
if isinstance(val, str):

0mq/funbody_zmq2.dir/concore2.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ def unchanged():
130130
olds = s
131131
return False
132132

133+
def _resolve_port_file_path(base_path, port_num, name):
134+
port_dir = os.path.abspath(base_path + str(port_num))
135+
file_path = os.path.abspath(os.path.join(port_dir, name))
136+
try:
137+
if os.path.commonpath([port_dir, file_path]) != port_dir:
138+
raise ValueError
139+
except ValueError:
140+
raise ValueError(f"Invalid file name '{name}' for port {port_num}")
141+
return file_path
142+
133143
def read(port_identifier, name, initstr_val):
134144
global s, simtime, retrycount
135145

@@ -154,12 +164,12 @@ def read(port_identifier, name, initstr_val):
154164

155165
try:
156166
file_port_num = int(port_identifier)
167+
file_path = _resolve_port_file_path(inpath, file_port_num, name)
157168
except ValueError:
158-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
169+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
159170
return default_return_val
160171

161172
time.sleep(delay)
162-
file_path = os.path.join(inpath+str(file_port_num), name)
163173
ins = ""
164174

165175
try:
@@ -220,9 +230,9 @@ def write(port_identifier, name, val, delta=0):
220230
file_path = os.path.join("../"+port_identifier, name)
221231
else:
222232
file_port_num = int(port_identifier)
223-
file_path = os.path.join(outpath+str(file_port_num), name)
233+
file_path = _resolve_port_file_path(outpath, file_port_num, name)
224234
except ValueError:
225-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
235+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
226236
return
227237

228238
if isinstance(val, str):

0mq/funcall.dir/concore2.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ def unchanged():
130130
olds = s
131131
return False
132132

133+
def _resolve_port_file_path(base_path, port_num, name):
134+
port_dir = os.path.abspath(base_path + str(port_num))
135+
file_path = os.path.abspath(os.path.join(port_dir, name))
136+
try:
137+
if os.path.commonpath([port_dir, file_path]) != port_dir:
138+
raise ValueError
139+
except ValueError:
140+
raise ValueError(f"Invalid file name '{name}' for port {port_num}")
141+
return file_path
142+
133143
def read(port_identifier, name, initstr_val):
134144
global s, simtime, retrycount
135145

@@ -154,12 +164,12 @@ def read(port_identifier, name, initstr_val):
154164

155165
try:
156166
file_port_num = int(port_identifier)
167+
file_path = _resolve_port_file_path(inpath, file_port_num, name)
157168
except ValueError:
158-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
169+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
159170
return default_return_val
160171

161172
time.sleep(delay)
162-
file_path = os.path.join(inpath+str(file_port_num), name)
163173
ins = ""
164174

165175
try:
@@ -220,9 +230,9 @@ def write(port_identifier, name, val, delta=0):
220230
file_path = os.path.join("../"+port_identifier, name)
221231
else:
222232
file_port_num = int(port_identifier)
223-
file_path = os.path.join(outpath+str(file_port_num), name)
233+
file_path = _resolve_port_file_path(outpath, file_port_num, name)
224234
except ValueError:
225-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
235+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
226236
return
227237

228238
if isinstance(val, str):

0mq/funcall2.dir/concore2.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ def unchanged():
130130
olds = s
131131
return False
132132

133+
def _resolve_port_file_path(base_path, port_num, name):
134+
port_dir = os.path.abspath(base_path + str(port_num))
135+
file_path = os.path.abspath(os.path.join(port_dir, name))
136+
try:
137+
if os.path.commonpath([port_dir, file_path]) != port_dir:
138+
raise ValueError
139+
except ValueError:
140+
raise ValueError(f"Invalid file name '{name}' for port {port_num}")
141+
return file_path
142+
133143
def read(port_identifier, name, initstr_val):
134144
global s, simtime, retrycount
135145

@@ -154,12 +164,12 @@ def read(port_identifier, name, initstr_val):
154164

155165
try:
156166
file_port_num = int(port_identifier)
167+
file_path = _resolve_port_file_path(inpath, file_port_num, name)
157168
except ValueError:
158-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
169+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
159170
return default_return_val
160171

161172
time.sleep(delay)
162-
file_path = os.path.join(inpath+str(file_port_num), name)
163173
ins = ""
164174

165175
try:
@@ -220,9 +230,9 @@ def write(port_identifier, name, val, delta=0):
220230
file_path = os.path.join("../"+port_identifier, name)
221231
else:
222232
file_port_num = int(port_identifier)
223-
file_path = os.path.join(outpath+str(file_port_num), name)
233+
file_path = _resolve_port_file_path(outpath, file_port_num, name)
224234
except ValueError:
225-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
235+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
226236
return
227237

228238
if isinstance(val, str):

0mq/funcall_distributed.dir/concore2.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,16 @@ def unchanged():
130130
olds = s
131131
return False
132132

133+
def _resolve_port_file_path(base_path, port_num, name):
134+
port_dir = os.path.abspath(base_path + str(port_num))
135+
file_path = os.path.abspath(os.path.join(port_dir, name))
136+
try:
137+
if os.path.commonpath([port_dir, file_path]) != port_dir:
138+
raise ValueError
139+
except ValueError:
140+
raise ValueError(f"Invalid file name '{name}' for port {port_num}")
141+
return file_path
142+
133143
def read(port_identifier, name, initstr_val):
134144
global s, simtime, retrycount
135145

@@ -154,12 +164,12 @@ def read(port_identifier, name, initstr_val):
154164

155165
try:
156166
file_port_num = int(port_identifier)
167+
file_path = _resolve_port_file_path(inpath, file_port_num, name)
157168
except ValueError:
158-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
169+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
159170
return default_return_val
160171

161172
time.sleep(delay)
162-
file_path = os.path.join(inpath+str(file_port_num), name)
163173
ins = ""
164174

165175
try:
@@ -220,9 +230,9 @@ def write(port_identifier, name, val, delta=0):
220230
file_path = os.path.join("../"+port_identifier, name)
221231
else:
222232
file_port_num = int(port_identifier)
223-
file_path = os.path.join(outpath+str(file_port_num), name)
233+
file_path = _resolve_port_file_path(outpath, file_port_num, name)
224234
except ValueError:
225-
print(f"Error: Invalid port identifier '{port_identifier}' for file operation. Must be integer or ZMQ name.")
235+
print(f"Error: Invalid port identifier '{port_identifier}' or file name '{name}' for file operation.")
226236
return
227237

228238
if isinstance(val, str):

0 commit comments

Comments
 (0)