CVE-2016-5731: Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting') (CWE-79)
value: Cross-site scripting (XSS) vulnerability in examples/openid.php in phpMyAdmin 4.0.x before 4.0.10.16, 4.4.x before 4.4.15.7, and 4.6.x before 4.6.3 allows remote attackers to inject arbitrary web script or HTML via vectors involving an OpenID error message.
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: 2016-07-03T01:59Z
Repository: https://github.com/phpmyadmin/phpmyadmin
Language: PHP
Files changed: examples/openid.php
Commit date: 2016-06-17 14:34:50 +0200
Commit message: Add error handling to constructing openid message

Signed-off-by: Michal Čihař <michal@cihar.com>

Diff: diff --git a/examples/openid.php b/examples/openid.php
index a15189b37af99..8ef34e9ee34d5 100644
--- a/examples/openid.php
+++ b/examples/openid.php
@@ -61,10 +61,20 @@ function Show_page($contents)
     </body>
     </html>
     <?php
 }
 
+function Die_error($e)
+{
+    $contents = "<div class='relyingparty_results'>\n";
+    $contents .= "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>\n";
+    $contents .= "</div class='relyingparty_results'>";
+    Show_page($contents);
+    exit;
+}
+
+
 /* Need to have cookie visible from parent directory */
 session_set_cookie_params(0, '/', '', false);
 /* Create signon session */
 $session_name = 'SignonSession';
 session_name($session_name);
@@ -108,27 +118,19 @@ function Show_page($contents)
 
 /* Create OpenID object */
 try {
     $o = new OpenID_RelyingParty($returnTo, $realm, $identifier);
 } catch (Exception $e) {
-    $contents = "<div class='relyingparty_results'>\n";
-    $contents .= "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>\n";
-    $contents .= "</div class='relyingparty_results'>";
-    Show_page($contents);
-    exit;
+    Die_error($e);
 }
 
 /* Redirect to OpenID provider */
 if (isset($_POST['start'])) {
     try {
         $authRequest = $o->prepare();
     } catch (Exception $e) {
-        $contents = "<div class='relyingparty_results'>\n";
-        $contents .= "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>\n";
-        $contents .= "</div class='relyingparty_results'>";
-        Show_page($contents);
-        exit;
+        Die_error($e);
     }
 
     $url = $authRequest->getAuthorizeURL();
 
     header("Location: $url");
@@ -141,11 +143,15 @@ function Show_page($contents)
         // I hate php sometimes
         $queryString = file_get_contents('php://input');
     }
 
     /* Check reply */
-    $message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
+    try {
+        $message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
+    } catch (Exception $e) {
+        Die_error($e);
+    }
 
     $id = $message->get('openid.claimed_id');
 
     if (!empty($id) && isset($AUTH_MAP[$id])) {
         $_SESSION['PMA_single_signon_user'] = $AUTH_MAP[$id]['user'];

Vulnerable code:     $contents = "<div class='relyingparty_results'>\n";
    $contents .= "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>\n";
    $contents .= "</div class='relyingparty_results'>";
    Show_page($contents);
    exit;
        $contents = "<div class='relyingparty_results'>\n";
        $contents .= "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>\n";
        $contents .= "</div class='relyingparty_results'>";
        Show_page($contents);
        exit;
    $message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
Fixed code: function Die_error($e)
{
    $contents = "<div class='relyingparty_results'>\n";
    $contents .= "<pre>" . htmlspecialchars($e->getMessage()) . "</pre>\n";
    $contents .= "</div class='relyingparty_results'>";
    Show_page($contents);
    exit;
}


    Die_error($e);
        Die_error($e);
    try {
        $message = new OpenID_Message($queryString, OpenID_Message::FORMAT_HTTP);
    } catch (Exception $e) {
        Die_error($e);
    }