diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index 8682939f267..b085ce49db0 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -161,9 +161,10 @@ function versiondolibarrarray() * @param int $nocommentremoval Do no try to remove comments (in such a case, we consider that each line is a request, so use also $linelengthlimit=0) * @param int $offsetforchartofaccount Offset to use to load chart of account table to update sql on the fly to add offset to rowid and account_parent value * @param int $colspan 2=Add a colspan=2 on td + * @param int $onlysqltoimportwebsite Only sql resquests used to import a website template is allowed * @return int <=0 if KO, >0 if OK */ -function run_sql($sqlfile, $silent = 1, $entity = '', $usesavepoint = 1, $handler = '', $okerror = 'default', $linelengthlimit = 32768, $nocommentremoval = 0, $offsetforchartofaccount = 0, $colspan = 0) +function run_sql($sqlfile, $silent = 1, $entity = '', $usesavepoint = 1, $handler = '', $okerror = 'default', $linelengthlimit = 32768, $nocommentremoval = 0, $offsetforchartofaccount = 0, $colspan = 0, $onlysqltoimportwebsite = 0) { global $db, $conf, $langs, $user; @@ -323,6 +324,52 @@ function run_sql($sqlfile, $silent = 1, $entity = '', $usesavepoint = 1, $handle $keyforsql = md5($sqlfile); foreach ($arraysql as $i => $sql) { if ($sql) { + // Test if sql is allowed + if ($onlysqltoimportwebsite) { + $newsql = str_replace(array("\'"), '__BACKSLASHQUOTE__', $sql); + // Remove all strings contents + $l = strlen($newsql); + $is = 0; + $quoteopen = 0; + $newsqlclean = ''; + while ($is < $l) { + $char = $newsql[$is]; + if ($char == "'") { + if ($quoteopen) { + $quoteopen--; + } else { + $quoteopen++; + } + } elseif (empty($quoteopen)) { + $newsqlclean .= $char; + } + $is++; + } + $newsqlclean = str_replace(array("null"), '__000__', $newsqlclean); + //print $newsqlclean."
\n"; + + // A very small control. This can still by bypassed by adding a second SQL request concatenated + $qualified = 0; + if (preg_match('/^--/', $newsqlclean)) { + $qualified = 1; + } elseif (preg_match('/^UPDATE llx_website SET fk_default_home = \d+\+\d+ WHERE rowid = \d+;$/', $newsqlclean)) { + $qualified = 1; + } elseif (preg_match('/^INSERT INTO llx_website_page\([a-z0-9_\s,]+\) VALUES\([0-9_\s,\+]+\);$/', $newsqlclean)) { + // Insert must match + // INSERT INTO llx_website_page(rowid, fk_page, fk_website, pageurl, aliasalt, title, description, lang, image, keywords, status, date_creation, tms, import_key, grabbed_from, type_container, htmlheader, content, author_alias) VALUES(1+123, null, 17, , , , , , , , , , , null, , , , , ); + $qualified = 1; + } + + if (!$qualified) { + $error++; + //print 'Request '.($i + 1)." contains non allowed instructions.
\n"; + //print "newsqlclean = ".$newsqlclean."
\n"; + dol_syslog('Admin.lib::run_sql Request '.($i + 1)." contains non allowed instructions.", LOG_DEBUG); + dol_syslog('$newsqlclean='.$newsqlclean, LOG_DEBUG); + break; + } + } + // Replace the prefix tables if (MAIN_DB_PREFIX != 'llx_') { $sql = preg_replace('/llx_/i', MAIN_DB_PREFIX, $sql); @@ -365,7 +412,7 @@ function run_sql($sqlfile, $silent = 1, $entity = '', $usesavepoint = 1, $handle $sqlmodified++; } - // Replace __x__ with rowid of insert nb x + // Replace __x__ with the rowid of the result of the insert number x while (preg_match('/__([0-9]+)__/', $newsql, $reg)) { $cursor = $reg[1]; if (empty($listofinsertedrowid[$cursor])) { diff --git a/htdocs/website/class/website.class.php b/htdocs/website/class/website.class.php index bb46729145c..0a342d1ad62 100644 --- a/htdocs/website/class/website.class.php +++ b/htdocs/website/class/website.class.php @@ -1209,7 +1209,7 @@ class Website extends CommonObject } // Load sql record - $runsql = run_sql($sqlfile, 1, '', 0, '', 'none', 0, 1); // The maxrowid of table is searched into this function two + $runsql = run_sql($sqlfile, 1, '', 0, '', 'none', 0, 1, 0, 0, 1); // The maxrowid of table is searched into this function two if ($runsql <= 0) { $this->errors[] = 'Failed to load sql file '.$sqlfile; $error++;