diff --git a/README.md b/README.md index 3553401..41807e1 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ DISCLAIMER: There may not be any net benefit to using FormFormer (FF) for most a FormFormer forms HTML/HTML5 forms. It is decoupled from submission processing and validation. An $errorMessage string can be passed to field constructors and/or form constructor for error display. (Some of the included examples do demonstrate minimal processing and validation techniques.) -The goal was simple yet flexible code. Using immutable objects for all classes except FieldBuilder (optionally makes field instantiation less verbose) helps maintain simplicity. Flexibility is provided by incorporating general $attributes array properties into Form and Field classes, requiring the client to have knowledge of HTML attributes and also potentially outputting invalid HTML, as most attributes are not validated. +The goal was simple yet flexible code. Using immutable objects for all classes, except FieldBuilder (which optionally makes field instantiation less verbose), helps maintain simplicity. Flexibility is provided by incorporating general $attributes array properties into Form and Field classes, requiring the client to have knowledge of HTML attributes and also potentially outputting invalid HTML, as most attributes are not validated. There are certainly complexities which FF does not handle, especially related to formatting. It can be extended and/or adapted over time to handle some, and simply not used for others. @@ -13,7 +13,13 @@ INSTALLATION or add "it-all/form-former": "^2.0" to composer.json and run composer update SECURITY -Since FormFormer is limited to forming forms, rather than receiving, filtering, or validating data, there is little to no security implemented in the source code (/src). There is some minimal security in /examples/init.inc in terms of escaping user input data that will potentially be displayed in HTML (in the case of a validation error). Minimal validation is performed in the examples. For a good php validator package, please see https://github.com/vlucas/valitron. +Since FormFormer is limited to forming forms, rather than receiving, filtering, or validating data, there is little security implemented in the source code (/src). In order to prevent XSS, the htmlentities function (https://www.php.net/htmlentities) is used when outputting html element attribute values (which may contain user input if client code validates input and repopulates for failures) and html element content values (for example <textarea>escaped content</textarea>). + +Minimal validation is performed in the examples. + +For a good php validator package, please see https://github.com/vlucas/valitron. + +Further reference: https://www.martinfowler.com/articles/web-security-basics.html https://stackoverflow.com/questions/129677/whats-the-best-method-for-sanitizing-user-input-with-php#130323 https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet#File_uploads diff --git a/examples/init.inc b/examples/init.inc index 45809c1..83cface 100644 --- a/examples/init.inc +++ b/examples/init.inc @@ -2,14 +2,4 @@ declare(strict_types=1); require('../vendor/autoload.php'); - -// minimal security to escape user input -foreach ($_POST as $key => $val) { - $_POST[$key] = htmlspecialchars($val); -} - -foreach ($_GET as $key => $val) { - $_GET[$key] = htmlspecialchars($val); -} - require('Template.php'); diff --git a/src/UserInterfaceHelper.php b/src/UserInterfaceHelper.php index 0ccc7a4..9de7e07 100644 --- a/src/UserInterfaceHelper.php +++ b/src/UserInterfaceHelper.php @@ -9,7 +9,9 @@ public static function generateElementAttributes(array $attributes): string { $attributesString = ''; foreach ($attributes as $aKey => $aValue) { - $attributesString .= ' '.$aKey.'="'.$aValue.'"'; + $attributeName = strtolower($aKey); + $attributeValue = htmlentities($aValue, ENT_QUOTES | ENT_HTML5); + $attributesString .= " $attributeName=\"$attributeValue\""; } return $attributesString; @@ -23,7 +25,7 @@ public static function generateElement(string $name, array $attributes, bool $cl $html = '<'.$name.self::generateElementAttributes($attributes).'>'; if ($close) { - $html .= $content.''; + $html .= htmlentities($content, ENT_QUOTES | ENT_HTML5).''; } return $html; }