CVE-2023-4432: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Cross-site Scripting (XSS) - Reflected in GitHub repository cockpit-hq/cockpit prior to 2.6.4.
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-08-19T01:15Z
Repository: https://github.com/cockpit-hq/cockpit
Language: PHP
Files changed: CHANGELOG.md, modules/System/views/api/graphql-viewer.php, modules/System/views/api/rest-api-viewer.php
Commit date: 2023-08-19 02:51:12 +0200
Commit message: Fix possible Cross-site Scripting (XSS) in Rest/GraphQL viewer

Diff: diff --git a/CHANGELOG.md b/CHANGELOG.md
index fe9f6277a..931f15c8f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,11 @@
 # Release Notes
 
 ## WIP
 
 - Fix mime type detection on asset upload
+- Fix possible Cross-site Scripting (XSS) in Rest/GraphQL viewer
 
 ## 2.6.3 (2023-08-15)
 
 - Prevent uploading .phps + .(x)html files in assets manager
 - Require verification for updating user data
diff --git a/modules/System/views/api/graphql-viewer.php b/modules/System/views/api/graphql-viewer.php
index cdb324968..80ad6f757 100644
--- a/modules/System/views/api/graphql-viewer.php
+++ b/modules/System/views/api/graphql-viewer.php
@@ -110,11 +110,11 @@
         document.body,
       );
 
   </script>
 
-  <input id="apiKey" type="text" placeholder="API Key" value="<?=($apiKey ? $apiKey : '')?>">
+  <input id="apiKey" type="text" placeholder="API Key" value="<?=$this->escape($apiKey ? $apiKey : '')?>">
 
 <style>
 
 /* GraphiQL One Dark Alt (Dark Mode) theme by Ben Keating[1]
  * Colors taken from Atom's One Dark theme[2]. Add this file to the end of
@@ -221,11 +221,11 @@ color: #CACDD3;
 
 .graphiql-container .execute-button {
   background: #10131a;
   border: 1px solid <?=($primaryColor ? $primaryColor : '#0e8fff')?>;
   box-shadow: none !important;
-  fill: <?=($primaryColor ? $primaryColor : '#0e8fff')?>;
+  fill: <?= $this->escape($primaryColor ? $primaryColor : '#0e8fff')?>;
 }
 
 .graphiql-container .history-contents p {
   border: none;
 }
diff --git a/modules/System/views/api/rest-api-viewer.php b/modules/System/views/api/rest-api-viewer.php
index d6ed5a5c0..6b8e6b243 100644
--- a/modules/System/views/api/rest-api-viewer.php
+++ b/modules/System/views/api/rest-api-viewer.php
@@ -3,25 +3,25 @@
 <head>
     <title>REST - Api</title>
 </head>
 <body>
     <rapi-doc
-        spec-url="<?=$openApiUrl?>"
+        spec-url="<?=$this->escape($openApiUrl)?>"
         show-header="false"
         show-info="false"
         render-style="read"
         load-fonts="false"
 
         <?php if($apiKey): ?>
         api-key-name = "api-key"
         api-key-location = "header"
-        api-key-value = "<?=$apiKey?>"
+        api-key-value = "<?=$this->escape($apiKey)?>"
         <?php endif ?>
 
-        bg-color="<?=($bgColor ? $bgColor : '#10131a')?>"
-        text-color="<?=($textColor ? $textColor : '#fafafa')?>"
-        primary-color="<?=($primaryColor ? $primaryColor : '#0e8fff')?>"
+        bg-color="<?=$this->escape($bgColor ? $bgColor : '#10131a')?>"
+        text-color="<?= $this->escape($textColor ? $textColor : '#fafafa')?>"
+        primary-color="<?= $this->escape($primaryColor ? $primaryColor : '#0e8fff')?>"
     ></rapi-doc>
 
     <script type="module" src="<?=$this->base('system:assets/vendor/rapidoc.js')?>"></script>
 </body>
 </html>

Vulnerable code:   <input id="apiKey" type="text" placeholder="API Key" value="<?=($apiKey ? $apiKey : '')?>">
  fill: <?=($primaryColor ? $primaryColor : '#0e8fff')?>;
        spec-url="<?=$openApiUrl?>"
        api-key-value = "<?=$apiKey?>"
        bg-color="<?=($bgColor ? $bgColor : '#10131a')?>"
        text-color="<?=($textColor ? $textColor : '#fafafa')?>"
        primary-color="<?=($primaryColor ? $primaryColor : '#0e8fff')?>"
Fixed code: - Fix possible Cross-site Scripting (XSS) in Rest/GraphQL viewer
  <input id="apiKey" type="text" placeholder="API Key" value="<?=$this->escape($apiKey ? $apiKey : '')?>">
  fill: <?= $this->escape($primaryColor ? $primaryColor : '#0e8fff')?>;
        spec-url="<?=$this->escape($openApiUrl)?>"
        api-key-value = "<?=$this->escape($apiKey)?>"
        bg-color="<?=$this->escape($bgColor ? $bgColor : '#10131a')?>"
        text-color="<?= $this->escape($textColor ? $textColor : '#fafafa')?>"
        primary-color="<?= $this->escape($primaryColor ? $primaryColor : '#0e8fff')?>"