CVE-2015-10059: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: A vulnerability has been found in s134328 Webapplication-Veganguide and classified as problematic. This vulnerability affects unknown code of the file p05-integration/app/shared/api/apiService.js. The manipulation of the argument country/city leads to cross site scripting. The attack can be initiated remotely. The name of the patch is 2aa760fa4e779e40a28206a32ac22ac10356f519. It is recommended to apply a patch to fix this issue. The identifier of this vulnerability is VDB-218416.
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.
CVSS v3 base score: 6.1
Published: 2023-01-17T13:15Z
Repository: https://github.com/s134328/Webapplication-Veganguide
Language: JavaScript
Files changed: p05-integration/app/shared/api/apiService.js, p05-integration/cache.manifest
Commit date: 2015-05-11 08:29:07 +0200
Commit message: Sprint 1: Frontend: API gesichert vor XSS

User-Eingaben (Parameter aus GET/URLs) werden nur genutzt wenn diese
Alpha-Numerisch + Unterstrich + Bindestrich sind.

Diff: diff --git a/p05-integration/app/shared/api/apiService.js b/p05-integration/app/shared/api/apiService.js
index a435292..27333e3 100644
--- a/p05-integration/app/shared/api/apiService.js
+++ b/p05-integration/app/shared/api/apiService.js
@@ -38,11 +38,11 @@ ngApp.factory('apiService', ['$http', '$localStorage',function($http, $localStor
 	 * 
 	 * @private
 	 * @function get
 	 * @memberOf app.api.apiService
 	 * @param {string} URL
-	 * @returns
+	 * @returns nothing
 	 */
 	var get = function(url, fn, callback) {
 		var now = new Date(); // current date and time
 		if(!$localStorage[fn] // not cached before
 			|| !$localStorage[fn].loadTime // or: loadTime invalid
@@ -64,10 +64,29 @@ ngApp.factory('apiService', ['$http', '$localStorage',function($http, $localStor
 		} else { // cached and is up to date
 			callback($localStorage[fn]); // execute callback with data from cache and cache time
 		}		
 	};
 
+	/**
+	 * Decode the string into a safe placeholder.
+	 * If it contains unsafe characters an empty string will be returned.
+	 * 
+	 * @private
+	 * @function placeholder
+	 * @memberOf app.api.apiService
+	 * @param {string} placeholder - A maybe unsafe placeholder used in an $http Request
+	 * @returns {string} Safe Placeholder
+	 */
+	var safe = function(placeholder) {
+		var reg = /^[a-zA-Z0-9\-_]+$/;
+		if(reg.test) {
+			return placeholder;
+		} else {
+			return "";
+		}
+	};
+
 	return {
 		/**
 		 * URL to the API
 		 * @var {string} URL
 		 * @memberOf app.api.apiService 
@@ -98,11 +117,11 @@ ngApp.factory('apiService', ['$http', '$localStorage',function($http, $localStor
 		 * @see {@link http://veganguide.org/api|vg.browse.listCountries}
 		 * @param {fn} callback - Function to execute
 		 */
 		listCountries: function(callback) {
 			get('api/JSON_Dummies/Countries.json', 'listCountries', callback);
-			///get(this.url + "?apikey=" + this.apikey + "&lang=" + this.lang, 'listCountries', callback);
+			///get(this.url + '?apikey=' + this.apikey + '&lang=' + this.lang, 'listCountries', callback);
 		},
 
 		/**
 		 * Executes a callback with a list of all cities as parameter
 		 *
@@ -112,11 +131,11 @@ ngApp.factory('apiService', ['$http', '$localStorage',function($http, $localStor
 		 * @param {string} country - Cities should be in this country
 		 * @param {fn} callback - Function to execute
 		 */
 		listCities: function(country, callback) {
 			get('api/JSON_Dummies/Cities_Germany.json', 'listCities', callback);
-			//get('this.url + "?apikey=" + this.apikey + "&lang=" + this.lang + "&country=" + country', 'listCities', callback);
+			//get(this.url + '?apikey=' + this.apikey + '&lang=' + this.lang + '&country=' + safe(country), 'listCities', callback);
 		},
 
 		/**
 		 * Executes a callback with a list of all places as parameter
 		 *
@@ -127,9 +146,9 @@ ngApp.factory('apiService', ['$http', '$localStorage',function($http, $localStor
 		 * @param {string} city - Cities should be in this city
 		 * @param {fn} callback - Function to execute
 		 */
 		listPlacesByCity: function(country, city, callback) {
 			get('api/JSON_Dummies/Lokale_Leipzig.json', 'listPlacesByCity',  callback);
-			//get(this.url + "?apikey=" + this.apikey + "&lang=" + this.lang + "&country=" + country + "&city=" + city',  callback);
+			//get(this.url + '?apikey=' + this.apikey + '&lang=' + this.lang + '&country=' + safe(country) + '&city=' + safe(city),  callback);
 		}
 	};
 }]);
diff --git a/p05-integration/cache.manifest b/p05-integration/cache.manifest
index 01264dd..d228ada 100644
--- a/p05-integration/cache.manifest
+++ b/p05-integration/cache.manifest
@@ -1,7 +1,7 @@
 CACHE MANIFEST
-# rev 20150511-0746
+# rev 20150511-0827
 
 CACHE:
 assets/css/veganguide.css
 assets/lib/jquery-1.11.1.min.js
 assets/lib/jquery.mobile-1.4.5.min.css

Vulnerable code: 	 * @returns
			///get(this.url + "?apikey=" + this.apikey + "&lang=" + this.lang, 'listCountries', callback);
			//get('this.url + "?apikey=" + this.apikey + "&lang=" + this.lang + "&country=" + country', 'listCities', callback);
			//get(this.url + "?apikey=" + this.apikey + "&lang=" + this.lang + "&country=" + country + "&city=" + city',  callback);
# rev 20150511-0746
Fixed code: 	 * @returns nothing
	/**
	 * Decode the string into a safe placeholder.
	 * If it contains unsafe characters an empty string will be returned.
	 * 
	 * @private
	 * @function placeholder
	 * @memberOf app.api.apiService
	 * @param {string} placeholder - A maybe unsafe placeholder used in an $http Request
	 * @returns {string} Safe Placeholder
	 */
	var safe = function(placeholder) {
		var reg = /^[a-zA-Z0-9\-_]+$/;
		if(reg.test) {
			return placeholder;
		} else {
			return "";
		}
	};

			///get(this.url + '?apikey=' + this.apikey + '&lang=' + this.lang, 'listCountries', callback);
			//get(this.url + '?apikey=' + this.apikey + '&lang=' + this.lang + '&country=' + safe(country), 'listCities', callback);
			//get(this.url + '?apikey=' + this.apikey + '&lang=' + this.lang + '&country=' + safe(country) + '&city=' + safe(city),  callback);
# rev 20150511-0827