Skip to content

Commit 4e49d75

Browse files
committed
Unsafe Deserialization and Remote Code Execution by an Authenticated user in pgAdmin 4 (CVE-2024-2044).
1 parent 0cbb532 commit 4e49d75

File tree

2 files changed

+20
-10
lines changed

2 files changed

+20
-10
lines changed

docs/en_US/release_notes_8_4.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,4 @@ Bug fixes
4343
| `Issue #7193 <https://github.com/pgadmin-org/pgadmin4/issues/7193>`_ - Ensure that the OAuth2 session is logged out when users log out from pgAdmin.
4444
| `Issue #7217 <https://github.com/pgadmin-org/pgadmin4/issues/7217>`_ - Remove role related checks on the UI dashboard when terminating session/query and let PostgreSQL take care of it.
4545
| `Issue #7225 <https://github.com/pgadmin-org/pgadmin4/issues/7225>`_ - Fix an issue where type column in dependents/dependencies tab is not showing correct label.
46+
| `Issue #7258 <https://github.com/pgadmin-org/pgadmin4/issues/7258>`_ - Unsafe Deserialization and Remote Code Execution by an Authenticated user in pgAdmin 4 (CVE-2024-2044).

web/pgadmin/utils/session.py

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
from flask.sessions import SessionInterface, SessionMixin
3636
from werkzeug.datastructures import CallbackDict
37+
from werkzeug.security import safe_join
38+
from werkzeug.exceptions import InternalServerError
3739

3840
from pgadmin.utils.ajax import make_json_response
3941

@@ -192,27 +194,30 @@ def __init__(self, path, secret, disk_write_delay, skip_paths=None):
192194
self.skip_paths = [] if skip_paths is None else skip_paths
193195

194196
def exists(self, sid):
195-
fname = os.path.join(self.path, sid)
196-
return os.path.exists(fname)
197+
fname = safe_join(self.path, sid)
198+
return fname is not None and os.path.exists(fname)
197199

198200
def remove(self, sid):
199-
fname = os.path.join(self.path, sid)
200-
if os.path.exists(fname):
201+
fname = safe_join(self.path, sid)
202+
if fname is not None and os.path.exists(fname):
201203
os.unlink(fname)
202204

203205
def new_session(self):
204206
sid = str(uuid4())
205-
fname = os.path.join(self.path, sid)
207+
fname = safe_join(self.path, sid)
206208

207-
while os.path.exists(fname):
209+
while fname is not None and os.path.exists(fname):
208210
sid = str(uuid4())
209-
fname = os.path.join(self.path, sid)
211+
fname = safe_join(self.path, sid)
210212

211213
# Do not store the session if skip paths
212214
for sp in self.skip_paths:
213215
if request.path.startswith(sp):
214216
return ManagedSession(sid=sid)
215217

218+
if fname is None:
219+
raise InternalServerError('Failed to create new session')
220+
216221
# touch the file
217222
with open(fname, 'wb'):
218223
return ManagedSession(sid=sid)
@@ -222,12 +227,12 @@ def new_session(self):
222227
def get(self, sid, digest):
223228
'Retrieve a managed session by session-id, checking the HMAC digest'
224229

225-
fname = os.path.join(self.path, sid)
230+
fname = safe_join(self.path, sid)
226231
data = None
227232
hmac_digest = None
228233
randval = None
229234

230-
if os.path.exists(fname):
235+
if fname is not None and os.path.exists(fname):
231236
try:
232237
with open(fname, 'rb') as f:
233238
randval, hmac_digest, data = load(f)
@@ -266,7 +271,11 @@ def put(self, session):
266271
if request.path.startswith(sp):
267272
return
268273

269-
fname = os.path.join(self.path, session.sid)
274+
fname = safe_join(self.path, session.sid)
275+
276+
if fname is None:
277+
raise InternalServerError('Failed to update the session')
278+
270279
with open(fname, 'wb') as f:
271280
dump(
272281
(session.randval, session.hmac_digest, dict(session)),

0 commit comments

Comments
 (0)