Fix: Avoid double escapes in sql values (#38940)
* Fix: values already escaped for db in 'isInDb' # Fix: values already escaped for db in 'isInDb' The values of $value_arr were escaped before the call to 'isInDb' resulting in a potential double escape' * Fix: escape values only once in sqlFilterSearchField # Fix: escape values only once in sqlFilterSearchField The values of $value were escaped before appending them to the sql expression where they were also escaped, resulting in a potential double escape' * Fix: escape values only once in sqlFilterSearchField # Fix: escape values only once in sqlFilterSearchField The values of $value were escaped before appending them to the sql expression where they were also escaped, resulting in a potential double escape' * Fix: escape values only once in getOptions # Fix: escape values only once in getOptions The values of $selectedValues were escaped before appending them to the sql expression where they were also escaped, resulting in a potential double escape' * Fix: escape values only once in sqlFilterSearchField # Fix: escape values only once in sqlFilterSearchField The values of $value were escaped before appending them to the sql expression where they were also escaped, resulting in a potential double escape' * Fix: escape values only once in sqlFilterSearchField # Fix: escape values only once in sqlFilterSearchField The values of $value were escaped before appending them to the sql expression where they were also escaped, resulting in a potential double escape' * Fix: escape values only once in sqlFilterSearchField # Fix: escape values only once in sqlFilterSearchField The values of $value were escaped before appending them to the sql expression where they were also escaped, resulting in a potential double escape' --------- Co-authored-by: Laurent Destailleur <eldy@destailleur.fr>
This commit is contained in:
parent
65a0d0e36e
commit
4eaa846739
7 changed files with 76 additions and 38 deletions
|
|
@ -99,7 +99,7 @@ abstract class CommonObject
|
|||
public $warning;
|
||||
|
||||
/**
|
||||
* @var string[] Array of warning strings
|
||||
* @var string[] Array of warning strings
|
||||
*/
|
||||
public $warnings = array();
|
||||
|
||||
|
|
@ -7677,7 +7677,7 @@ abstract class CommonObject
|
|||
$sanitizedGeoDataType = ExtraFields::$geoDataTypes[$attributeType] ?? null;
|
||||
if ($this->array_options["options_".$key] === null) {
|
||||
$sql = "UPDATE ".$this->db->prefix().$this->db->sanitize($table_element)."_extrafields";
|
||||
$sql.= " SET ".$this->db->sanitize($key)." = null";
|
||||
$sql .= " SET ".$this->db->sanitize($key)." = null";
|
||||
} elseif (!empty($sanitizedGeoDataType['ST_Function'])) {
|
||||
$sql = "UPDATE ".$this->db->prefix().$this->db->sanitize($table_element)."_extrafields";
|
||||
$sql .= " SET ".$this->db->sanitize($key)." = ".$this->db->sanitize($sanitizedGeoDataType['ST_Function'])."('".$this->db->escape($this->array_options["options_".$key])."')";
|
||||
|
|
@ -9482,7 +9482,6 @@ abstract class CommonObject
|
|||
$param_list = array_keys($param['options']);
|
||||
$InfoFieldList = explode(":", $param_list[0]);
|
||||
$value_arr = explode(',', $fieldValue);
|
||||
$value_arr = array_map(array($this->db, 'escape'), $value_arr);
|
||||
|
||||
$selectkey = "rowid";
|
||||
if (count($InfoFieldList) > 4 && !empty($InfoFieldList[4])) {
|
||||
|
|
@ -9603,7 +9602,7 @@ abstract class CommonObject
|
|||
} elseif (($mode == 'edit') && !in_array(abs($visibility), array(1, 3, 4))) {
|
||||
// We need to make sure, that the values of hidden extrafields are also part of $_POST. Otherwise, they would be empty after an update of the object. See also getOptionalsFromPost
|
||||
$ef_name = 'options_' . $key;
|
||||
$ef_value = $this->array_options[$ef_name]??'';
|
||||
$ef_value = $this->array_options[$ef_name] ?? '';
|
||||
$out .= '<input type="hidden" name="' . $ef_name . '" id="' . $ef_name . '" value="' . $ef_value . '" />' . "\n";
|
||||
continue; // <> -1 and <> 1 and <> 3 = not visible on forms, only on list and <> 4 = not visible at the creation
|
||||
} elseif ($mode == 'view' && empty($visibility)) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
/* Copyright (C) 2025 Open-Dsi <support@open-dsi.fr>
|
||||
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -70,9 +71,11 @@ class CheckboxField extends CommonSelectField
|
|||
|
||||
$moreCss = $this->getInputCss($fieldInfos, $moreCss);
|
||||
$moreAttrib = trim((string) $moreAttrib);
|
||||
if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib;
|
||||
if (empty($moreAttrib)) {
|
||||
$moreAttrib = ' ' . $moreAttrib;
|
||||
}
|
||||
$htmlName = $keyPrefix . $key . $keySuffix;
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value)));
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value : array($value)));
|
||||
|
||||
$optionsList = array();
|
||||
$options = $this->getOptions($fieldInfos, $key);
|
||||
|
|
@ -95,7 +98,7 @@ class CheckboxField extends CommonSelectField
|
|||
public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '')
|
||||
{
|
||||
global $langs;
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value)));
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value : array($value)));
|
||||
|
||||
$out = '';
|
||||
if (!$this->isEmptyValue($fieldInfos, $values)) {
|
||||
|
|
@ -147,7 +150,7 @@ class CheckboxField extends CommonSelectField
|
|||
public function verifyFieldValue($fieldInfos, $key, $value)
|
||||
{
|
||||
global $langs;
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value)));
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value : array($value)));
|
||||
|
||||
$result = parent::verifyFieldValue($fieldInfos, $key, $values);
|
||||
if ($result && !$this->isEmptyValue($fieldInfos, $values)) {
|
||||
|
|
@ -201,7 +204,9 @@ class CheckboxField extends CommonSelectField
|
|||
|
||||
if (GETPOSTISSET($htmlName)) {
|
||||
$values = GETPOST($htmlName, 'array');
|
||||
if (is_array($values)) $values = implode(',', $values);
|
||||
if (is_array($values)) {
|
||||
$values = implode(',', $values);
|
||||
}
|
||||
} else {
|
||||
$values = $defaultValue;
|
||||
}
|
||||
|
|
@ -249,7 +254,8 @@ class CheckboxField extends CommonSelectField
|
|||
$field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key));
|
||||
|
||||
$sanitizedSqlIn = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'";
|
||||
return " AND " . $field . " IN (" . $sanitizedSqlIn . ")";
|
||||
$sqlPartialCond = " AND " . $field . " IN (" . $sanitizedSqlIn . ")";
|
||||
return $sqlPartialCond;
|
||||
}
|
||||
|
||||
return '';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
/* Copyright (C) 2025 Open-Dsi <support@open-dsi.fr>
|
||||
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -53,9 +54,11 @@ class ChkbxlstField extends CommonSellistField
|
|||
|
||||
$moreCss = $this->getInputCss($fieldInfos, $moreCss);
|
||||
$moreAttrib = trim((string) $moreAttrib);
|
||||
if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib;
|
||||
if (empty($moreAttrib)) {
|
||||
$moreAttrib = ' ' . $moreAttrib;
|
||||
}
|
||||
$htmlName = $keyPrefix . $key . $keySuffix;
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value)));
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value : array($value)));
|
||||
|
||||
$optionsList = array();
|
||||
$options = $this->getOptions($fieldInfos, $key);
|
||||
|
|
@ -84,9 +87,11 @@ class ChkbxlstField extends CommonSellistField
|
|||
|
||||
$moreCss = $this->getInputCss($fieldInfos, $moreCss);
|
||||
$moreAttrib = trim((string) $moreAttrib);
|
||||
if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib;
|
||||
if (empty($moreAttrib)) {
|
||||
$moreAttrib = ' ' . $moreAttrib;
|
||||
}
|
||||
$htmlName = $keyPrefix . $key . $keySuffix;
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value)));
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value : array($value)));
|
||||
|
||||
$options = $this->getOptions($fieldInfos, $key);
|
||||
|
||||
|
|
@ -107,7 +112,7 @@ class ChkbxlstField extends CommonSellistField
|
|||
*/
|
||||
public function printOutputField($fieldInfos, $key, $value, $keyPrefix = '', $keySuffix = '', $moreCss = '', $moreAttrib = '')
|
||||
{
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value)));
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value : array($value)));
|
||||
|
||||
$out = '';
|
||||
if (!$this->isEmptyValue($fieldInfos, $values)) {
|
||||
|
|
@ -167,7 +172,7 @@ class ChkbxlstField extends CommonSellistField
|
|||
*/
|
||||
public function verifyFieldValue($fieldInfos, $key, $value)
|
||||
{
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value)));
|
||||
$values = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value : array($value)));
|
||||
|
||||
$result = parent::verifyFieldValue($fieldInfos, $key, $values);
|
||||
if ($result && !$this->isEmptyValue($fieldInfos, $values)) {
|
||||
|
|
@ -217,7 +222,9 @@ class ChkbxlstField extends CommonSellistField
|
|||
|
||||
if (GETPOSTISSET($htmlName)) {
|
||||
$values = GETPOST($htmlName, 'array');
|
||||
if (is_array($values)) $values = implode(',', $values);
|
||||
if (is_array($values)) {
|
||||
$values = implode(',', $values);
|
||||
}
|
||||
} else {
|
||||
$values = $defaultValue;
|
||||
}
|
||||
|
|
@ -264,8 +271,9 @@ class ChkbxlstField extends CommonSellistField
|
|||
$alias = $fieldInfos->sqlAlias ?? 't.';
|
||||
$field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key));
|
||||
|
||||
$tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'";
|
||||
return " AND " . $field . " IN (" . $this->db->sanitize($tmp, 1) . ")";
|
||||
$sanitizedSqlIn = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'";
|
||||
$sqlPartialCond = " AND " . $field . " IN (" . $sanitizedSqlIn . ")";
|
||||
return $sqlPartialCond;
|
||||
}
|
||||
|
||||
return '';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
/* Copyright (C) 2025 Open-Dsi <support@open-dsi.fr>
|
||||
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -128,7 +129,9 @@ class CommonSellistField extends CommonField
|
|||
$labelAlias[] = $tmp['alias'];
|
||||
}
|
||||
$keyField = (string) ($InfoFieldList[2] ?? '');
|
||||
if (empty($keyField)) $keyField = 'rowid';
|
||||
if (empty($keyField)) {
|
||||
$keyField = 'rowid';
|
||||
}
|
||||
$keyFieldParent = (string) ($InfoFieldList[3] ?? '');
|
||||
$tmp = array_map('trim', explode('|', $keyFieldParent));
|
||||
$parentName = (string) ($tmp[0] ?? '');
|
||||
|
|
@ -302,8 +305,8 @@ class CommonSellistField extends CommonField
|
|||
}
|
||||
// Only selected values
|
||||
if (!empty($selectedValues)) {
|
||||
$tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $selectedValues)) . "'";
|
||||
$sql .= " AND " . $this->db->sanitize($keyField) . " IN (" . $this->db->sanitize($tmp, 1) . ")";
|
||||
$sanitizedSqlIn = "'" . implode("','", array_map(array($this->db, 'escape'), $selectedValues)) . "'";
|
||||
$sql .= " AND " . $this->db->sanitize($keyField) . " IN (" . $sanitizedSqlIn . ")";
|
||||
}
|
||||
|
||||
// Note: $InfoFieldList can be 'sellist:TableName:LabelFieldName[:KeyFieldName[:KeyFieldParent[:Filter[:CategoryIdType[:CategoryIdList[:Sortfield]]]]]]'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
/* Copyright (C) 2025 Open-Dsi <support@open-dsi.fr>
|
||||
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -53,9 +54,11 @@ class RadioField extends CommonSelectField
|
|||
|
||||
$moreCss = $this->getInputCss($fieldInfos, $moreCss);
|
||||
$moreAttrib = trim((string) $moreAttrib);
|
||||
if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib;
|
||||
if (empty($moreAttrib)) {
|
||||
$moreAttrib = ' ' . $moreAttrib;
|
||||
}
|
||||
$htmlName = $keyPrefix . $key . $keySuffix;
|
||||
$value = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value)));
|
||||
$value = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value : array($value)));
|
||||
|
||||
$optionsList = array();
|
||||
$options = $this->getOptions($fieldInfos, $key);
|
||||
|
|
@ -82,7 +85,9 @@ class RadioField extends CommonSelectField
|
|||
{
|
||||
$moreCss = $this->getInputCss($fieldInfos, $moreCss);
|
||||
$moreAttrib = trim((string) $moreAttrib);
|
||||
if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib;
|
||||
if (empty($moreAttrib)) {
|
||||
$moreAttrib = ' ' . $moreAttrib;
|
||||
}
|
||||
$htmlName = $keyPrefix . $key . $keySuffix;
|
||||
|
||||
$selectedValue = $this->isEmptyValue($fieldInfos, $value) ? '' : (string) $value;
|
||||
|
|
@ -253,8 +258,9 @@ class RadioField extends CommonSelectField
|
|||
$alias = $fieldInfos->sqlAlias ?? 't.';
|
||||
$field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key));
|
||||
|
||||
$tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'";
|
||||
return " AND " . $field . " IN (" . $this->db->sanitize($tmp, 1) . ")";
|
||||
$sanitizedSqlIn = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'";
|
||||
$sqlPartialCond = " AND " . $field . " IN (" . $sanitizedSqlIn . ")";
|
||||
return $sqlPartialCond;
|
||||
}
|
||||
|
||||
return '';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
/* Copyright (C) 2025 Open-Dsi <support@open-dsi.fr>
|
||||
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -53,9 +54,11 @@ class SelectField extends CommonSelectField
|
|||
|
||||
$moreCss = $this->getInputCss($fieldInfos, $moreCss);
|
||||
$moreAttrib = trim((string) $moreAttrib);
|
||||
if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib;
|
||||
if (empty($moreAttrib)) {
|
||||
$moreAttrib = ' ' . $moreAttrib;
|
||||
}
|
||||
$htmlName = $keyPrefix . $key . $keySuffix;
|
||||
$value = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value: array($value)));
|
||||
$value = $this->isEmptyValue($fieldInfos, $value) ? array() : (is_string($value) ? explode(',', $value) : (is_array($value) ? $value : array($value)));
|
||||
|
||||
$optionsList = array();
|
||||
$options = $this->getOptions($fieldInfos, $key);
|
||||
|
|
@ -82,9 +85,13 @@ class SelectField extends CommonSelectField
|
|||
{
|
||||
$moreCss = $this->getInputCss($fieldInfos, $moreCss);
|
||||
$moreAttrib = trim((string) $moreAttrib);
|
||||
if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib;
|
||||
if (empty($moreAttrib)) {
|
||||
$moreAttrib = ' ' . $moreAttrib;
|
||||
}
|
||||
$placeHolder = $fieldInfos->inputPlaceholder;
|
||||
if (!empty($placeHolder)) $placeHolder = ' placeholder="' . dolPrintHTMLForAttribute($placeHolder) . '"';
|
||||
if (!empty($placeHolder)) {
|
||||
$placeHolder = ' placeholder="' . dolPrintHTMLForAttribute($placeHolder) . '"';
|
||||
}
|
||||
$autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : '';
|
||||
$htmlName = $keyPrefix . $key . $keySuffix;
|
||||
|
||||
|
|
@ -248,8 +255,9 @@ class SelectField extends CommonSelectField
|
|||
$alias = $fieldInfos->sqlAlias ?? 't.';
|
||||
$field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key));
|
||||
|
||||
$tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'";
|
||||
return " AND " . $field . " IN (" . $this->db->sanitize($tmp, 1) . ")";
|
||||
$sanitizedSqlIn = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'";
|
||||
$sqlPartialCond = " AND " . $field . " IN (" . $sanitizedSqlIn . ")";
|
||||
return $sqlPartialCond;
|
||||
}
|
||||
|
||||
return '';
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
/* Copyright (C) 2025 Open-Dsi <support@open-dsi.fr>
|
||||
* Copyright (C) 2026 MDW <mdeweerd@users.noreply.github.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -53,7 +54,9 @@ class SellistField extends CommonSellistField
|
|||
|
||||
$moreCss = $this->getInputCss($fieldInfos, $moreCss);
|
||||
$moreAttrib = trim((string) $moreAttrib);
|
||||
if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib;
|
||||
if (empty($moreAttrib)) {
|
||||
$moreAttrib = ' ' . $moreAttrib;
|
||||
}
|
||||
$htmlName = $keyPrefix . $key . $keySuffix;
|
||||
|
||||
$optionsList = array();
|
||||
|
|
@ -83,9 +86,13 @@ class SellistField extends CommonSellistField
|
|||
|
||||
$moreCss = $this->getInputCss($fieldInfos, $moreCss);
|
||||
$moreAttrib = trim((string) $moreAttrib);
|
||||
if (empty($moreAttrib)) $moreAttrib = ' ' . $moreAttrib;
|
||||
if (empty($moreAttrib)) {
|
||||
$moreAttrib = ' ' . $moreAttrib;
|
||||
}
|
||||
$placeHolder = $fieldInfos->inputPlaceholder;
|
||||
if (!empty($placeHolder)) $placeHolder = ' placeholder="' . dolPrintHTMLForAttribute($placeHolder) . '"';
|
||||
if (!empty($placeHolder)) {
|
||||
$placeHolder = ' placeholder="' . dolPrintHTMLForAttribute($placeHolder) . '"';
|
||||
}
|
||||
$autoFocus = $fieldInfos->inputAutofocus ? ' autofocus' : '';
|
||||
$htmlName = $keyPrefix . $key . $keySuffix;
|
||||
$selectedValue = is_null($value) || $this->isEmptyValue($fieldInfos, $value) ? '' : (string) $value;
|
||||
|
|
@ -274,8 +281,9 @@ class SellistField extends CommonSellistField
|
|||
$alias = $fieldInfos->sqlAlias ?? 't.';
|
||||
$field = $this->db->sanitize($alias . ($fieldInfos->nameInTable ?? $key));
|
||||
|
||||
$tmp = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'";
|
||||
return " AND " . $field . " IN (" . $this->db->sanitize($tmp, 1) . ")";
|
||||
$sanitizedSqlIn = "'" . implode("','", array_map(array($this->db, 'escape'), $value)) . "'";
|
||||
$sqlPartialCond = " AND " . $field . " IN (" . $sanitizedSqlIn . ")";
|
||||
return $sqlPartialCond;
|
||||
}
|
||||
|
||||
return '';
|
||||
|
|
|
|||
Loading…
Reference in a new issue