From bed1ec89816dacf1fddc92afb1d09b38fd4a1363 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Wed, 11 Feb 2026 12:10:08 +0000 Subject: [PATCH 1/2] Enhance path validation recommendations Expanded recommendations for validating user input when constructing file paths, including normalization and using allowlists. --- .../src/Security/CWE-022/PathInjection.qhelp | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/python/ql/src/Security/CWE-022/PathInjection.qhelp b/python/ql/src/Security/CWE-022/PathInjection.qhelp index ed12b74b6d97..ebe267a462ce 100644 --- a/python/ql/src/Security/CWE-022/PathInjection.qhelp +++ b/python/ql/src/Security/CWE-022/PathInjection.qhelp @@ -13,21 +13,26 @@ attacker being able to influence behavior by modifying unexpected files.

-Validate user input before using it to construct a file path, either using an off-the-shelf library function -like werkzeug.utils.secure_filename, or by performing custom validation. +Validate paths constructed from untrusted user input before using them to access files.

-Ideally, follow these rules: +The choice of validation depends on the use case.

- +

+If you want to allow paths spanning multiple folders, a common strategy is to make sure that the constructed +file path is contained within a safe root folder. First, normalize the path using os.path.normpath or +os.path.realpath to remove any ".." segments. Then check that the normalized path starts with the +root folder. Note that the normalization step is important, since otherwise even a path that starts with the root +folder could be used to access files outside the root folder. +

+ +

+More restrictive options include using a library function like werkzeug.utils.secure_filename to eliminate +any special characters from the file path, or restricting the path to an allow list of safe paths. These options are +safe, but can only be used in particular circumstances. +

From 5f970d9f2fc9de4a41cca594bf06ba494e2527e9 Mon Sep 17 00:00:00 2001 From: Chris Smowton Date: Thu, 12 Feb 2026 12:01:33 +0000 Subject: [PATCH 2/2] Rewordings per copilot --- python/ql/src/Security/CWE-022/PathInjection.qhelp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/ql/src/Security/CWE-022/PathInjection.qhelp b/python/ql/src/Security/CWE-022/PathInjection.qhelp index ebe267a462ce..53653abb12e6 100644 --- a/python/ql/src/Security/CWE-022/PathInjection.qhelp +++ b/python/ql/src/Security/CWE-022/PathInjection.qhelp @@ -23,14 +23,15 @@ The choice of validation depends on the use case.

If you want to allow paths spanning multiple folders, a common strategy is to make sure that the constructed file path is contained within a safe root folder. First, normalize the path using os.path.normpath or -os.path.realpath to remove any ".." segments. Then check that the normalized path starts with the +os.path.realpath (make sure to use the latter if symlinks are a consideration) +to remove any internal ".." segments and/or follow links. Then check that the normalized path starts with the root folder. Note that the normalization step is important, since otherwise even a path that starts with the root folder could be used to access files outside the root folder.

More restrictive options include using a library function like werkzeug.utils.secure_filename to eliminate -any special characters from the file path, or restricting the path to an allow list of safe paths. These options are +any special characters from the file path, or restricting the path to a known list of safe paths. These options are safe, but can only be used in particular circumstances.