Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fix XSS, prevent their storage
Use HTML purifier lib to sanitize preferences footer
  • Loading branch information
trasher committed Nov 9, 2021
1 parent 8e94064 commit 0d55bc7
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 21 deletions.
3 changes: 2 additions & 1 deletion galette/composer.json
Expand Up @@ -49,7 +49,8 @@
"php-di/slim-bridge": "2.0.0",
"doctrine/annotations": "^1.8",
"laminas/laminas-servicemanager": "3.7",
"symfony/polyfill-php80": "^1.23"
"symfony/polyfill-php80": "^1.23",
"ezyang/htmlpurifier": "^4.13"
},
"require-dev": {
"atoum/atoum": "dev-master",
Expand Down
56 changes: 55 additions & 1 deletion galette/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions galette/lib/Galette/Controllers/Crud/PaymentTypeController.php
Expand Up @@ -7,7 +7,7 @@
*
* PHP version 5
*
* Copyright © 2019-2020 The Galette Team
* Copyright © 2019-2021 The Galette Team
*
* This file is part of Galette (http://galette.tuxfamily.org).
*
Expand All @@ -28,7 +28,7 @@
* @package Galette
*
* @author Johan Cwiklinski <johan@x-tnd.be>
* @copyright 2019-2020 The Galette Team
* @copyright 2019-2021 The Galette Team
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
* @link http://galette.tuxfamily.org
* @since Available since 0.9.4dev - 2019-12-09
Expand All @@ -50,7 +50,7 @@
* @name PaymentTypeController
* @package Galette
* @author Johan Cwiklinski <johan@x-tnd.be>
* @copyright 2019-2020 The Galette Team
* @copyright 2019-2021 The Galette Team
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
* @link http://galette.tuxfamily.org
* @since Available since 0.9.4dev - 2019-12-09
Expand Down Expand Up @@ -205,7 +205,7 @@ public function store(Request $request, Response $response, int $id = null): Res
'error_detected',
preg_replace(
'(%s)',
$ptype->name,
$ptype->getName(),
_T("Payment type '%s' has not been added!")
)
);
Expand All @@ -214,7 +214,7 @@ public function store(Request $request, Response $response, int $id = null): Res
'error_detected',
preg_replace(
'(%s)',
$ptype->name,
$ptype->getName(),
_T("Payment type '%s' has not been modified!")
)
);
Expand All @@ -227,7 +227,7 @@ public function store(Request $request, Response $response, int $id = null): Res
'success_detected',
preg_replace(
'(%s)',
$ptype->name,
$ptype->getName(),
_T("Payment type '%s' has been successfully added.")
)
);
Expand All @@ -236,7 +236,7 @@ public function store(Request $request, Response $response, int $id = null): Res
'success_detected',
preg_replace(
'(%s)',
$ptype->name,
$ptype->getName(),
_T("Payment type '%s' has been successfully modified.")
)
);
Expand Down
20 changes: 20 additions & 0 deletions galette/lib/Galette/Core/Preferences.php
Expand Up @@ -755,6 +755,9 @@ public function validateValue($fieldname, $value)
$this->errors[] = _T("- Invalid year for cards.");
}
break;
case 'pref_footer':
$value = $this->cleanHtmlValue($value);
break;
}

return $value;
Expand Down Expand Up @@ -961,6 +964,8 @@ public function __get($name)
&& $name == 'pref_mail_method'
) {
return GaletteMail::METHOD_DISABLED;
} elseif ($name == 'pref_footer') {
return $this->cleanHtmlValue($this->prefs[$name]);
} else {
if ($name == 'pref_adhesion_form' && $this->prefs[$name] == '') {
$this->prefs[$name] = self::$defaults['pref_adhesion_form'];
Expand Down Expand Up @@ -1294,4 +1299,19 @@ public function setSocialReplacements(): self

return $this;
}

/**
* Purify HTML value
*
* @param string $value Value to clean
*
* @return string
*/
public function cleanHtmlValue(string $value): string
{
$config = \HTMLPurifier_Config::createDefault();
$config->set('Cache.SerializerPath', GALETTE_CACHE_DIR);
$purifier = new \HTMLPurifier($config);
return $purifier->purify($value);
}
}
2 changes: 2 additions & 0 deletions galette/lib/Galette/Entity/Entitled.php
Expand Up @@ -429,6 +429,7 @@ public function getIdByLabel($label)
public function add($label, $extra)
{
// Avoid duplicates.
$label = strip_tags($label);
$ret = $this->getIdByLabel($label);

if ($ret !== false) {
Expand Down Expand Up @@ -489,6 +490,7 @@ public function add($label, $extra)
*/
public function update($id, $label, $extra)
{
$label = strip_tags($label);
$ret = $this->get($id);
if (!$ret) {
/* get() already logged and set $this->error. */
Expand Down
4 changes: 2 additions & 2 deletions galette/lib/Galette/Entity/Title.php
Expand Up @@ -139,8 +139,8 @@ private function loadFromRs($rs)
public function store($zdb)
{
$data = array(
'short_label' => $this->short,
'long_label' => $this->long
'short_label' => strip_tags($this->short),
'long_label' => strip_tags($this->long)
);
try {
if ($this->id !== null && $this->id > 0) {
Expand Down
2 changes: 1 addition & 1 deletion galette/lib/Galette/Entity/Transaction.php
Expand Up @@ -357,7 +357,7 @@ public function check($values, $required, $disabled)
break;
case 'trans_desc':
/** TODO: retrieve field length from database and check that */
$this->_description = $value;
$this->_description = strip_tags($value);
if (mb_strlen($value) > 150) {
$this->errors[] = _T("- Transaction description must be 150 characters long maximum.");
}
Expand Down
6 changes: 3 additions & 3 deletions galette/templates/default/gestion_intitule_content.tpl
Expand Up @@ -57,7 +57,7 @@
{$eid}
<span class="row-title">
<a href="{path_for name="editEntitled" data=["class" => $url_class, "action" => "edit", "id" => $eid]}">
{_T string="%s field" pattern="/%s/" replace=$entry.name}
{_T string="%s field" pattern="/%s/" replace=$entry.name|escape}
</a>
</span>
</td>
Expand Down Expand Up @@ -89,14 +89,14 @@
class="action tooltip"
>
<i class="fas fa-edit fa-fw"></i>
<span class="sr-only">{_T string="Edit '%s' field" pattern="/%s/" replace=$entry.name}</span>
<span class="sr-only">{_T string="Edit '%s' field" pattern="/%s/" replace=$entry.name|escape}</span>
</a>
<a
href="{path_for name="removeEntitled" data=["class" => $url_class, "id" => $eid]}"
class="delete tooltip"
>
<i class="fas fa-trash fa-fw"></i>
<span class="sr-only">{_T string="Delete '%s' field" pattern="/%s/" replace=$entry.name}</span>
<span class="sr-only">{_T string="Delete '%s' field" pattern="/%s/" replace=$entry.name|escape}</span>
</a>
</td>
</tr>
Expand Down
10 changes: 5 additions & 5 deletions galette/templates/default/gestion_titres.tpl
Expand Up @@ -44,19 +44,19 @@
{/if}
<span class="row-title">
<a href="{path_for name="editTitle" data=["id" => $title->id]}">
{_T string="%s title" pattern="/%s/" replace=$title->short}
{_T string="%s title" pattern="/%s/" replace=$title->short|escape}
</a>
</span>
</td>
<td class="left" data-title="{_T string="Short form"}">{$title->short}</td>
<td class="left" data-title="{_T string="Long form"}">{$title->long}</td>
<td class="left" data-title="{_T string="Short form"}">{$title->short|escape}</td>
<td class="left" data-title="{_T string="Long form"}">{$title->long|escape}</td>
<td class="center actions_row">
<a
href="{path_for name="editTitle" data=["id" => $title->id]}"
class="tooltip action"
>
<i class="fas fa-edit fa-fw"></i>
<span class="sr-only">{_T string="Edit '%s' title" pattern="/%s/" replace=$title->short}</span>
<span class="sr-only">{_T string="Edit '%s' title" pattern="/%s/" replace=$title->short|escape}</span>
</a>
{if $title->id eq 1 or $title->id eq 2}
<img src="{base_url}/{$template_subdir}images/icon-empty.png" alt="" width="16px" height="16px"/>
Expand All @@ -66,7 +66,7 @@
class="delete tooltip"
>
<i class="fa fa-trash fa-fw"></i>
<span class="sr-only">{_T string="Delete '%s' title" pattern="/%s/" replace=$title->short}</span>
<span class="sr-only">{_T string="Delete '%s' title" pattern="/%s/" replace=$title->short|escape}</span>
</a>
{/if}
</td>
Expand Down
2 changes: 1 addition & 1 deletion galette/templates/default/gestion_transactions.tpl
Expand Up @@ -150,7 +150,7 @@
</a>
</td>
{/if}
<td class="{$cclass} nowrap" data-title="{_T string="Description"}">{$transaction->description}</td>
<td class="{$cclass} nowrap" data-title="{_T string="Description"}">{$transaction->description|escape}</td>
{if $login->isAdmin() or $login->isStaff()}
<td class="{$cclass}" data-title="{_T string="Originator"}">
{if $filters->filtre_cotis_adh eq ""}
Expand Down

0 comments on commit 0d55bc7

Please sign in to comment.