Skip to content

Commit ccabc9e

Browse files
committed
fix: Escape metadata values in DirectoryMetadata.__createMetaSelection
__createMetaSelection interpolated user-supplied metadata operands directly into the SQL selection string (e.g. "{table}Value='{operand}'"), and the callers (__findSubdirByMeta, __checkDirsForMetadata) execute the resulting query with no bound args, so a crafted metadata query value was live SQL -> injection via findDirectoriesByMetadata. Escape every string operand through the DB _escapeString/_escapeValues helpers (which quote and escape the value) before inlining it, mirroring the FileMetadata.__createMetaSelection sibling which already does this. Numeric operands keep their existing safe %d/%f handling. This defect predates the SQL-parameterisation series.
1 parent 61b8579 commit ccabc9e

1 file changed

Lines changed: 28 additions & 7 deletions

File tree

src/DIRAC/DataManagementSystem/DB/FileCatalogComponents/DirectoryMetadata/DirectoryMetadata.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -513,28 +513,49 @@ def __createMetaSelection(self, value, table=""):
513513
elif isinstance(operand, float):
514514
selectList.append(f"{table}Value{operation}{operand:f}")
515515
else:
516-
selectList.append(f"{table}Value{operation}'{operand}'")
516+
result = self.db._escapeString(operand)
517+
if not result["OK"]:
518+
return result
519+
selectList.append(f"{table}Value{operation}{result['Value']}")
517520
elif operation == "in" or operation == "=":
518521
if isinstance(operand, list):
519-
vString = ",".join(["'" + str(x) + "'" for x in operand])
522+
result = self.db._escapeValues(operand)
523+
if not result["OK"]:
524+
return result
525+
vString = ",".join(result["Value"])
520526
selectList.append(f"{table}Value IN ({vString})")
521527
else:
522-
selectList.append(f"{table}Value='{operand}'")
528+
result = self.db._escapeString(operand)
529+
if not result["OK"]:
530+
return result
531+
selectList.append(f"{table}Value={result['Value']}")
523532
elif operation == "nin" or operation == "!=":
524533
if isinstance(operand, list):
525-
vString = ",".join(["'" + str(x) + "'" for x in operand])
534+
result = self.db._escapeValues(operand)
535+
if not result["OK"]:
536+
return result
537+
vString = ",".join(result["Value"])
526538
selectList.append(f"{table}Value NOT IN ({vString})")
527539
else:
528-
selectList.append(f"{table}Value!='{operand}'")
540+
result = self.db._escapeString(operand)
541+
if not result["OK"]:
542+
return result
543+
selectList.append(f"{table}Value!={result['Value']}")
529544
selectString = " AND ".join(selectList)
530545
elif isinstance(value, list):
531-
vString = ",".join(["'" + str(x) + "'" for x in value])
546+
result = self.db._escapeValues(value)
547+
if not result["OK"]:
548+
return result
549+
vString = ",".join(result["Value"])
532550
selectString = f"{table}Value in ({vString})"
533551
else:
534552
if value == "Any":
535553
selectString = ""
536554
else:
537-
selectString = f"{table}Value='{value}' "
555+
result = self.db._escapeString(value)
556+
if not result["OK"]:
557+
return result
558+
selectString = f"{table}Value={result['Value']} "
538559

539560
return S_OK(selectString)
540561

0 commit comments

Comments
 (0)