CVE-2019-25094: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: A vulnerability, which was classified as problematic, was found in innologi appointments Extension up to 2.0.5 on TYPO3. This affects an unknown part of the component Appointment Handler. The manipulation of the argument formfield leads to cross site scripting. It is possible to initiate the attack remotely. Upgrading to version 2.0.6 is able to address this issue. The identifier of the patch is 986d3cb34e5e086c6f04e061f600ffc5837abe7f. It is recommended to upgrade the affected component. The identifier VDB-217353 was assigned to this vulnerability.
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-04T10:15Z
Repository: https://github.com/innologi/typo3-appointments
Language: HTML
Files changed: Resources/Private/Partials/Address/Properties.html, Resources/Private/Partials/Agenda/Week.html, Resources/Private/Partials/Appointment/Properties.html, Resources/Private/Partials/Appointment/Unfinished.html, Resources/Private/Partials/FormField/FormField5.html, Resources/Private/Partials/FormField/Properties.html, Resources/Private/Partials/FormField/Property2.html, Resources/Private/Partials/FormField/Property3.html, Resources/Private/Partials/FormField/Property4.html, Resources/Private/Partials/FormField/Property5.html, Resources/Private/Templates/Appointment/List.html
Commit date: 2019-01-29 17:12:13 +0100
Commit message: [BUGFIX] Prevent XSS on various formfield values

Also, use the standalone Fluid's htmlspecialchars VH instead of TYPO3's
htmlentities VH. They're essentially the same, but going with the former
increases the portability of our code.
Diff: diff --git a/Resources/Private/Partials/Address/Properties.html b/Resources/Private/Partials/Address/Properties.html
index 3e75562..0ca049b 100644
--- a/Resources/Private/Partials/Address/Properties.html
+++ b/Resources/Private/Partials/Address/Properties.html
@@ -4,20 +4,20 @@
 <f:if condition="{type.addressEnableName}">
 	<tr>
 		<td scope="row">
 			<f:translate key="property.appointment.address.name" />
 		</td>
-		<td><f:format.html>{address.name}</f:format.html></td>
+		<td><f:format.htmlspecialchars>{address.name}</f:format.htmlspecialchars></td>
 	</tr>
 </f:if>
 
 <f:if condition="{type.addressEnableSecurity}">
 	<tr>
 		<td scope="row">
 			<f:translate key="property.appointment.address.socialSecurityNumber" />
 		</td>
-		<td><f:format.html>{address.socialSecurityNumber}</f:format.html></td>
+		<td><f:format.htmlspecialchars>{address.socialSecurityNumber}</f:format.htmlspecialchars></td>
 	</tr>
 </f:if>
 
 <f:if condition="{type.addressEnableGender}">
 	<tr>
@@ -33,30 +33,34 @@
 <f:if condition="{type.addressEnableBirthday}">
 	<tr>
 		<td scope="row">
 			<f:translate key="property.appointment.address.birthday" />
 		</td>
-		<td><f:format.date format="d-m-Y">{address.birthday}</f:format.date></td>
+		<td><f:format.htmlspecialchars>
+			<f:format.date format="d-m-Y">{address.birthday}</f:format.date>
+		</f:format.htmlspecialchars></td>
 	</tr>
 </f:if>
 
 <f:if condition="{type.addressEnableAddress}">
 	<tr>
 		<td scope="row">
 			<f:translate key="property.appointment.address.address" />
 		</td>
 		<td>
-			<f:format.html>{address.address}<br />{address.zip} {address.city}</f:format.html>
+			<f:format.htmlspecialchars>{address.address}</f:format.htmlspecialchars>
+			<br />
+			<f:format.htmlspecialchars>{address.zip} {address.city}</f:format.htmlspecialchars>
 		</td>
 	</tr>
 </f:if>
 
 <f:if condition="{type.addressEnableEmail}">
 	<tr>
 		<td scope="row">
 			<f:translate key="property.appointment.address.email" />
 		</td>
-		<td><f:format.html>{address.email}</f:format.html></td>
+		<td><f:format.htmlspecialchars>{address.email}</f:format.htmlspecialchars></td>
 	</tr>
 </f:if>
 
 </html>
\ No newline at end of file
diff --git a/Resources/Private/Partials/Agenda/Week.html b/Resources/Private/Partials/Agenda/Week.html
index 0f79a00..07b7387 100644
--- a/Resources/Private/Partials/Agenda/Week.html
+++ b/Resources/Private/Partials/Agenda/Week.html
@@ -19,11 +19,11 @@
 			<ul>
 				<f:for each="{date.appointments}" as="appointment">
 					<li>
 						<f:link.action title="{f:translate(key:'link.title.appointment_show')}" controller="Appointment" action="show" arguments="{appointment : appointment}" addQueryString="TRUE" argumentsToBeExcludedFromQueryString="{0:'tx_appointments_list[dateFirst]'}" class="link_appointment">
 							<f:format.date format="H:i">{appointment.beginTime}</f:format.date>
-							<f:format.htmlentities>{appointment.type.name}</f:format.htmlentities>
+							<f:format.htmlspecialchars>{appointment.type.name}</f:format.htmlspecialchars>
 						</f:link.action>
 					</li>
 				</f:for>
 			</ul>
 		</f:if>
diff --git a/Resources/Private/Partials/Appointment/Properties.html b/Resources/Private/Partials/Appointment/Properties.html
index 59e0fd3..aa0b6b9 100644
--- a/Resources/Private/Partials/Appointment/Properties.html
+++ b/Resources/Private/Partials/Appointment/Properties.html
@@ -6,11 +6,11 @@
 	
 	<tr>
 		<td scope="row">
 			<f:translate key="property.appointment.type" />
 		</td>
-		<td><f:format.htmlentities>{appointment.type.name}</f:format.htmlentities></td>
+		<td><f:format.htmlspecialchars>{appointment.type.name}</f:format.htmlspecialchars></td>
 	</tr>
 	<tr>
 		<td scope="row">
 			<f:translate key="property.appointment.beginTime.date" />
 		</td>
@@ -32,11 +32,13 @@
 	<f:if condition="{appointment.feUser}">
 		<tr>
 			<td scope="row">
 				<f:translate key="property.appointment.feUser" />
 			</td>
-			<td>{f:if(condition:appointment.feUser.name, then:appointment.feUser.name, else:appointment.feUser.username)}</td>
+			<td><f:format.htmlspecialchars>
+				{f:if(condition:appointment.feUser.name, then:appointment.feUser.name, else:appointment.feUser.username)}
+			</f:format.htmlspecialchars></td>
 		</tr>
 	</f:if>
 	
 	<tr>
 		<td colspan="2">&nbsp;</td>
@@ -82,20 +84,20 @@
 		</tr>
 		<tr>
 			<td scope="row">
 				<f:translate key="property.appointment.notes" />
 			</td>
-			<td><f:format.html>{appointment.notes}</f:format.html></td>
+			<td><f:format.htmlspecialchars>{appointment.notes}</f:format.htmlspecialchars></td>
 		</tr>
 	</f:if>
 	
 	<f:if condition="{superUser}">
 		<tr>
 			<td scope="row">
 				<f:translate key="property.appointment.notesSu" />
 			</td>
-			<td><f:format.html>{appointment.notesSu}</f:format.html></td>
+			<td><f:format.htmlspecialchars>{appointment.notesSu}</f:format.htmlspecialchars></td>
 		</tr>
 	</f:if>
 </table>
 
 </html>
\ No newline at end of file
diff --git a/Resources/Private/Partials/Appointment/Unfinished.html b/Resources/Private/Partials/Appointment/Unfinished.html
index 28ee6c3..8c96520 100644
--- a/Resources/Private/Partials/Appointment/Unfinished.html
+++ b/Resources/Private/Partials/Appointment/Unfinished.html
@@ -14,17 +14,17 @@
 					<li>
 						<f:if condition="{a:appointment.isExpired(appointment:appointment,timerMinutes:settings.freeSlotInMinutes)}">
 							<f:then>
 								<f:link.action title="{f:translate(key:'link.title.appointment_resume')}" action="new1" arguments="{appointment : appointment}" addQueryString="TRUE" class="link_appointment">
 									<span class="time-unreserved"><f:format.date format="d-m-Y, H:i">{appointment.beginTime}</f:format.date></span>:
-									<f:format.htmlentities>{appointment.type.name}</f:format.htmlentities>
+									<f:format.htmlspecialchars>{appointment.type.name}</f:format.htmlspecialchars>
 								</f:link.action>(<f:translate key="tx_appointments_list.free_state" />)
 							</f:then>
 							<f:else>
 								<f:link.action title="{f:translate(key:'link.title.appointment_resume')}" action="new2" arguments="{appointment : appointment}" addQueryString="TRUE" class="link_appointment">
 									<f:format.date format="d-m-Y, H:i">{appointment.beginTime}</f:format.date>:
-									<f:format.htmlentities>{appointment.type.name}</f:format.htmlentities>
+									<f:format.htmlspecialchars>{appointment.type.name}</f:format.htmlspecialchars>
 								</f:link.action>(<a:appointment.timer appointment="{appointment}" timerMinutes="{settings.freeSlotInMinutes}" format="minutes"/> <f:translate key="tx_appointments_list.minutes_remaining"/>)
 							</f:else>
 						</f:if>
 					</li>
 				</f:for>
diff --git a/Resources/Private/Partials/FormField/FormField5.html b/Resources/Private/Partials/FormField/FormField5.html
index b18d913..ed30634 100644
--- a/Resources/Private/Partials/FormField/FormField5.html
+++ b/Resources/Private/Partials/FormField/FormField5.html
@@ -10,9 +10,9 @@
 		id="appointments-formfield-{formField.uid}-{choiceIterator.index}"
 		property="formFieldValues.i{formField.uid}.value"
 		value="{choiceKey}"
 		checked="{0:formFieldValue.value} == {0:choiceKey}"
 		class="formfield-id-{formField.uid} radio session"
-	/> <f:format.htmlentities>{choiceValue}</f:format.htmlentities>
+	/> <f:format.htmlspecialchars>{choiceValue}</f:format.htmlspecialchars>
 </f:for>
 
 </html>
\ No newline at end of file
diff --git a/Resources/Private/Partials/FormField/Properties.html b/Resources/Private/Partials/FormField/Properties.html
index 7e7c98a..66be1a0 100644
--- a/Resources/Private/Partials/FormField/Properties.html
+++ b/Resources/Private/Partials/FormField/Properties.html
@@ -1,11 +1,11 @@
 <html data-namespace-typo3-fluid="true"
 	xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers">
 
 <f:if condition="{formField}">
 	<tr>
-		<td scope="row"><f:format.html>{formField.label}</f:format.html></td>
+		<td scope="row"><f:format.htmlspecialchars>{formField.label}</f:format.htmlspecialchars></td>
 		<td>
 			<f:render partial="FormField/Property{formField.fieldType}" arguments="{formField:formField, formFieldValue:formFieldValue}" />
 		</td>
 	</tr>
 </f:if>
diff --git a/Resources/Private/Partials/FormField/Property2.html b/Resources/Private/Partials/FormField/Property2.html
index 24b1c2d..b7c8a19 100644
--- a/Resources/Private/Partials/FormField/Property2.html
+++ b/Resources/Private/Partials/FormField/Property2.html
@@ -1,6 +1,6 @@
 <html data-namespace-typo3-fluid="true"
 	xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers">
 	
-<f:format.html>{formField.choicesArray.{formFieldValue.value}}</f:format.html>
+<f:format.htmlspecialchars>{formField.choicesArray.{formFieldValue.value}}</f:format.htmlspecialchars>
 
 </html>
\ No newline at end of file
diff --git a/Resources/Private/Partials/FormField/Property3.html b/Resources/Private/Partials/FormField/Property3.html
index d18dd44..07a329f 100644
--- a/Resources/Private/Partials/FormField/Property3.html
+++ b/Resources/Private/Partials/FormField/Property3.html
@@ -1,6 +1,6 @@
 <html data-namespace-typo3-fluid="true"
 	xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers">
 
-<f:format.html>{formFieldValue.value}</f:format.html>
+<f:format.htmlspecialchars>{formFieldValue.value}</f:format.htmlspecialchars>
 
 </html>
\ No newline at end of file
diff --git a/Resources/Private/Partials/FormField/Property4.html b/Resources/Private/Partials/FormField/Property4.html
index a155858..248de09 100644
--- a/Resources/Private/Partials/FormField/Property4.html
+++ b/Resources/Private/Partials/FormField/Property4.html
@@ -1,6 +1,6 @@
 <html data-namespace-typo3-fluid="true"
 	xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers">
 	
-<f:format.html>{formFieldValue.value}</f:format.html>
+<f:format.htmlspecialchars>{formFieldValue.value}</f:format.htmlspecialchars>
 
 </html>
\ No newline at end of file
diff --git a/Resources/Private/Partials/FormField/Property5.html b/Resources/Private/Partials/FormField/Property5.html
index 5b26906..6976ca6 100644
--- a/Resources/Private/Partials/FormField/Property5.html
+++ b/Resources/Private/Partials/FormField/Property5.html
@@ -1,6 +1,6 @@
 <html data-namespace-typo3-fluid="true"
 	xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers">
 
-<f:format.html>{formField.choicesArray.{formFieldValue.value}}</f:format.html>
+<f:format.htmlspecialchars>{formField.choicesArray.{formFieldValue.value}}</f:format.htmlspecialchars>
 
 </html>
\ No newline at end of file
diff --git a/Resources/Private/Templates/Appointment/List.html b/Resources/Private/Templates/Appointment/List.html
index d71d280..85defdd 100644
--- a/Resources/Private/Templates/Appointment/List.html
+++ b/Resources/Private/Templates/Appointment/List.html
@@ -25,11 +25,11 @@
 	<f:for each="{appointments}" as="appointment">
 		<tr>
 			<td>
 				<f:link.action title="{f:translate(key:'link.title.appointment_show')}" action="show" arguments="{appointment : appointment}" addQueryString="TRUE" class="link_appointment">
 					<f:format.date format="d-m-Y, H:i">{appointment.beginTime}</f:format.date>:
-					<f:format.htmlentities>{appointment.type.name}</f:format.htmlentities>
+					<f:format.htmlspecialchars>{appointment.type.name}</f:format.htmlspecialchars>
 				</f:link.action>
 			</td>
 			<f:if condition="{a:appointment.isMutable(appointment:appointment, time:now)}">
 				<f:then>
 					<td><f:link.action title="{f:translate(key:'link.title.appointment_edit')}" action="edit" arguments="{appointment : appointment}" addQueryString="TRUE" class="button_edit"><f:translate key="tx_appointments_list.appointment_edit" /></f:link.action></td>

Vulnerable code: 		<td><f:format.html>{address.name}</f:format.html></td>
		<td><f:format.html>{address.socialSecurityNumber}</f:format.html></td>
		<td><f:format.date format="d-m-Y">{address.birthday}</f:format.date></td>
			<f:format.html>{address.address}<br />{address.zip} {address.city}</f:format.html>
		<td><f:format.html>{address.email}</f:format.html></td>
							<f:format.htmlentities>{appointment.type.name}</f:format.htmlentities>
		<td><f:format.htmlentities>{appointment.type.name}</f:format.htmlentities></td>
			<td>{f:if(condition:appointment.feUser.name, then:appointment.feUser.name, else:appointment.feUser.username)}</td>
			<td><f:format.html>{appointment.notes}</f:format.html></td>
			<td><f:format.html>{appointment.notesSu}</f:format.html></td>
									<f:format.htmlentities>{appointment.type.name}</f:format.htmlentities>
									<f:format.htmlentities>{appointment.type.name}</f:format.htmlentities>
	/> <f:format.htmlentities>{choiceValue}</f:format.htmlentities>
		<td scope="row"><f:format.html>{formField.label}</f:format.html></td>
<f:format.html>{formField.choicesArray.{formFieldValue.value}}</f:format.html>
<f:format.html>{formFieldValue.value}</f:format.html>
<f:format.html>{formFieldValue.value}</f:format.html>
<f:format.html>{formField.choicesArray.{formFieldValue.value}}</f:format.html>
					<f:format.htmlentities>{appointment.type.name}</f:format.htmlentities>
Fixed code: 		<td><f:format.htmlspecialchars>{address.name}</f:format.htmlspecialchars></td>
		<td><f:format.htmlspecialchars>{address.socialSecurityNumber}</f:format.htmlspecialchars></td>
		<td><f:format.htmlspecialchars>
			<f:format.date format="d-m-Y">{address.birthday}</f:format.date>
		</f:format.htmlspecialchars></td>
			<f:format.htmlspecialchars>{address.address}</f:format.htmlspecialchars>
			<br />
			<f:format.htmlspecialchars>{address.zip} {address.city}</f:format.htmlspecialchars>
		<td><f:format.htmlspecialchars>{address.email}</f:format.htmlspecialchars></td>
							<f:format.htmlspecialchars>{appointment.type.name}</f:format.htmlspecialchars>
		<td><f:format.htmlspecialchars>{appointment.type.name}</f:format.htmlspecialchars></td>
			<td><f:format.htmlspecialchars>
				{f:if(condition:appointment.feUser.name, then:appointment.feUser.name, else:appointment.feUser.username)}
			</f:format.htmlspecialchars></td>
			<td><f:format.htmlspecialchars>{appointment.notes}</f:format.htmlspecialchars></td>
			<td><f:format.htmlspecialchars>{appointment.notesSu}</f:format.htmlspecialchars></td>
									<f:format.htmlspecialchars>{appointment.type.name}</f:format.htmlspecialchars>
									<f:format.htmlspecialchars>{appointment.type.name}</f:format.htmlspecialchars>
	/> <f:format.htmlspecialchars>{choiceValue}</f:format.htmlspecialchars>
		<td scope="row"><f:format.htmlspecialchars>{formField.label}</f:format.htmlspecialchars></td>
<f:format.htmlspecialchars>{formField.choicesArray.{formFieldValue.value}}</f:format.htmlspecialchars>
<f:format.htmlspecialchars>{formFieldValue.value}</f:format.htmlspecialchars>
<f:format.htmlspecialchars>{formFieldValue.value}</f:format.htmlspecialchars>
<f:format.htmlspecialchars>{formField.choicesArray.{formFieldValue.value}}</f:format.htmlspecialchars>
					<f:format.htmlspecialchars>{appointment.type.name}</f:format.htmlspecialchars>