Use sanitization for locale constants

This commit is contained in:
Dmitriy Simushev 2014-01-31 12:52:59 +00:00
parent 825da2027f
commit 8d3dcacded
9 changed files with 183 additions and 50 deletions

View File

@ -33,7 +33,8 @@ if ($referer && isset($_SESSION['threadid'])) {
$msg = getstring2_(
"chat.client.visited.page",
array($referer),
$thread->locale
$thread->locale,
true
);
$thread->postMessage(Thread::KIND_FOR_AGENT, $msg);
}

View File

@ -723,14 +723,15 @@ function chat_start_for_user(
Thread::KIND_FOR_AGENT,
getstring2(
'chat.visitor.invitation.accepted',
array($operator_name)
array($operator_name),
true
)
);
} else {
if ($referrer) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.came.from', array($referrer))
getstring2('chat.came.from', array($referrer), true)
);
}
if ($requested_operator && !$requested_operator_online) {
@ -738,11 +739,12 @@ function chat_start_for_user(
Thread::KIND_INFO,
getstring2(
'chat.requested_operator.offline',
array(get_operator_name($requested_operator))
array(get_operator_name($requested_operator)),
true
)
);
} else {
$thread->postMessage(Thread::KIND_INFO, getstring('chat.wait'));
$thread->postMessage(Thread::KIND_INFO, getstring('chat.wait', true));
}
}
@ -750,7 +752,7 @@ function chat_start_for_user(
if ($info) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.visitor.info', array($info))
getstring2('chat.visitor.info', array($info), true)
);
}

View File

@ -533,7 +533,7 @@ class ThreadProcessor extends ClientSideProcessor
if ($email) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.visitor.email', array($email))
getstring2('chat.visitor.email', array($email), true)
);
}
@ -647,19 +647,19 @@ class ThreadProcessor extends ClientSideProcessor
if ($referrer) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.came.from', array($referrer))
getstring2('chat.came.from', array($referrer), true)
);
}
if ($email) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.visitor.email', array($email))
getstring2('chat.visitor.email', array($email), true)
);
}
if ($info) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring2('chat.visitor.info', array($info))
getstring2('chat.visitor.info', array($info), true)
);
}
$thread->postMessage(Thread::KIND_USER, $message, array('name' => $name));

View File

@ -364,7 +364,7 @@ class Thread
// Send message
$thread->postMessage(
self::KIND_EVENTS,
getstring_("chat.status.user.reopenedthread", $thread->locale)
getstring_("chat.status.user.reopenedthread", $thread->locale, true)
);
return $thread;
@ -602,7 +602,8 @@ class Thread
// Send message to user
$message_to_post = getstring_(
"chat.status.operator.dead",
$this->locale
$this->locale,
true
);
$this->postMessage(
self::KIND_CONN,
@ -626,7 +627,8 @@ class Thread
// And send a message to operator
$message_to_post = getstring_(
"chat.status.user.dead",
$this->locale
$this->locale,
true
);
$this->postMessage(
self::KIND_FOR_AGENT,
@ -708,13 +710,15 @@ class Thread
$message_to_post = getstring2_(
"chat.status.operator.changed",
array($operator_name, $this->agentName),
$this->locale
$this->locale,
true
);
} else {
$message_to_post = getstring2_(
"chat.status.operator.returned",
array($operator_name),
$this->locale
$this->locale,
true
);
}
@ -867,7 +871,8 @@ class Thread
getstring2_(
"chat.status.user.left",
array($this->userName),
$this->locale
$this->locale,
true
)
);
} else {
@ -876,7 +881,8 @@ class Thread
self::KIND_FOR_AGENT,
getstring_(
"chat.visitor.invitation.canceled",
$this->locale
$this->locale,
true
)
);
} else {
@ -885,7 +891,8 @@ class Thread
getstring2_(
"chat.status.operator.left",
array($this->agentName),
$this->locale
$this->locale,
true
)
);
}
@ -942,20 +949,23 @@ class Thread
$message = getstring2_(
"chat.status.operator.changed",
array($operator_name, $this->agentName),
$this->locale
$this->locale,
true
);
} else {
$message = getstring2_(
"chat.status.operator.returned",
array($operator_name),
$this->locale
$this->locale,
true
);
}
} else {
$message = getstring2_(
"chat.status.operator.joined",
array($operator_name),
$this->locale
$this->locale,
true
);
}
} elseif ($this->state == self::STATE_CHATTING) {
@ -965,7 +975,8 @@ class Thread
$message = getstring2_(
"chat.status.operator.changed",
array($operator_name, $this->agentName),
$this->locale
$this->locale,
true
);
}
} else {
@ -1015,7 +1026,8 @@ class Thread
$message = getstring2_(
"chat.status.user.changedname",
array($old_name, $new_name),
$this->locale
$this->locale,
true
);
$this->postMessage(self::KIND_EVENTS, $message);
}

View File

@ -287,7 +287,7 @@ function getoutputenc()
: MIBEW_ENCODING;
}
function getstring_($text, $locale)
function getstring_($text, $locale, $raw = false)
{
global $messages;
if (!isset($messages[$locale])) {
@ -296,53 +296,66 @@ function getstring_($text, $locale)
$localized = $messages[$locale];
if (isset($localized[$text])) {
return $localized[$text];
return $raw
? $localized[$text]
: sanitize_string($localized[$text], 'low', 'moderate');
}
if ($locale != 'en') {
return getstring_($text, 'en');
return getstring_($text, 'en', $raw);
}
return "!" . $text;
return "!" . ($raw ? $text : sanitize_string($text, 'low', 'moderate'));
}
function getstring($text)
function getstring($text, $raw = false)
{
return getstring_($text, CURRENT_LOCALE);
return getstring_($text, CURRENT_LOCALE, $raw);
}
function getlocal($text)
function getlocal($text, $raw = false)
{
return myiconv(MIBEW_ENCODING, getoutputenc(), getstring_($text, CURRENT_LOCALE));
return getlocal_($text, CURRENT_LOCALE, $raw);
}
function getlocal_($text, $locale)
function getlocal_($text, $locale, $raw = false)
{
return myiconv(MIBEW_ENCODING, getoutputenc(), getstring_($text, $locale));
$string = myiconv(
MIBEW_ENCODING,
getoutputenc(),
getstring_($text, $locale, true)
);
return $raw ? $string : sanitize_string($string, 'low', 'moderate');
}
function getstring2_($text, $params, $locale)
function getstring2_($text, $params, $locale, $raw = false)
{
$string = getstring_($text, $locale);
$string = getstring_($text, $locale, true);
for ($i = 0; $i < count($params); $i++) {
$string = str_replace("{" . $i . "}", $params[$i], $string);
}
return $string;
return $raw ? $string : sanitize_string($string, 'low', 'moderate');
}
function getstring2($text, $params)
function getstring2($text, $params, $raw = false)
{
return getstring2_($text, $params, CURRENT_LOCALE);
return getstring2_($text, $params, CURRENT_LOCALE, $raw);
}
function getlocal2($text, $params)
function getlocal2($text, $params, $raw = false)
{
$string = myiconv(MIBEW_ENCODING, getoutputenc(), getstring_($text, CURRENT_LOCALE));
$string = myiconv(
MIBEW_ENCODING,
getoutputenc(),
getstring_($text, CURRENT_LOCALE, true)
);
for ($i = 0; $i < count($params); $i++) {
$string = str_replace("{" . $i . "}", $params[$i], $string);
}
return $string;
return $raw ? $string : sanitize_string($string, 'low', 'moderate');
}
/* prepares for Javascript string */
@ -354,7 +367,7 @@ function get_local_for_js($text, $params)
$string = str_replace("{" . $i . "}", $params[$i], $string);
}
return $string;
return sanitize_string($string, 'low', 'moderate');
}
function locale_load_id_list($name)

View File

@ -54,3 +54,104 @@ function escape_with_cdata($text)
{
return "<![CDATA[" . str_replace("]]>", "]]>]]&gt;<![CDATA[", $text) . "]]>";
}
/**
* Simple HTML sanitation.
*
* Includes some code from the PHP StripAttributes Class For XML and HTML.
*
* @param string $string Target string
* @param string $tags_level Sanitation level for tags. Available values are
* "high", "moderate" and "low".
* @param string $attr_level Sanitation level for attributes. Available values
* are "high", "moderate" and "low".
* @return string Sanitized string with stripped dangerous tags and attributes.
*
* @author David (semlabs.co.uk)
* @copyright (c) 2009, David (semlabs.co.uk)
* @license MIT
* @link http://semlabs.co.uk/journal/php-strip-attributes-class-for-xml-and-html
*/
function sanitize_string($string, $tags_level = 'high', $attr_level = 'high')
{
$sanitize_tags = array(
'high' => '',
'moderate' => '<span><em><strong><b><i><br>',
'low' => '<span><em><strong><b><i><br><p><ul><ol><li><a><font><style>',
);
$sanitize_attributes = array(
'high' => array(),
'moderate' => array('class', 'style', 'href', 'rel', 'id'),
'low' => false,
);
$tags_level = array_key_exists($tags_level, $sanitize_tags) ? $tags_level : 'high';
$string = strip_tags($string, $sanitize_tags[$tags_level]);
$attr_level = array_key_exists($attr_level, $sanitize_attributes) ? $attr_level : 'high';
if ($sanitize_attributes[$attr_level]) {
preg_match_all("/<([^ !\/\>\n]+)([^>]*)>/i", $string, $elements);
foreach ($elements[1] as $key => $element) {
if ($elements[2][$key]) {
$new_attributes = '';
preg_match_all(
"/([^ =]+)\s*=\s*[\"|']{0,1}([^\"']*)[\"|']{0,1}/i",
$elements[2][$key],
$attributes
);
if ($attributes[1]) {
foreach ($attributes[1] as $attr_key => $attr) {
if (in_array($attributes[1][$attr_key], $sanitize_attributes[$attr_level])) {
$new_attributes .= ' ' . $attributes[1][$attr_key]
. '="' . $attributes[2][$attr_key] . '"';
}
}
}
$replacement = '<' . $elements[1][$key] . $new_attributes . '>';
$string = preg_replace(
'/' . sanitize_reg_escape($elements[0][$key]) . '/',
$replacement,
$string
);
}
}
}
return $string;
}
/**
* Remove dangerous characters from regular expression.
*
* @param string $string Target regular expression
* @return string Sanitized reqular expression
*/
function sanitize_reg_escape($string)
{
$conversions = array(
"^" => "\^",
"[" => "\[",
"." => "\.",
"$" => "\$",
"{" => "\{",
"*" => "\*",
"(" => "\(",
"\\" => "\\\\",
"/" => "\/",
"+" => "\+",
")" => "\)",
"|" => "\|",
"?" => "\?",
"<" => "\<",
">" => "\>",
);
return strtr($string, $conversions);
}

View File

@ -121,12 +121,13 @@ function invitation_invite($visitor_id, $operator)
Thread::KIND_FOR_AGENT,
getlocal2(
'chat.visitor.invitation.sent',
array($operator_name, $last_visited_page)
array($operator_name, $last_visited_page),
true
)
);
$thread->postMessage(
Thread::KIND_AGENT,
getlocal("invitation.message"),
getlocal("invitation.message", true),
array(
'name' => $operator_name,
'operator_id' => $operator['operatorid'],
@ -200,7 +201,7 @@ function invitation_reject($visitor_id)
if ($thread) {
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getlocal('chat.visitor.invitation.rejected')
getlocal('chat.visitor.invitation.rejected', true)
);
}
@ -270,7 +271,7 @@ function invitation_close_old()
$thread = Thread::createFromDbInfo($thread_info);
$thread->postMessage(
Thread::KIND_FOR_AGENT,
getstring_('chat.visitor.invitation.ignored', $thread->locale)
getstring_('chat.visitor.invitation.ignored', $thread->locale, true)
);
unset($thread);
}

View File

@ -71,14 +71,15 @@ foreach ($messages as $msg) {
$history .= message_to_text($msg);
}
$subject = getstring("mail.user.history.subject");
$subject = getstring("mail.user.history.subject", true);
$body = getstring2(
"mail.user.history.body",
array($thread->userName,
$history,
Settings::get('title'),
Settings::get('hosturl')
)
),
true
);
mibew_mail($email, $mibew_mailbox, $subject, $body);

View File

@ -66,7 +66,8 @@ if (isset($_GET['nextGroup'])) {
getstring2_(
"chat.status.operator.redirect",
array(get_operator_name($operator)),
$thread->locale
$thread->locale,
true
)
);
} else {
@ -110,7 +111,8 @@ if (isset($_GET['nextGroup'])) {
getstring2_(
"chat.status.operator.redirect",
array(get_operator_name($operator)),
$thread->locale
$thread->locale,
true
)
);
} else {