Commit ba817c0e authored by Carsten  Rose's avatar Carsten Rose
Browse files

Implemented new escape class 'mysql' (realEscapeString).

Implemented defaultEscapeType. configurable via config.qfq.ini (global) and per Form.
Implemented max GET parameter lenght. Default: 50. BTW: in phpunit test there have been a parameter 'file' which exceeds the limit of 32.

Config.qfq: Skip empty variable names - happens in phpunit tests. Read new `systemEscapeTypeDefault`.
Constants.php: renamed  TOKEN_LDAP_ESCAPE_* to TOKEN_ESCAPE_LDAP_*. Add TOKEN_ESCAPE_MYSQL, TOKEN_ESCAPE_NONE
Database.php: Set charset to real_escape_string() functions properly. Proxy for mysqli::real_escape_string()
Evaluate.php: Respect global escapeTypeDefault. Implement
formEditor.sql: add column `escapeTypeDefault`. Add FormElement 'escapeTypeDefault'.
parent cb2784bd
...@@ -245,6 +245,14 @@ config.qfq.ini ...@@ -245,6 +245,14 @@ config.qfq.ini
+-----------------------------+-------------------------------------------------+ crendentials is supported. | +-----------------------------+-------------------------------------------------+ crendentials is supported. |
| LDAP_1_PASSWORD | LDAP_1_PASSWORD=mySecurePassword | | | LDAP_1_PASSWORD | LDAP_1_PASSWORD=mySecurePassword | |
+-----------------------------+-------------------------------------------------+----------------------------------------------------------------------------+ +-----------------------------+-------------------------------------------------+----------------------------------------------------------------------------+
| SECURITY_VARS_HONEYPOT | SECURITY_VARS_HONEYPOT = email,username,password| If empty: no check. All named variables will rendered as INPUT elements |
+-----------------------------+-------------------------------------------------+----------------------------------------------------------------------------+
| SECURITY_ATTACK_DELAY | SECURITY_ATTACK_DELAY = 5 | If an attack is detected, sleep 'x' seconds and exit PHP process |
+-----------------------------+-------------------------------------------------+----------------------------------------------------------------------------+
| SECURITY_SHOW_MESSAGE | SECURITY_SHOW_MESSAGE = true | If an attack is detected, show a message |
+-----------------------------+-------------------------------------------------+----------------------------------------------------------------------------+
| SECURITY_GET_MAX_LENGTH | SECURITY_GET_MAX_LENGTH = 32 | Check that there are no GET vars longer than 'x' chars |
+-----------------------------+-------------------------------------------------+----------------------------------------------------------------------------+
Example: *typo3conf/config.qfq.ini* Example: *typo3conf/config.qfq.ini*
...@@ -278,6 +286,10 @@ Example: *typo3conf/config.qfq.ini* ...@@ -278,6 +286,10 @@ Example: *typo3conf/config.qfq.ini*
;EDIT_FORM_PAGE = form ;EDIT_FORM_PAGE = form
;LDAP_1_RDN='ou=Admin,dc=example,dc=com' ;LDAP_1_RDN='ou=Admin,dc=example,dc=com'
;LDAP_1_PASSWORD=mySecurePassword ;LDAP_1_PASSWORD=mySecurePassword
;SECURITY_VARS_HONEYPOT=email,username,password
;SECURITY_ATTACK_DELAY=5
;SECURITY_SHOW_MESSAGE=true
;SECURITY_GET_MAX_LENGTH=32
.. _local-documentation: .. _local-documentation:
...@@ -507,8 +519,13 @@ All values passed to QFQ will be: ...@@ -507,8 +519,13 @@ All values passed to QFQ will be:
Get Parameter Get Parameter
------------- -------------
Get parameter might contain urlencoded content (%xx). 'urldDecode' all GET parameter. GET parameter might contain urlencoded content (%xx). 'urldDecode' all GET parameter.
The string length of GET parameter is limited on SECURITY_GET_MAX_LENGTH chars (see `config.qfq.ini`_)
**QFQ security restiction**:
* '%nn' in GET variables will always be decoded. It's not possible to transfer '%nn' itself.
* GET variables are limited to SECURITY_GET_MAX_LENGTH chars - any violation will break QFQ.
Post Parameter Post Parameter
-------------- --------------
...@@ -520,15 +537,26 @@ required, the encoding can be disabled per FormElement. During Form load, the ht ...@@ -520,15 +537,26 @@ required, the encoding can be disabled per FormElement. During Form load, the ht
$_SERVER $_SERVER
-------- --------
All $_SERVER vars are htmlentities (all, not only specialchars) encoded. All $_SERVER vars are htmlentities (all, not only specialchars!) encoded.
Honeypot Honeypot
-------- --------
Every QFQ Form contains 'honeypot'-HTML input elements (hidden & readonly). Which to use is configured in `config.qfq.ini`_ Every QFQ Form contains 'honeypot'-HTML input elements (hidden & readonly). Which to use is configured in `config.qfq.ini`_
(default: 'username', 'password' and 'email'). Independet of the QFQ Form, on every start of QFQ these variables are (default: 'username', 'password' and 'email'). Independet of the QFQ Form, on every start of QFQ, these variables are
tested if they are non-empty and if 'yes', QFQ will sleep <x> seconds and than exit the running PHP process (prevent tested if they are non-empty.
brute force attacks) - an detected attack leads to a complete white (=empty) page. By default an error message is displayed.
**QFQ security restiction**:
* The honeypot variables can't be used in GET or POST as regular HTML input elements - any use of it will break QFQ.
Violation
---------
On any violation, QFQ will sleep SYSTEM_SECURITY_ATTACK_DELAY seconds (`config.qfq.ini`_) and than exit the running PHP process.
A detected attack leads to a complete white (=empty) page.
If SECURITY_SHOW_MESSAGE == true (`config.qfq.ini`_), a message is displayed.
SIP SIP
--- ---
......
...@@ -54,6 +54,10 @@ WKHTMLTOPDF = /opt/wkhtmltox/bin/wkhtmltopdf ...@@ -54,6 +54,10 @@ WKHTMLTOPDF = /opt/wkhtmltox/bin/wkhtmltopdf
;LDAP_1_RDN = ;LDAP_1_RDN =
;LDAP_1_PASSWORD = ;LDAP_1_PASSWORD =
;ESCAPE_TYPE_DEFAULT=s
;SECURITY_VARS_HONEYPOT=email,username,password ;SECURITY_VARS_HONEYPOT=email,username,password
;SECURITY_ATTACK_DELAY=5 ;SECURITY_ATTACK_DELAY=5
;SECURITY_SHOW_MESSAGE=true ;SECURITY_SHOW_MESSAGE=true
\ No newline at end of file ;SECURITY_GET_MAX_LENGTH=50
...@@ -291,6 +291,10 @@ abstract class AbstractBuildForm { ...@@ -291,6 +291,10 @@ abstract class AbstractBuildForm {
// Iterate over all fake vars // Iterate over all fake vars
$arr = explode(',', $vars); $arr = explode(',', $vars);
foreach ($arr as $name) { foreach ($arr as $name) {
$name = trim($name);
if ($name === '') {
continue;
}
$html .= "<input name='$name' type='hidden' value='' readonly>"; $html .= "<input name='$name' type='hidden' value='' readonly>";
} }
......
...@@ -233,6 +233,7 @@ const ERROR_DB_UNKNOWN_COLUMN = 2011; ...@@ -233,6 +233,7 @@ const ERROR_DB_UNKNOWN_COLUMN = 2011;
const ERROR_DB_UNKNOWN_COMMAND = 2012; const ERROR_DB_UNKNOWN_COMMAND = 2012;
const ERROR_DB_MISSING_COLUMN_ID = 2013; const ERROR_DB_MISSING_COLUMN_ID = 2013;
const ERROR_DB_COLUMN_NOT_FOUND_IN_TABLE = 2014; const ERROR_DB_COLUMN_NOT_FOUND_IN_TABLE = 2014;
const ERROR_DB_SET_CHARSET = 2015;
// onArray // onArray
const ERROR_SUBSTITUTE_FOUND = 2100; const ERROR_SUBSTITUTE_FOUND = 2100;
...@@ -350,6 +351,16 @@ const SYSTEM_EDIT_FORM_PAGE = 'EDIT_FORM_PAGE'; ...@@ -350,6 +351,16 @@ const SYSTEM_EDIT_FORM_PAGE = 'EDIT_FORM_PAGE';
const SYSTEM_PATH_EXT = 'EXT_PATH'; const SYSTEM_PATH_EXT = 'EXT_PATH';
const SYSTEM_SITE_PATH = 'SITE_PATH'; const SYSTEM_SITE_PATH = 'SITE_PATH';
const SYSTEM_LDAP_1_RDN = 'LDAP_1_RDN'; // Credentials to access LDAP
const SYSTEM_LDAP_1_PASSWORD = 'LDAP_1_PASSWORD'; // Credentials to access LDAP
const SYSTEM_ESCAPE_TYPE_DEFAULT = 'ESCAPE_TYPE_DEFAULT';
const SYSTEM_SECURITY_VARS_HONEYPOT = 'SECURITY_VARS_HONEYPOT'; // Fake variables
const SYSTEM_SECURITY_ATTACK_DELAY = 'SECURITY_ATTACK_DELAY'; // Detected attack causes x seconds delay
const SYSTEM_SECURITY_SHOW_MESSAGE = 'SECURITY_SHOW_MESSAGE'; // Detected attack shows an error message
const SYSTEM_SECURITY_GET_MAX_LENGTH = 'SECURITY_GET_MAX_LENGTH'; // Trim every character (before conversion) to SECURITY_GET_MAX_LENGTH chars;
// Not stored in config.qfq.ini, but used in STORE_SYSTEM
// Information for: Log / Debug / Exception // Information for: Log / Debug / Exception
const SYSTEM_SQL_RAW = 'sqlRaw'; // Type: SANITIZE_ALL / String. SQL Query (before substitute). Useful for error reporting. const SYSTEM_SQL_RAW = 'sqlRaw'; // Type: SANITIZE_ALL / String. SQL Query (before substitute). Useful for error reporting.
const SYSTEM_SQL_FINAL = 'sqlFinal'; // Type: SANITIZE_ALL / String. SQL Query (after substitute). Useful for error reporting. const SYSTEM_SQL_FINAL = 'sqlFinal'; // Type: SANITIZE_ALL / String. SQL Query (after substitute). Useful for error reporting.
...@@ -363,15 +374,6 @@ const SYSTEM_REPORT_COLUMN_INDEX = 'reportColumnIndex'; // Keyname of SQL-column ...@@ -363,15 +374,6 @@ const SYSTEM_REPORT_COLUMN_INDEX = 'reportColumnIndex'; // Keyname of SQL-column
const SYSTEM_REPORT_COLUMN_NAME = 'reportColumnName'; // Keyname of SQL-column processed at the moment. const SYSTEM_REPORT_COLUMN_NAME = 'reportColumnName'; // Keyname of SQL-column processed at the moment.
const SYSTEM_REPORT_COLUMN_VALUE = 'reportColumnValue'; // Keyname of SQL-column processed at the moment. const SYSTEM_REPORT_COLUMN_VALUE = 'reportColumnValue'; // Keyname of SQL-column processed at the moment.
const SYSTEM_REPORT_FULL_LEVEL = 'reportFullLevel'; // Keyname of SQL-column processed at the moment. const SYSTEM_REPORT_FULL_LEVEL = 'reportFullLevel'; // Keyname of SQL-column processed at the moment.
const SYSTEM_LDAP_1_RDN = 'LDAP_1_RDN'; // Credentials to access LDAP
const SYSTEM_LDAP_1_PASSWORD = 'LDAP_1_PASSWORD'; // Credentials to access LDAP
const SYSTEM_SECURITY_VARS_HONEYPOT = 'SECURITY_VARS_HONEYPOT'; // Fake variables
const SYSTEM_SECURITY_ATTACK_DELAY = 'SECURITY_ATTACK_DELAY'; // Fake variables
const SYSTEM_SECURITY_SHOW_MESSAGE = 'SECURITY_SHOW_MESSAGE'; // Fake variables
// Not stored in config.qfq.ini, but used in STORE_SYSTEM
const SYSTEM_DOWNLOAD_POPUP = 'hasDownloadPopup'; // Marker which is set to 'true' if there is at least one Download Link rendered const SYSTEM_DOWNLOAD_POPUP = 'hasDownloadPopup'; // Marker which is set to 'true' if there is at least one Download Link rendered
const DOWNLOAD_POPUP_REQUEST = 'true'; const DOWNLOAD_POPUP_REQUEST = 'true';
...@@ -432,8 +434,10 @@ const DOUBLE_TICK = '"'; ...@@ -432,8 +434,10 @@ const DOUBLE_TICK = '"';
// TOKEN evaluate // TOKEN evaluate
const TOKEN_ESCAPE_SINGLE_TICK = 's'; const TOKEN_ESCAPE_SINGLE_TICK = 's';
const TOKEN_ESCAPE_DOUBLE_TICK = 'd'; const TOKEN_ESCAPE_DOUBLE_TICK = 'd';
const TOKEN_LDAP_ESCAPE_FILTER = 'l'; const TOKEN_ESCAPE_LDAP_FILTER = 'l';
const TOKEN_LDAP_ESCAPE_DN = 'L'; const TOKEN_ESCAPE_LDAP_DN = 'L';
const TOKEN_ESCAPE_MYSQL = 'm';
const TOKEN_ESCAPE_NONE = '-';
// Workaround for PHP < 5.6.0 // Workaround for PHP < 5.6.0
if (!function_exists('ldap_escape')) { if (!function_exists('ldap_escape')) {
...@@ -584,6 +588,8 @@ const F_FINAL_DELETE_FORM = 'finalDeleteForm'; ...@@ -584,6 +588,8 @@ const F_FINAL_DELETE_FORM = 'finalDeleteForm';
const F_SUBMIT_BUTTON_TEXT = 'submitButtonText'; const F_SUBMIT_BUTTON_TEXT = 'submitButtonText';
const F_BUTTON_ON_CHANGE_CLASS = 'buttonOnChangeClass'; const F_BUTTON_ON_CHANGE_CLASS = 'buttonOnChangeClass';
const F_ESCAPE_TYPE_DEFAULT = 'escapeTypeDefault';
const F_CLASS = 'class'; const F_CLASS = 'class';
const F_CLASS_PILL = 'classPill'; const F_CLASS_PILL = 'classPill';
const F_CLASS_BODY = 'classBody'; const F_CLASS_BODY = 'classBody';
......
...@@ -107,6 +107,11 @@ class Database { ...@@ -107,6 +107,11 @@ class Database {
throw new UserFormException ("Error open Database 'mysql:host=" . $config[SYSTEM_DB_SERVER] . ";dbname=" . $config[SYSTEM_DB_NAME] . ";dbuser=" . $config[SYSTEM_DB_USER] . "'': " . $mysqli->connect_errno . PHP_EOL . $mysqli->connect_error, ERROR_DB_OPEN); throw new UserFormException ("Error open Database 'mysql:host=" . $config[SYSTEM_DB_SERVER] . ";dbname=" . $config[SYSTEM_DB_NAME] . ";dbuser=" . $config[SYSTEM_DB_USER] . "'': " . $mysqli->connect_errno . PHP_EOL . $mysqli->connect_error, ERROR_DB_OPEN);
} }
// Necessary that mysqli::real_escape_string() functions properly.
if (!$mysqli->set_charset('utf8')) {
throw new UserFormException ("Error set_charset('utf8') Database: " . $mysqli->connect_errno . PHP_EOL . $mysqli->connect_error, ERROR_DB_SET_CHARSET);
}
return $mysqli; return $mysqli;
} }
...@@ -738,4 +743,14 @@ class Database { ...@@ -738,4 +743,14 @@ class Database {
return $new; return $new;
} }
/**
* Proxy for mysqli::real_escape_string()
*
* @param string $value
* @return string
*/
public function realEscapeString($value) {
return $this->mysqli->real_escape_string($value);
}
} }
\ No newline at end of file
...@@ -20,13 +20,21 @@ require_once(__DIR__ . '/helper/Support.php'); ...@@ -20,13 +20,21 @@ require_once(__DIR__ . '/helper/Support.php');
* @package qfq * @package qfq
*/ */
class Evaluate { class Evaluate {
/**
* @var Store
*/
private $store = null; private $store = null;
/**
* @var Database
*/
private $db = null; private $db = null;
private $startDelimiter = ''; private $startDelimiter = '';
private $startDelimiterLength = 0; private $startDelimiterLength = 0;
private $endDelimiter = ''; private $endDelimiter = '';
private $endDelimiterLength = 0; private $endDelimiterLength = 0;
private $sqlKeywords = array('SELECT ', 'INSERT ', 'DELETE ', 'UPDATE ', 'SHOW '); private $sqlKeywords = array('SELECT ', 'INSERT ', 'DELETE ', 'UPDATE ', 'SHOW ');
private $escapeTypeDefault = '';
// private $debugStack = array(); // private $debugStack = array();
...@@ -44,6 +52,7 @@ class Evaluate { ...@@ -44,6 +52,7 @@ class Evaluate {
$this->startDelimiterLength = strlen($startDelimiter); $this->startDelimiterLength = strlen($startDelimiter);
$this->endDelimiter = $endDelimiter; $this->endDelimiter = $endDelimiter;
$this->endDelimiterLength = strlen($endDelimiter); $this->endDelimiterLength = strlen($endDelimiter);
$this->escapeTypeDefault = $this->store->getVar(F_ESCAPE_TYPE_DEFAULT, STORE_SYSTEM);
} }
/** /**
...@@ -174,6 +183,7 @@ class Evaluate { ...@@ -174,6 +183,7 @@ class Evaluate {
* @return array|null|string * @return array|null|string
* @throws CodeException * @throws CodeException
* @throws DbException * @throws DbException
* @throws UserFormException
*/ */
public function substitute($token, &$foundInStore = '') { public function substitute($token, &$foundInStore = '') {
$sqlMode = ROW_IMPLODE_ALL; $sqlMode = ROW_IMPLODE_ALL;
...@@ -198,6 +208,10 @@ class Evaluate { ...@@ -198,6 +208,10 @@ class Evaluate {
// explode for: <key>:<store priority>:<sanitize class>:<escape> // explode for: <key>:<store priority>:<sanitize class>:<escape>
$arr = explode(':', $token, 4); $arr = explode(':', $token, 4);
$arr = array_merge($arr, [null, null, null, null]); // fake isset() $arr = array_merge($arr, [null, null, null, null]); // fake isset()
$escapeTypes = $arr[3];
if ($escapeTypes == '') {
$escapeTypes = $this->escapeTypeDefault;
}
// search for value in stores // search for value in stores
$value = $this->store->getVar($arr[0], $arr[1], $arr[2], $foundInStore); $value = $this->store->getVar($arr[0], $arr[1], $arr[2], $foundInStore);
...@@ -206,7 +220,7 @@ class Evaluate { ...@@ -206,7 +220,7 @@ class Evaluate {
if (is_string($value)) { if (is_string($value)) {
// Process all escape requests in the given order. // Process all escape requests in the given order.
for ($ii = 0; $ii < strlen($arr[3]); $ii++) { for ($ii = 0; $ii < strlen($arr[3]); $ii++) {
$escape = $arr[3][$ii]; $escape = $escapeTypes[$ii];
switch ($escape) { switch ($escape) {
case TOKEN_ESCAPE_SINGLE_TICK: case TOKEN_ESCAPE_SINGLE_TICK:
$value = str_replace("'", "\\'", $value); $value = str_replace("'", "\\'", $value);
...@@ -214,13 +228,19 @@ class Evaluate { ...@@ -214,13 +228,19 @@ class Evaluate {
case TOKEN_ESCAPE_DOUBLE_TICK: case TOKEN_ESCAPE_DOUBLE_TICK:
$value = str_replace('"', '\\"', $value); $value = str_replace('"', '\\"', $value);
break; break;
case TOKEN_LDAP_ESCAPE_FILTER: case TOKEN_ESCAPE_LDAP_FILTER:
$value = Support::ldap_escape($value, null, LDAP_ESCAPE_FILTER); $value = Support::ldap_escape($value, null, LDAP_ESCAPE_FILTER);
break; break;
case TOKEN_LDAP_ESCAPE_DN: case TOKEN_ESCAPE_LDAP_DN:
$value = Support::ldap_escape($value, null, LDAP_ESCAPE_DN); $value = Support::ldap_escape($value, null, LDAP_ESCAPE_DN);
break; break;
case TOKEN_ESCAPE_MYSQL:
$value = $this->db->realEscapeString($value);
break;
case TOKEN_ESCAPE_NONE: // do nothing
break;
default: default:
throw new UserFormException("Unknown Escape qualifier: $escape", UNKNOWN_TYPE);
break; break;
} }
} }
......
...@@ -634,11 +634,12 @@ class QuickFormQuery { ...@@ -634,11 +634,12 @@ class QuickFormQuery {
F_CLASS_PILL, F_CLASS_PILL,
F_CLASS_BODY, F_CLASS_BODY,
F_BUTTON_ON_CHANGE_CLASS, F_BUTTON_ON_CHANGE_CLASS,
F_ESCAPE_TYPE_DEFAULT,
]; ];
// By definition: existing vars which are empty, means: EMPTY - do not use any default! // By definition: existing vars which are empty, means: EMPTY - do not use any default!
// But: if these variables are table columns, they always exist. For those: empty value means 'not set' - unset those. // But: if these variables are table columns, they always exist. For those: empty value means 'not set' - unset those.
foreach ([F_BS_LABEL_COLUMNS, F_BS_INPUT_COLUMNS, F_BS_NOTE_COLUMNS] as $key) { foreach ([F_BS_LABEL_COLUMNS, F_BS_INPUT_COLUMNS, F_BS_NOTE_COLUMNS, F_ESCAPE_TYPE_DEFAULT] as $key) {
if ($formSpec[$key] == '') { if ($formSpec[$key] == '') {
unset ($formSpec[$key]); unset ($formSpec[$key]);
} }
...@@ -675,6 +676,10 @@ class QuickFormQuery { ...@@ -675,6 +676,10 @@ class QuickFormQuery {
$formSpec[F_SUBMIT_BUTTON_TEXT] = ''; $formSpec[F_SUBMIT_BUTTON_TEXT] = '';
} }
if ($formSpec[F_ESCAPE_TYPE_DEFAULT] == '') {
$formSpec[F_ESCAPE_TYPE_DEFAULT] = $this->store->getVar(F_ESCAPE_TYPE_DEFAULT, STORE_SYSTEM);
}
return $formSpec; return $formSpec;
} }
......
...@@ -52,18 +52,32 @@ class Config { ...@@ -52,18 +52,32 @@ class Config {
* @param array $config * @param array $config
*/ */
private static function checkForAttack(array $config) { private static function checkForAttack(array $config) {
$flag = false; $attack = false;
// Iterate over all fake vars // Iterate over all fake vars
$arr = explode(',', $config[SYSTEM_SECURITY_VARS_HONEYPOT]); $arr = explode(',', $config[SYSTEM_SECURITY_VARS_HONEYPOT]);
foreach ($arr as $key) { foreach ($arr as $key) {
$key = trim($key);
if ($key === '') {
continue;
}
if (!empty($_POST[$key]) || !empty($_GET[$key])) { if (!empty($_POST[$key]) || !empty($_GET[$key])) {
$flag = true; $attack = true;
}
}
// Limit length of all get vars: protect against SQL injection based on long ...%34%34%24%34...
$maxLength = $config[SYSTEM_SECURITY_GET_MAX_LENGTH];
if ($maxLength > 0) {
foreach ($_GET as $value) {
if (strlen($value) > $maxLength) {
$attack = true;
}
} }
} }
// Nothing found? // Nothing found?
if (!$flag) { if ($attack === false) {
return; return;
} }
...@@ -72,7 +86,7 @@ class Config { ...@@ -72,7 +86,7 @@ class Config {
sleep($config[SYSTEM_SECURITY_ATTACK_DELAY]); sleep($config[SYSTEM_SECURITY_ATTACK_DELAY]);
} }
if ($config[SYSTEM_SECURITY_SHOW_MESSAGE] == 'true') { if ($config[SYSTEM_SECURITY_SHOW_MESSAGE] == 'true' || $config[SYSTEM_SECURITY_SHOW_MESSAGE] == 1) {
echo "Attack detected - stop process"; echo "Attack detected - stop process";
} }
...@@ -98,6 +112,8 @@ class Config { ...@@ -98,6 +112,8 @@ class Config {
Support::setIfNotSet($config, SYSTEM_SECURITY_VARS_HONEYPOT, 'email,username,password'); Support::setIfNotSet($config, SYSTEM_SECURITY_VARS_HONEYPOT, 'email,username,password');
Support::setIfNotSet($config, SYSTEM_SECURITY_ATTACK_DELAY, '5'); Support::setIfNotSet($config, SYSTEM_SECURITY_ATTACK_DELAY, '5');
Support::setIfNotSet($config, SYSTEM_SECURITY_SHOW_MESSAGE, 'true'); Support::setIfNotSet($config, SYSTEM_SECURITY_SHOW_MESSAGE, 'true');
Support::setIfNotSet($config, SYSTEM_SECURITY_GET_MAX_LENGTH, '50');
Support::setIfNotSet($config, SYSTEM_ESCAPE_TYPE_DEFAULT, TOKEN_ESCAPE_SINGLE_TICK);
return $config; return $config;
} }
...@@ -125,6 +141,7 @@ class Config { ...@@ -125,6 +141,7 @@ class Config {
[SYSTEM_CSS_CLASS_QFQ_FORM_PILL, F_CLASS_PILL], [SYSTEM_CSS_CLASS_QFQ_FORM_PILL, F_CLASS_PILL],
[SYSTEM_CSS_CLASS_QFQ_FORM_BODY, F_CLASS_BODY], [SYSTEM_CSS_CLASS_QFQ_FORM_BODY, F_CLASS_BODY],
[SYSTEM_FORM_BUTTON_ON_CHANGE_CLASS, F_BUTTON_ON_CHANGE_CLASS], [SYSTEM_FORM_BUTTON_ON_CHANGE_CLASS, F_BUTTON_ON_CHANGE_CLASS],
[SYSTEM_ESCAPE_TYPE_DEFAULT, F_ESCAPE_TYPE_DEFAULT],
]; ];
foreach ($setting as $row) { foreach ($setting as $row) {
......
...@@ -9,7 +9,8 @@ CREATE TABLE IF NOT EXISTS `Form` ( ...@@ -9,7 +9,8 @@ CREATE TABLE IF NOT EXISTS `Form` (
`permitNew` ENUM('sip', 'logged_in', 'logged_out', 'always', 'never') NOT NULL DEFAULT 'sip', `permitNew` ENUM('sip', 'logged_in', 'logged_out', 'always', 'never') NOT NULL DEFAULT 'sip',
`permitEdit` ENUM('sip', 'logged_in', 'logged_out', 'always', 'never') NOT NULL DEFAULT 'sip', `permitEdit` ENUM('sip', 'logged_in', 'logged_out', 'always', 'never') NOT NULL DEFAULT 'sip',
`render` ENUM('bootstrap', 'table', 'plain') NOT NULL DEFAULT 'bootstrap', `escapeTypeDefault` ENUM('', 's', 'd', 'l', 'L', 'm', '-') NOT NULL DEFAULT 's',
`render` ENUM('bootstrap', 'table', 'plain') NOT NULL DEFAULT 'bootstrap',
`requiredParameter` VARCHAR(255) NOT NULL DEFAULT '', `requiredParameter` VARCHAR(255) NOT NULL DEFAULT '',
`showButton` SET('new', 'delete', 'close', 'save') NOT NULL DEFAULT 'new,delete,close,save', `showButton` SET('new', 'delete', 'close', 'save') NOT NULL DEFAULT 'new,delete,close,save',
`multiMode` ENUM('none', 'horizontal', 'vertical') NOT NULL DEFAULT 'none', `multiMode` ENUM('none', 'horizontal', 'vertical') NOT NULL DEFAULT 'none',
...@@ -27,7 +28,7 @@ CREATE TABLE IF NOT EXISTS `Form` ( ...@@ -27,7 +28,7 @@ CREATE TABLE IF NOT EXISTS `Form` (
`parameter` TEXT NOT NULL, `parameter` TEXT NOT NULL,
`deleted` ENUM('yes', 'no') NOT NULL DEFAULT 'no', `deleted` ENUM('yes', 'no') NOT NULL DEFAULT 'no',
`modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `modified` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', `created` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
...@@ -164,8 +165,9 @@ VALUES ...@@ -164,8 +165,9 @@ VALUES
(1, 'requiredParameter', 'Required Parameter', 'show', 'text', 'all', 'native', 200, 0, 0, '', '', '', '', '', 2, '', '', '', 'specialchar'), (1, 'requiredParameter', 'Required Parameter', 'show', 'text', 'all', 'native', 200, 0, 0, '', '', '', '', '', 2, '', '', '', 'specialchar'),
(1, 'permitNew', 'Permit New', 'show', 'radio', 'all', 'native', 210, 0, 10, '', '', '', '', '', 2, '', '', '', 'specialchar'), (1, 'permitNew', 'Permit New', 'show', 'radio', 'all', 'native', 210, 0, 10, '', '', '', '', '', 2, '', '', '', 'specialchar'),
(1, 'permitEdit', 'Permit Edit', 'show', 'radio', 'all', 'native', 220, 0, 10, '', '', '', '', '', 2, '', '', '', 'specialchar'), (1, 'permitEdit', 'Permit Edit', 'show', 'radio', 'all', 'native', 220, 0, 10, '', '', '', '', '', 2, '', '', '', 'specialchar'),
(1, 'render', 'Render', 'show', 'radio', 'all', 'native', 230, 0, 3, '', '', '', '', '', 2, '', '', '', 'specialchar'), (1, 'escapeTypeDefault', 'Escape type default', 'show', 'radio', 'all', 'native', 230, 0, 10, '', '', '', '', '', 2, '', '', '', 'specialchar'),
(1, 'showButton', 'Show button', 'show', 'checkbox', 'all', 'native', 240, 0, 5, '', '', '', '', 'checkBoxMode = multi\norientation=vertical', 2, '', '', '', 'specialchar'), (1, 'render', 'Render', 'show', 'radio', 'all', 'native', 240, 0, 3, '', '', '', '', '', 2, '', '', '', 'specialchar'),
(1, 'showButton', 'Show button', 'show', 'checkbox', 'all', 'native', 250, 0, 5, '', '', '', '', 'checkBoxMode = multi\norientation=vertical', 2, '', '', '', 'specialchar'),
(1, 'forwardMode', 'Forward', 'show', 'radio', 'all', 'native', 300, 0, 0, '', '', '', '', '', 3, '', '', '', 'specialchar'), (1, 'forwardMode', 'Forward', 'show', 'radio', 'all', 'native', 300, 0, 0, '', '', '', '', '', 3, '', '', '', 'specialchar'),
(1, 'forwardPage', 'Forward Page', 'show', 'text', 'all', 'native', 310, 0, 0, '', '', '', '', '', 3, '', '', '', 'none'), (1, 'forwardPage', 'Forward Page', 'show', 'text', 'all', 'native', 310, 0, 0, '', '', '', '', '', 3, '', '', '', 'none'),
...@@ -179,7 +181,8 @@ VALUES ...@@ -179,7 +181,8 @@ VALUES
(1, 'multi', 'Multi', 'show', 'fieldset', 'all', 'native', 400, 0, 0, '', '', '', '', '', 4, '', '', '', 'specialchar'), (1, 'multi', 'Multi', 'show', 'fieldset', 'all', 'native', 400, 0, 0, '', '', '', '', '', 4, '', '', '', 'specialchar'),
(1, 'multiMode', 'Multi Mode', 'show', 'radio', 'all', 'native', 410, 0, 0, '', '', '', '', '', 4, '', '', '', 'specialchar'), (1, 'multiMode', 'Multi Mode', 'show', 'radio', 'all', 'native', 410, 0, 0, '', '', '', '', '', 4, '', '', '', 'specialchar'),
(1, 'multiSql', 'Multi SQL', 'show', 'text', 'all', 'native', 420, '40,3', 0, '', '', '', '', '', 4, '', '', '', 'none'), (1, 'multiSql', 'Multi SQL', 'show', 'text', 'all', 'native', 420, '40,3', 0, '', '', '', '', '', 4, '', '', '',
'none'),
(1, 'multiDetailForm', 'Multi Detail Form', 'show', 'text', 'all', 'native', 430, 0, 0, '', '', '', '', '', 4, (1, 'multiDetailForm', 'Multi Detail Form', 'show', 'text', 'all', 'native', 430, 0, 0, '', '', '', '', '', 4,
'', '', '', 'specialchar'), '', '', '', 'specialchar'),
(1, 'multiDetailFormParameter', 'Multi Detail Form Parameter', 'show', 'text', 'all', 'native', 440, 0, 0, '', '', (1, 'multiDetailFormParameter', 'Multi Detail Form Parameter', 'show', 'text', 'all', 'native', 440, 0, 0, '', '',
......
...@@ -239,6 +239,12 @@ EOT; ...@@ -239,6 +239,12 @@ EOT;
F_CLASS_BODY => 'qfq-color-grey-2', F_CLASS_BODY => 'qfq-color-grey-2',
F_BUTTON_ON_CHANGE_CLASS => 'btn-info alert-info', F_BUTTON_ON_CHANGE_CLASS => 'btn-info alert-info',
SYSTEM_EDIT_FORM_PAGE => 'form', SYSTEM_EDIT_FORM_PAGE => 'form',
SYSTEM_SECURITY_VARS_HONEYPOT => 'email,username,password',
SYSTEM_SECURITY_ATTACK_DELAY => '5',
SYSTEM_SECURITY_SHOW_MESSAGE => 'true',
SYSTEM_SECURITY_GET_MAX_LENGTH => '50',
SYSTEM_ESCAPE_TYPE_DEFAULT => 's',
]; ];
$fileName = $this->createFile($body); $fileName = $this->createFile($body);
......
...@@ -9,8 +9,9 @@ CREATE TABLE IF NOT EXISTS `Form` ( ...@@ -9,8 +9,9 @@ CREATE TABLE IF NOT EXISTS `Form` (
`permitNew` ENUM('sip', 'logged_in', 'logged_out', 'always', 'never') NOT NULL DEFAULT 'sip', `permitNew` ENUM('sip', 'logged_in', 'logged_out', 'always', 'never') NOT NULL DEFAULT 'sip',
`permitEdit` ENUM('sip', 'logged_in', 'logged_out', 'always', 'never') NOT NULL DEFAULT 'sip', `permitEdit` ENUM('sip', 'logged_in', 'logged_out', 'always', 'never') NOT NULL DEFAULT 'sip',
`escapeTypeDefault` ENUM('', 's', 'd', 'l', 'L', 'm', '-') NOT NULL DEFAULT 's',
`render` ENUM('plain', 'table', 'bootstrap') NOT NULL DEFAULT 'plain', `render` ENUM('plain', 'table', 'bootstrap') NOT NULL DEFAULT 'plain',
`requiredParameter` VARCHAR(255) NOT NULL DEFAULT '', `requiredParameter` VARCHAR(255) NOT NULL DEFAULT '',
`showButton` SET('new', 'delete') NOT NULL DEFAULT 'new,delete', `showButton` SET('new', 'delete') NOT NULL DEFAULT 'new,delete',
`multiMode` ENUM('none', 'horizontal', 'vertical') NOT NULL DEFAULT 'none', `multiMode` ENUM('none', 'horizontal', 'vertical') NOT NULL DEFAULT 'none',
`multiSql` TEXT NOT NULL, `multiSql` TEXT NOT NULL,
...@@ -54,58 +55,58 @@ CREATE TABLE IF NOT EXISTS `Form` ( ...@@ -54,58 +55,58 @@ CREATE TABLE IF NOT EXISTS `Form` (
DROP TABLE IF EXISTS `FormElement`; DROP TABLE IF EXISTS `FormElement`;
CREATE TABLE IF NOT EXISTS `FormElement` ( CREATE TABLE IF NOT EXISTS `FormElement` (
`id` INT(11) NOT NULL AUTO_INCREMENT, `id` INT(11) NOT NULL AUTO_INCREMENT,