Issues (51)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

updateidplist/index.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * /updateidplist/
5
 *
6
 * The '/updateidplist/' endpoint updates the CILogon idplist.xml and
7
 * idplist.json files. These are 'pared down' versions of the IdP-specific
8
 * InCommon-metadata.xml file, extracting just the useful portions of XML
9
 * for display on CILogon. This endpoint downloads the InCommon metadata and
10
 * creates both idplist.xml and idplist.json. It then looks for existing
11
 * idplist.{json,xml} files and sees if there are any differences. If so,
12
 * it prints out the differences and sends email. It also checks for newly
13
 * added IdPs and sends email. Finally, it copies the newly created idplist
14
 * files to the old location.
15
 */
16
17
// error_reporting(E_ALL); ini_set('display_errors',1);
18
19
require_once __DIR__ . '/../vendor/autoload.php';
20
require_once __DIR__ . '/../config.php';
21
include_once __DIR__ . '/../config.secrets.php';
22
23
use CILogon\Service\Util;
24
use CILogon\Service\Content;
25
use CILogon\Service\IdpList;
26
27
Util::startPHPSession();
28
29
// Use a semaphore to prevent multiple processes running at the same time
30
$idplist_dir = dirname(DEFAULT_IDP_JSON);
31
$last_checked = $idplist_dir . '/.last_checked';
32
$key = ftok($last_checked, '1');
33
$semaphore = sem_get($key, 1);
34
if (@sem_acquire($semaphore, 1) === false) {
35
    echo "<p>Another process is running.</p>\n";
36
    return;
37
}
38
39
// Declare a few configuration constants
40
$mailto = EMAIL_ALERTS;
41
$mailtoidp = defined('EMAIL_IDP_UPDATES') ?
42
    EMAIL_ALERTS . ',' . EMAIL_IDP_UPDATES : '';
43
$mailfrom = 'From: ' . EMAIL_ALERTS . "\r\n" . 'X-Mailer: PHP/' . phpversion();
44
$check_timeout = 300; // in seconds
45
$httphost = Util::getHN();
46
47
// Load the '.last_checked' file and find the last time the endpoint
48
// was hit. If the file doesn't exist, then this is the first time.
49
// If the last time checked is less than a timeout, do nothing.
50
$lastcheck = file_get_contents($last_checked);
51
$difftime = abs(time() - (int)$lastcheck);
52
if ($difftime < $check_timeout) {
53
    echo "<p>Please wait " . ($check_timeout - $difftime) . " seconds.</p>\n";
54
    return;
55
}
56
57
// Download InCommon metadata to a new temporary directory in /tmp/.
58
// Be sure to delete the temporary directory before script exit.
59
$incommon_url = 'https://mdq.incommon.org/entities/idps/all';
60
$tmpdir = '';
61
$tmpincommon = '';
62
if (($incommon_xml = file_get_contents($incommon_url)) === false) {
63
    $errmsg = "Error: Unable to download InCommon-metadata.xml.";
64
    echo "<p>$errmsg</p>\n";
65
    mail($mailto, "/updateidplist/ failed on $httphost", $errmsg, $mailfrom);
66
    http_response_code(500);
67
    return;
68
} else {
69
    $tmpdir = Util::tempDir('/tmp/');
70
    $tmpincommon = $tmpdir . '/InCommon-metadata.xml';
71
    if ((file_put_contents($tmpincommon, $incommon_xml)) === false) {
72
        $errmsg = "Error: Unable to save InCommon-metadata.xml to temporary directory.";
73
        echo "<p>$errmsg</p>\n";
74
        mail($mailto, "/updateidplist/ failed on $httphost", $errmsg, $mailfrom);
75
        http_response_code(500);
76
        Util::deleteDir($tmpdir);
77
        return;
78
    }
79
}
80
81
// Now, create new idplist.xml and idplist.json files from the
82
// InCommon Metadata.
83
$tmpxml = $tmpdir . '/idplist.xml';
84
$idplist = new IdpList($tmpxml, $tmpincommon, false, 'xml');
85
$idplist->create();
86
if (!$idplist->write('xml')) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $idplist->write('xml') of type boolean|null is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
87
    $errmsg = "Error: Unable to create temporary idplist.xml file.";
88
    echo "<p>$errmsg</p>\n";
89
    mail($mailto, "/updateidplist/ failed on $httphost", $errmsg, $mailfrom);
90
    http_response_code(500);
91
    Util::deleteDir($tmpdir);
92
    return;
93
}
94
$tmpjson = $tmpdir . '/idplist.json';
95
$idplist->setFilename($tmpjson);
96
if (!$idplist->write('json')) {
97
    $errmsg = "Error: Unable to create temporary idplist.json file.";
98
    echo "<p>$errmsg</p>\n";
99
    mail($mailto, "/updateidplist/ failed on $httphost", $errmsg, $mailfrom);
100
    http_response_code(500);
101
    Util::deleteDir($tmpdir);
102
    return;
103
}
104
105
// Try to read in an existing idplist.xml file so we can do a 'diff' later.
106
$idpxml_filename = preg_replace('/\.json$/', '.xml', DEFAULT_IDP_JSON);
107
$oldidplist = new IdpList($idpxml_filename, '', false, 'xml');
108
109
// If we successfully read in an existing idplist.xml file,
110
// check for differences, and also look for newly added IdPs.
111
$oldidplistempty = true;
112
$oldidplistdiff = false;
113
$newidpemail = '';
114
if (!empty($oldidplist->idparray)) {
115
    $oldidplistempty = false;
116
117
    // Check for differences using weird json_encode method found at
118
    // https://stackoverflow.com/a/42530586/12381604
119
    $diffarray = array_map(
120
        'json_decode',
121
        array_merge(
122
            array_diff(
123
                array_map('json_encode', $idplist->idparray),
124
                array_map('json_encode', $oldidplist->idparray)
125
            ),
126
            array_diff(
127
                array_map('json_encode', $oldidplist->idparray),
128
                array_map('json_encode', $idplist->idparray)
129
            )
130
        )
131
    );
132
133
    if (!empty($diffarray)) {
134
        $oldidplistdiff = true;
135
136
        // Check to see if any new IdPs were added to the InCommon metadata.
137
        $newIdPList = array();
138
        $oldEntityIDList = $oldidplist->getEntityIDs();
139
        if (!empty($oldEntityIDList)) {
140
            $entityIDList = $idplist->getEntityIDs();
141
            foreach ($entityIDList as $value) {
142
                if (!in_array($value, $oldEntityIDList)) {
143
                    $newIdPList[$value] = 1;
144
                }
145
            }
146
        }
147
148
        // If we found some new InCommon metadata entries, save them in a
149
        // string to be sent to [email protected].
150
        if (!empty($newIdPList)) {
151
            $plural = (count($newIdPList) > 1);
152
            $newidpemail .= ($plural ? 'New' : 'A new') . ' Identity Provider' .
153
                 ($plural ? 's were' : ' was') . ' found in metadata ' .
154
                 "and added to the \nlist of available IdPs.\n" .
155
                 '--------------------------------------------------------------' .
156
                 "\n\n";
157
            foreach ($newIdPList as $entityID => $value) {
158
                $newidpemail .= "EntityId               = $entityID\n";
159
                $newidpemail .= "Organization Name      = " .
160
                    $idplist->getOrganizationName($entityID) . "\n";
161
                $newidpemail .= "Display Name           = " .
162
                    $idplist->getDisplayName($entityID) . "\n";
163
                if ($idplist->isRegisteredByInCommon($entityID)) {
164
                    $newidpemail .= "Registered by InCommon = Yes\n";
165
                }
166
                if ($idplist->isInCommonRandS($entityID)) {
167
                    $newidpemail .= "InCommon R & S         = Yes\n";
168
                }
169
                if ($idplist->isREFEDSRandS($entityID)) {
170
                    $newidpemail .= "REFEDS R & S           = Yes\n";
171
                }
172
                if ($idplist->isSIRTFI($entityID)) {
173
                    $newidpemail .= "SIRTFI                 = Yes\n";
174
                }
175
                $newidpemail .= "\n";
176
            }
177
        }
178
    }
179
}
180
181
// If we found new IdPs, print them out and send email (if on prod).
182
if (strlen($newidpemail) > 0) {
183
    echo "<xmp>\n";
184
    echo $newidpemail;
185
    echo "</xmp>\n";
186
187
    if (strlen($mailtoidp) > 0) {
188
        // Send "New IdPs Added" email only from production server
189
        if (
190
            ($httphost == 'cilogon.org') ||
191
            ($httphost == 'polo1.cilogon.org')
192
        ) {
193
            mail(
194
                $mailtoidp,
195
                "CILogon Service on $httphost - New IdP Automatically Added",
196
                $newidpemail,
197
                $mailfrom
198
            );
199
        }
200
    }
201
}
202
203
// If other differences were found, do an actual 'diff' and send email.
204
if ($oldidplistdiff) {
205
    $idpdiff = `diff -u $idpxml_filename $tmpxml 2>&1`;
206
    echo "<xmp>\n\n";
207
    echo $idpdiff;
208
    echo "</xmp>\n";
209
210
    mail(
211
        $mailto,
212
        "idplist.xml changed on $httphost",
213
        "idplist.xml changed on $httphost\n\n" . $idpdiff,
214
        $mailfrom
215
    );
216
}
217
218
// Copy temporary idplist.{json,xml} files to production directory.
219
if ($oldidplistempty || $oldidplistdiff) {
220
    if (copy($tmpxml, $idplist_dir . '/idplist.xml')) {
221
        chmod($idpxml_filename, 0664);
222
        chgrp($idpxml_filename, 'apache');
223
    } else {
224
        $errmsg = "Error: Unable to copy idplist.xml to destination.";
225
        echo "<p>$errmsg</p>\n";
226
        mail($mailto, "/updateidplist/ failed on $httphost", $errmsg, $mailfrom);
227
        http_response_code(500);
228
        Util::deleteDir($tmpdir);
229
        return;
230
    }
231
    if (copy($tmpjson, $idplist_dir . '/idplist.json')) {
232
        chmod(DEFAULT_IDP_JSON, 0664);
233
        chgrp(DEFAULT_IDP_JSON, 'apache');
234
    } else {
235
        $errmsg = "Error: Unable to copy idplist.json to destination.";
236
        echo "<p>$errmsg</p>\n";
237
        mail($mailto, "/updateidplist/ failed on $httphost", $errmsg, $mailfrom);
238
        http_response_code(500);
239
        Util::deleteDir($tmpdir);
240
        return;
241
    }
242
243
    if ($oldidplistempty) {
244
        echo "<h3>New idplist.{json,xml} files were created.</h3>\n";
245
    } else {
246
        echo "<h3>Existing idplist.{json,xml} files were updated.</h3>\n";
247
    }
248
} else {
249
    echo "<p>No change detected in InCommon metadata.</p>\n";
250
}
251
252
// Final clean up. Delete the tempdir for the InCommon-metadata.xml and
253
// write the current time to .last_checked.
254
Util::deleteDir($tmpdir);
255
file_put_contents($last_checked, time());
256
@sem_release($semaphore);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
257