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

F7529 - Guarantee Sip Action plays only once. First version, seems to work, next: rename function

parent 92b3fab7
Pipeline #1976 passed with stages
in 2 minutes and 54 seconds
......@@ -147,6 +147,7 @@ const ERROR_MESSAGE_HTTP_STATUS = 'httpStatus'; // HTTP Status Code to report
// QFQ Error Codes
const ERROR_UNKNOW_SANITIZE_CLASS = 1001;
const ERROR_QUIT_QFQ_REGULAR = 1001;
const ERROR_WIPE_NOT_IMPLEMENTED_FOR_STORE = 1002;
const ERROR_CODE_SHOULD_NOT_HAPPEN = 1003;
const ERROR_SIP_MALFORMED = 1005;
const ERROR_SIP_INVALID = 1006;
......@@ -735,6 +736,7 @@ const TOKEN_ESCAPE_LDAP_DN = 'L';
const TOKEN_ESCAPE_MYSQL = 'm';
const TOKEN_ESCAPE_PASSWORD_T3FE = 'p';
const TOKEN_ESCAPE_NONE = '-';
const TOKEN_ESCAPE_WIPE = 'w';
const TOKEN_ESCAPE_STOP_REPLACE = 'S';
const TOKEN_ESCAPE_EXCEPTION = 'X';
......
......@@ -11,6 +11,7 @@ namespace qfq;
use qfq;
require_once(__DIR__ . '/../core/store/Store.php');
require_once(__DIR__ . '/../core/store/Sip.php');
require_once(__DIR__ . '/../core/database/Database.php');
require_once(__DIR__ . '/../core/typo3/Password.php');
require_once(__DIR__ . '/helper/Support.php');
......@@ -68,9 +69,9 @@ class Evaluate {
$this->startDelimiterLength = strlen($startDelimiter);
$this->endDelimiter = $endDelimiter;
$this->endDelimiterLength = strlen($endDelimiter);
$this->escapeTypeDefault = $this->store->getVar(F_ESCAPE_TYPE_DEFAULT, STORE_SYSTEM);
$this->escapeTypeDefault = $this->store::getVar(F_ESCAPE_TYPE_DEFAULT, STORE_SYSTEM);
if (empty($this->escapeTypeDefault) || $this->escapeTypeDefault == TOKEN_ESCAPE_CONFIG) {
$this->escapeTypeDefault = $this->store->getVar(SYSTEM_ESCAPE_TYPE_DEFAULT, STORE_SYSTEM);
$this->escapeTypeDefault = $this->store::getVar(SYSTEM_ESCAPE_TYPE_DEFAULT, STORE_SYSTEM);
}
}
......@@ -155,7 +156,7 @@ class Evaluate {
$posFirstClose = strpos($result, $this->endDelimiter);
// Variables like 'fillStoreVar' might contain SQL statements. Put them in store in case a DB exception is thrown.
$this->store->setVar(SYSTEM_SQL_RAW, $line, STORE_SYSTEM);
$this->store::setVar(SYSTEM_SQL_RAW, $line, STORE_SYSTEM);
while ($posFirstClose !== false) {
......@@ -236,7 +237,7 @@ class Evaluate {
$token = OnString::trimQuote(trim(implode(' ', $arrToken)));
if ($this->link === null) {
$this->link = new Link($this->store->getSipInstance(), $dbIndex);
$this->link = new Link($this->store::getSipInstance(), $dbIndex);
}
$foundInStore = TOKEN_FOUND_AS_COLUMN;
......@@ -261,7 +262,7 @@ class Evaluate {
}
if ($this->link === null) {
$this->link = new Link($this->store->getSipInstance(), $dbIndex);
$this->link = new Link($this->store::getSipInstance(), $dbIndex);
}
$foundInStore = TOKEN_FOUND_AS_COLUMN;
......@@ -269,7 +270,7 @@ class Evaluate {
$s = $this->link->renderLink('U:' . $token . '|s|r:8');
// Flag to add DND JS code later on.
$this->store->setVar(SYSTEM_DRAG_AND_DROP_JS, 'true', STORE_SYSTEM);
$this->store::setVar(SYSTEM_DRAG_AND_DROP_JS, 'true', STORE_SYSTEM);
// data-dnd-api="typo3conf/ext/qfq/qfq/api/dragAndDrop.php?s={{'U:form=<form name>[&paramX=<any value>]|s|r:8' AS _link}}"
return DND_DATA_DND_API . '="' . API_DIR . '/' . API_DRAG_AND_DROP_PHP . '?s=' . $s . '"';
......@@ -298,7 +299,7 @@ class Evaluate {
$token = trim($token);
$dbIndex = $this->dbIndex;
$flagThrowExceptionIfNotFound = false;
$flagWipe = false;
// Check if the $token starts with '[<int>]...' - yes: open the necessary database.
if (strlen($token) > 2 && $token[0] === '[') {
......@@ -360,7 +361,7 @@ class Evaluate {
$typeMessageViolate = ($arrToken[VAR_INDEX_MESSAGE] === null || $arrToken[VAR_INDEX_MESSAGE] === '') ? SANITIZE_TYPE_MESSAGE_VIOLATE_CLASS : $arrToken[VAR_INDEX_MESSAGE];
// search for value in stores
$value = $this->store->getVar($arrToken[VAR_INDEX_VALUE], $arrToken[VAR_INDEX_STORE], $arrToken[VAR_INDEX_SANATIZE], $foundInStore, $typeMessageViolate);
$value = $this->store::getVar($arrToken[VAR_INDEX_VALUE], $arrToken[VAR_INDEX_STORE], $arrToken[VAR_INDEX_SANATIZE], $foundInStore, $typeMessageViolate);
// escape ticks
if (is_string($value)) {
......@@ -400,6 +401,9 @@ class Evaluate {
case TOKEN_ESCAPE_EXCEPTION:
// empty values will be handled later.
break;
case TOKEN_ESCAPE_WIPE:
$flagWipe = true;
break;
default:
throw new UserFormException("Unknown escape qualifier: $escape", ERROR_UNKNOW_SANITIZE_CLASS);
break;
......@@ -418,6 +422,22 @@ class Evaluate {
$value = str_replace('\\:', ':', $arrToken[VAR_INDEX_DEFAULT]);
}
if ($flagWipe) {
switch ($foundInStore) {
case STORE_SIP:
$this->store::setVar($arrToken[VAR_INDEX_VALUE], '', $foundInStore, true);
$sip = new Sip();
$sip->removeKeyFromSip($this->store::getVar(SIP_SIP, $foundInStore), $arrToken[VAR_INDEX_VALUE]);
break;
case STORE_EMPTY:
case STORE_ZERO:
break;
default:
throw new UserReportException("Wipe not implemented for store $foundInStore", ERROR_WIPE_NOT_IMPLEMENTED_FOR_STORE);
}
}
return $value;
}
......
......@@ -23,8 +23,6 @@ class Sip {
private $phpUnit = false;
private $staticUniqId = false;
private $getParamL = '';
private $getParamType = '';
/**
* @param bool|false $phpUnit
......@@ -291,6 +289,39 @@ class Sip {
Session::set($sipParamStringNew, $sip);
}
/**
* Remove one key/value from SIP. Do not change the SIP.
* set: sip['badcaffee1234']="r=123&action=start" >> sip['badcaffee1234']="r=123"
* unset: sip['r=123&action=start']
* set: sip("r=123")= 'badcaffee1234'
*
* @param string $s
* @param string $key
*/
public function removeKeyFromSip($s, $key) {
// Get old entry
$sipParamStringOld = Session::get($s);
$arr = explode('&', $sipParamStringOld);
foreach ($arr as $idx => $value) {
$tokenArr = explode('=', $value, 2);
if (($tokenArr[0] ?? '') == $key) {
unset($arr[$idx]);
}
}
$sipParamStringNew = implode('&', $arr);
# Remove old
Session::unsetItem($sipParamStringOld);
# Set new
Session::set($s, $sipParamStringNew);
Session::set($sipParamStringNew, $s);
}
/**
* Retrieve Params stored in $_SESSION[$s]
*
......@@ -305,7 +336,7 @@ class Sip {
# Check if parameter is manipulated
if (strlen($s) != SIP_TOKEN_LENGTH) {
Config::attackDetectedExitNow(array(), 'Invalid SIP token length: ' . strlen($s) . " _GET['s']=" . htmlentities($s) );
Config::attackDetectedExitNow(array(), 'Invalid SIP token length: ' . strlen($s) . " _GET['s']=" . htmlentities($s));
}
// Validate: Check if still the same fe_user is logged in.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment