CVE-2012-4396: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Multiple cross-site scripting (XSS) vulnerabilities in ownCloud before 4.0.2 allow remote attackers to inject arbitrary web script or HTML via the (1) file names to apps/user_ldap/settings.php; (2) url or (3) title parameter to apps/bookmarks/ajax/editBookmark.php; (4) tag or (5) page parameter to apps/bookmarks/ajax/updateList.php; (6) identity to apps/user_openid/settings.php; (7) stack name in apps/gallery/lib/tiles.php; (8) root parameter to apps/gallery/templates/index.php; (9) calendar displayname in apps/calendar/templates/part.import.php; (10) calendar uri in apps/calendar/templates/part.choosecalendar.rowfields.php; (11) title, (12) location, or (13) description parameter in apps/calendar/lib/object.php; (14) certain vectors in core/js/multiselect.js; or (15) artist, (16) album, or (17) title comments parameter in apps/media/lib_scanner.php.
CWE description: The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users.
Published: 2012-09-05T23:55Z
Repository: https://github.com/owncloud/core
Language: PHP
Files changed: apps/bookmarks/addBm.php, apps/bookmarks/ajax/addBookmark.php, apps/bookmarks/ajax/delBookmark.php, apps/bookmarks/ajax/editBookmark.php, apps/bookmarks/ajax/recordClick.php, apps/bookmarks/ajax/updateList.php, apps/bookmarks/js/addBm.js, apps/bookmarks/js/bookmarks.js, apps/bookmarks/js/bookmarksearch.js
Commit date: 2012-06-11 11:56:11 +0200
Commit message: Using POST instead of GET.

Diff: diff --git a/apps/bookmarks/addBm.php b/apps/bookmarks/addBm.php
index 313489d22..866fa1e7b 100644
--- a/apps/bookmarks/addBm.php
+++ b/apps/bookmarks/addBm.php
@@ -26,8 +26,8 @@
 // Check if we are a user
 OCP\User::checkLoggedIn();
 OCP\App::checkAppEnabled('bookmarks');
 
 require_once('bookmarksHelper.php');
-addBookmark($_GET['url'], '', 'Read-Later');
+addBookmark($_POST['url'], '', 'Read-Later');
 
 include 'templates/addBm.php';
diff --git a/apps/bookmarks/ajax/addBookmark.php b/apps/bookmarks/ajax/addBookmark.php
index 9241dc8dd..a2eb506f8 100644
--- a/apps/bookmarks/ajax/addBookmark.php
+++ b/apps/bookmarks/ajax/addBookmark.php
@@ -29,7 +29,7 @@ $RUNTIME_NOSETUPFS=true;
 // Check if we are a user
 OCP\JSON::checkLoggedIn();
 OCP\JSON::checkAppEnabled('bookmarks');
 
 require_once(OC::$APPSROOT . '/apps/bookmarks/bookmarksHelper.php');
-$id = addBookmark($_GET['url'], $_GET['title'], $_GET['tags']);
+$id = addBookmark($_POST['url'], $_POST['title'], $_POST['tags']);
 OCP\JSON::success(array('data' => $id));
\ No newline at end of file
diff --git a/apps/bookmarks/ajax/delBookmark.php b/apps/bookmarks/ajax/delBookmark.php
index 0b5689811..5a067701c 100644
--- a/apps/bookmarks/ajax/delBookmark.php
+++ b/apps/bookmarks/ajax/delBookmark.php
@@ -28,11 +28,11 @@ $RUNTIME_NOSETUPFS=true;
 
 // Check if we are a user
 OCP\JSON::checkLoggedIn();
 OCP\JSON::checkAppEnabled('bookmarks');
 
-$id = $_GET['id'];
+$id = $_POST['id'];
 if (!OC_Bookmarks_Bookmarks::deleteUrl($id)){
 	OC_JSON::error();
 	exit();
 }
 
diff --git a/apps/bookmarks/ajax/editBookmark.php b/apps/bookmarks/ajax/editBookmark.php
index db349af35..fcec2e1ce 100644
--- a/apps/bookmarks/ajax/editBookmark.php
+++ b/apps/bookmarks/ajax/editBookmark.php
@@ -37,21 +37,21 @@ if( $CONFIG_DBTYPE == 'sqlite' or $CONFIG_DBTYPE == 'sqlite3' ){
 	$_ut = 'date_part(\'epoch\',now())::integer';
 } else {
 	$_ut = "UNIX_TIMESTAMP()";
 }
 
-$bookmark_id = (int)$_GET["id"];
+$bookmark_id = (int)$_POST["id"];
 
 $query = OCP\DB::prepare("
 	UPDATE *PREFIX*bookmarks
 	SET url = ?, title =?, lastmodified = $_ut
 	WHERE id = $bookmark_id
 	");
 
 $params=array(
-	htmlspecialchars_decode($_GET["url"]),
-	htmlspecialchars_decode($_GET["title"]),
+	htmlspecialchars_decode($_POST["url"]),
+	htmlspecialchars_decode($_POST["title"]),
 	);
 $query->execute($params);
 
 # Remove old tags and insert new ones.
 $query = OCP\DB::prepare("
@@ -65,11 +65,11 @@ $query = OCP\DB::prepare("
 	INSERT INTO *PREFIX*bookmarks_tags
 	(bookmark_id, tag)
 	VALUES (?, ?)
 	");
 	
-$tags = explode(' ', urldecode($_GET["tags"]));
+$tags = explode(' ', urldecode($_POST["tags"]));
 foreach ($tags as $tag) {
 	if(empty($tag)) {
 		//avoid saving blankspaces
 		continue;
 	}
diff --git a/apps/bookmarks/ajax/recordClick.php b/apps/bookmarks/ajax/recordClick.php
index 2bd91f232..1eee1718d 100644
--- a/apps/bookmarks/ajax/recordClick.php
+++ b/apps/bookmarks/ajax/recordClick.php
@@ -35,10 +35,10 @@ $query = OCP\DB::prepare("
 	SET clickcount = clickcount + 1
 	WHERE user_id = ?
 		AND url LIKE ?
 	");
 	
-$params=array(OCP\USER::getUser(), htmlspecialchars_decode($_GET["url"]));
+$params=array(OCP\USER::getUser(), htmlspecialchars_decode($_POST["url"]));
 $bookmarks = $query->execute($params);
 
 header( "HTTP/1.1 204 No Content" );
 
diff --git a/apps/bookmarks/ajax/updateList.php b/apps/bookmarks/ajax/updateList.php
index c919a5fc4..4de2475d0 100644
--- a/apps/bookmarks/ajax/updateList.php
+++ b/apps/bookmarks/ajax/updateList.php
@@ -31,15 +31,15 @@ $RUNTIME_NOSETUPFS=true;
 OCP\JSON::checkLoggedIn();
 OCP\JSON::checkAppEnabled('bookmarks');
 
 
 //Filter for tag?
-$filterTag = isset($_GET['tag']) ? htmlspecialchars_decode($_GET['tag']) : false;
+$filterTag = isset($_POST['tag']) ? htmlspecialchars_decode($_POST['tag']) : false;
 
-$offset = isset($_GET['page']) ? intval($_GET['page']) * 10 : 0;
+$offset = isset($_POST['page']) ? intval($_POST['page']) * 10 : 0;
 
-$sort = isset($_GET['sort']) ? ($_GET['sort']) : 'bookmarks_sorting_recent';
+$sort = isset($_POST['sort']) ? ($_POST['sort']) : 'bookmarks_sorting_recent';
 if($sort == 'bookmarks_sorting_clicks') {
 	$sqlSortColumn = 'clickcount';
 } else {
 	$sqlSortColumn = 'id';
 }
diff --git a/apps/bookmarks/js/addBm.js b/apps/bookmarks/js/addBm.js
index d64e55e89..625ac8420 100644
--- a/apps/bookmarks/js/addBm.js
+++ b/apps/bookmarks/js/addBm.js
@@ -4,10 +4,11 @@ $(document).ready(function() {
 
 function addBookmark(event) {
 	var url = $('#bookmark_add_url').val();
 	var tags = $('#bookmark_add_tags').val();
 	$.ajax({
+		type: 'POST',
 		url: 'ajax/addBookmark.php',
 		data: 'url=' + encodeURI(url) + '&tags=' + encodeURI(tags),
 		success: function(data){ 
 			window.close();
 		}
diff --git a/apps/bookmarks/js/bookmarks.js b/apps/bookmarks/js/bookmarks.js
index a746cf437..7f3104e81 100644
--- a/apps/bookmarks/js/bookmarks.js
+++ b/apps/bookmarks/js/bookmarks.js
@@ -18,10 +18,11 @@ function getBookmarks() {
 		//have patience :)
 		return;
 	}
 
 	$.ajax({
+		  type: 'POST',
 		url: OC.filePath('bookmarks', 'ajax', 'updateList.php'),
 		data: 'tag=' + encodeURIComponent($('#bookmarkFilterTag').val()) + '&page=' + bookmarks_page + '&sort=' + bookmarks_sorting,
 		success: function(bookmarks){
 			if (bookmarks.data.length) {
 				bookmarks_page += 1;
@@ -68,10 +69,11 @@ function addOrEditBookmark(event) {
 		OC.dialogs.alert('A valid bookmark title must be provided', 'Error creating bookmark');
 		return false;
 	}
 	if (id == 0) {
 		$.ajax({
+			type: 'POST',
 			url: OC.filePath('bookmarks', 'ajax', 'addBookmark.php'),
 			data: 'url=' + encodeURIComponent(url) + '&title=' + encodeURIComponent(title) + '&tags=' + encodeURIComponent(tags),
 			success: function(response){
 				$('.bookmarks_input').val('');
 				$('.bookmarks_list').empty();
@@ -80,10 +82,11 @@ function addOrEditBookmark(event) {
 			}
 		});
 	}
 	else {
 		$.ajax({
+			type: 'POST',
 			url: OC.filePath('bookmarks', 'ajax', 'editBookmark.php'),
 			data: 'id=' + id + '&url=' + encodeURIComponent(url) + '&title=' + encodeURIComponent(title) + '&tags=' + encodeURIComponent(tags),
 			success: function(){
 				$('.bookmarks_input').val('');
 				$('#bookmark_add_id').val('0');
@@ -97,10 +100,11 @@ function addOrEditBookmark(event) {
 }
 
 function delBookmark(event) {
 	var record = $(this).parent().parent();
 	$.ajax({
+		type: 'POST',
 		url: OC.filePath('bookmarks', 'ajax', 'delBookmark.php'),
 		data: 'id=' + record.data('id'),
 		success: function(data){
 			if (data.status == 'success') {
 				record.remove();
@@ -175,10 +179,11 @@ function updateOnBottom() {
 	}
 }
 
 function recordClick(event) {
 	$.ajax({
+		type: 'POST',
 		url: OC.filePath('bookmarks', 'ajax', 'recordClick.php'),
 		data: 'url=' + encodeURIComponent($(this).attr('href')),
 	});
 }
 
diff --git a/apps/bookmarks/js/bookmarksearch.js b/apps/bookmarks/js/bookmarksearch.js
index e7a4fb183..e8f5363c9 100644
--- a/apps/bookmarks/js/bookmarksearch.js
+++ b/apps/bookmarks/js/bookmarksearch.js
@@ -14,9 +14,10 @@ $(document).ready(function(){
 
 function recordClick(event) {
 	var jsFileLocation = $('script[src*=bookmarksearch]').attr('src');
 	jsFileLocation = jsFileLocation.replace('js/bookmarksearch.js', '');
 	$.ajax({
+		type: 'POST',
 		url: jsFileLocation + 'ajax/recordClick.php',
 		data: 'url=' + encodeURI($(this).attr('href')),
 	});	
 }

Vulnerable code: addBookmark($_GET['url'], '', 'Read-Later');
$id = addBookmark($_GET['url'], $_GET['title'], $_GET['tags']);
$id = $_GET['id'];
$bookmark_id = (int)$_GET["id"];
	htmlspecialchars_decode($_GET["url"]),
	htmlspecialchars_decode($_GET["title"]),
$tags = explode(' ', urldecode($_GET["tags"]));
$params=array(OCP\USER::getUser(), htmlspecialchars_decode($_GET["url"]));
$filterTag = isset($_GET['tag']) ? htmlspecialchars_decode($_GET['tag']) : false;
$offset = isset($_GET['page']) ? intval($_GET['page']) * 10 : 0;
$sort = isset($_GET['sort']) ? ($_GET['sort']) : 'bookmarks_sorting_recent';
Fixed code: addBookmark($_POST['url'], '', 'Read-Later');
$id = addBookmark($_POST['url'], $_POST['title'], $_POST['tags']);
$id = $_POST['id'];
$bookmark_id = (int)$_POST["id"];
	htmlspecialchars_decode($_POST["url"]),
	htmlspecialchars_decode($_POST["title"]),
$tags = explode(' ', urldecode($_POST["tags"]));
$params=array(OCP\USER::getUser(), htmlspecialchars_decode($_POST["url"]));
$filterTag = isset($_POST['tag']) ? htmlspecialchars_decode($_POST['tag']) : false;
$offset = isset($_POST['page']) ? intval($_POST['page']) * 10 : 0;
$sort = isset($_POST['sort']) ? ($_POST['sort']) : 'bookmarks_sorting_recent';
		type: 'POST',
		  type: 'POST',
			type: 'POST',
			type: 'POST',
		type: 'POST',
		type: 'POST',
		type: 'POST',