ensure z_input_filter is called exactly once, since we now depend on the number of htmlspecialchars operations for

markdown content. Also ensure that the content is escaped the correct number of times on imported items.
This commit is contained in:
zotlabs 2017-03-15 15:53:03 -07:00
parent 6078d02c3a
commit bcd02edd80
2 changed files with 53 additions and 20 deletions

View File

@ -528,11 +528,6 @@ function get_item_elements($x,$allow_code = false) {
$arr = array();
if($allow_code)
$arr['body'] = $x['body'];
else
$arr['body'] = (($x['body']) ? htmlspecialchars($x['body'],ENT_COMPAT,'UTF-8',false) : '');
$key = get_config('system','pubkey');
$maxlen = get_max_import_size();
@ -640,7 +635,17 @@ function get_item_elements($x,$allow_code = false) {
return array();
}
// Check signature on the body text received.
// This presents an issue that we aren't verifying the text that is actually displayed
// on this site. We are however verifying the received text was exactly as received.
// We have every right to strip content that poses a security risk. You are welcome to
// create a plugin to verify the content after filtering if this offends you.
if($arr['sig']) {
// check the supplied signature against the supplied content.
// Note that we will purify the content which could change it.
$r = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1",
dbesc($arr['author_xchan'])
);
@ -650,6 +655,14 @@ function get_item_elements($x,$allow_code = false) {
logger('get_item_elements: message verification failed.');
}
// if the input is markdown, remove one level of html escaping.
// It will be re-applied in item_store() and/or item_store_update().
// Do this after signature checking as the original signature
// was generated on the escaped content.
if($arr['mimetype'] === 'text/markdown')
$arr['body'] = \Zotlabs\Lib\MarkdownSoap::unescape($arr['body']);
if(array_key_exists('revision',$x)) {
// extended export encoding
@ -1475,14 +1488,20 @@ function item_store($arr, $allow_exec = false, $deliver = true) {
$arr['lang'] = detect_language($arr['body']);
// apply the input filter here
$arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec));
if(local_channel() && (local_channel() == $arr['uid'])) {
if(! $arr['sig']) {
$channel = App::get_channel();
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
$arr['item_verified'] = 1;
if(array_key_exists('input_filtered_signed',$arr)) {
unset($arr['input_filtered_signed']);
}
else {
$arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec));
if(local_channel() && (local_channel() == $arr['uid'])) {
if(! $arr['sig']) {
$channel = App::get_channel();
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
$arr['item_verified'] = 1;
}
}
}
}
@ -1896,17 +1915,22 @@ function item_store_update($arr,$allow_exec = false, $deliver = true) {
return $ret;
}
$arr['lang'] = detect_language($arr['body']);
// apply the input filter here
$arr['body'] = trim($arr['body'],$arr['mimetype'],$allow_exec);
if(array_key_exists('input_filtered_signed',$arr)) {
unset($arr['input_filtered_signed']);
}
else {
$arr['body'] = trim(z_input_filter($arr['body'],$arr['mimetype'],$allow_exec));
if(local_channel() && (local_channel() == $arr['uid']) && (! $arr['sig'])) {
$channel = App::get_channel();
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
$arr['item_verified'] = 1;
if(local_channel() && (local_channel() == $arr['uid'])) {
if(! $arr['sig']) {
$channel = App::get_channel();
if($channel['channel_hash'] === $arr['author_xchan']) {
$arr['sig'] = base64url_encode(rsa_sign($arr['body'],$channel['channel_prvkey']));
$arr['item_verified'] = 1;
}
}
}
}

View File

@ -333,12 +333,15 @@ function photo_upload($channel, $observer, $args) {
if($item['mid'] === $item['parent_mid']) {
$item['body'] = $summary;
$item['mimetype'] = 'text/bbcode';
$item['obj_type'] = ACTIVITY_OBJ_PHOTO;
$item['obj'] = json_encode($object);
$item['tgt_type'] = ACTIVITY_OBJ_ALBUM;
$item['target'] = json_encode($target);
$item['body'] = trim(z_input_filter($item['body'],$item['mimetype'],false));
if($item['author_xchan'] === $channel['channel_hash']) {
$item['sig'] = base64url_encode(rsa_sign($item['body'],$channel['channel_prvkey']));
$item['item_verified'] = 1;
@ -346,6 +349,12 @@ function photo_upload($channel, $observer, $args) {
else {
$item['sig'] = '';
}
// notify item_store or item_store_update that the input has been filtered and signed already.
// The signing procedure in those functions uses local_channel() which may not apply here.
$item['input_filtered_signed'] = true;
$force = true;
}