Proyectos de Subversion Moodle

Rev

Rev 1 | Mostrar el archivo completo | | | Autoría | Ultima modificación | Ver Log |

Rev 1 Rev 1441
Línea 53... Línea 53...
53
        'http' => 80,
53
        'http' => 80,
54
        'https' => 443
54
        'https' => 443
55
    ];
55
    ];
Línea 56... Línea 56...
56
 
56
 
-
 
57
    /**
-
 
58
     * @var string the host of the URL being checked by the helper.
-
 
59
     */
-
 
60
    protected $host;
-
 
61
 
-
 
62
    /**
-
 
63
     * @var array IP address or addresses the URL is allowed to be requested from (passed the blocked hosts check).
-
 
64
     */
-
 
65
    protected $allowedips = [];
-
 
66
 
-
 
67
    /**
-
 
68
     * @var ?int The port the URL is allowed to be requested from (passed the allowed port check).
-
 
69
     */
-
 
70
    protected $allowedport;
-
 
71
 
57
    /**
72
    /**
58
     * Checks whether the given URL is blocked by checking its address and port number against the allow/block lists.
73
     * Checks whether the given URL is blocked by checking its address and port number against the allow/block lists.
59
     * The behaviour of this function can be classified as strict, as it returns true for URLs which are invalid or
74
     * The behaviour of this function can be classified as strict, as it returns true for URLs which are invalid or
60
     * could not be parsed, as well as those valid URLs which were found in the blocklist.
75
     * could not be parsed, as well as those valid URLs which were found in the blocklist.
61
     *
76
     *
Línea 83... Línea 98...
83
        } catch (\moodle_exception $e) {
98
        } catch (\moodle_exception $e) {
84
            // Moodle exception is thrown if the $urlstring is invalid. Treat as blocked.
99
            // Moodle exception is thrown if the $urlstring is invalid. Treat as blocked.
85
            return true;
100
            return true;
86
        }
101
        }
Línea -... Línea 102...
-
 
102
 
-
 
103
        $this->host = $parsed['host'];
87
 
104
 
88
        // The port will be empty unless explicitly set in the $url (uncommon), so try to infer it from the supported schemes.
105
        // The port will be empty unless explicitly set in the $url (uncommon), so try to infer it from the supported schemes.
89
        if (!$parsed['port'] && $parsed['scheme'] && isset($this->transportschemes[$parsed['scheme']])) {
106
        if (!$parsed['port'] && $parsed['scheme'] && isset($this->transportschemes[$parsed['scheme']])) {
90
            $parsed['port'] = $this->transportschemes[$parsed['scheme']];
107
            $parsed['port'] = $this->transportschemes[$parsed['scheme']];
Línea 160... Línea 177...
160
                // If we don't get a valid record, bail (so cURL is never called).
177
                // If we don't get a valid record, bail (so cURL is never called).
161
                if (!$hostips) {
178
                if (!$hostips) {
162
                    return true;
179
                    return true;
163
                }
180
                }
Línea 164... Línea 181...
164
 
181
 
-
 
182
                // If any of the returned IPs are in the blocklist, block the request. Otherwise, temporarily record the IPs.
165
                // If any of the returned IPs are in the blocklist, block the request.
183
                $allowedips = [];
166
                foreach ($hostips as $hostip) {
184
                foreach ($hostips as $hostip) {
167
                    if ($this->address_explicitly_blocked($hostip)) {
185
                    if ($this->address_explicitly_blocked($hostip)) {
168
                        return true;
186
                        return true;
-
 
187
                    }
169
                    }
188
                    $allowedips[] = $hostip;
-
 
189
                }
-
 
190
 
-
 
191
                // If none of the IPs are blocked, set them on the allow list so we can enforce them on subsequent requests.
170
                }
192
                $this->allowedips = $allowedips;
171
            }
193
            }
172
        } else {
194
        } else {
173
            // Was not something we consider to be a valid IP or domain name, block it.
195
            // Was not something we consider to be a valid IP or domain name, block it.
174
            return true;
196
            return true;
Línea 199... Línea 221...
199
        // Intentionally block port 0 and below and check the int cast was valid.
221
        // Intentionally block port 0 and below and check the int cast was valid.
200
        if (empty($port) || (string)$portnum !== (string)$port || $port < 0) {
222
        if (empty($port) || (string)$portnum !== (string)$port || $port < 0) {
201
            return true;
223
            return true;
202
        }
224
        }
203
        $allowedports = $this->get_allowed_ports();
225
        $allowedports = $this->get_allowed_ports();
-
 
226
 
204
        return !empty($allowedports) && !in_array($portnum, $allowedports);
227
        $isblocked = !empty($allowedports) && !in_array($portnum, $allowedports);
-
 
228
 
-
 
229
        // If port is allowed, add it to our allow list so we can enforce it on subsequent requests.
-
 
230
        if (!$isblocked) {
-
 
231
            $this->allowedport = $portnum;
-
 
232
        }
-
 
233
 
-
 
234
        return $isblocked;
205
    }
235
    }
Línea 206... Línea 236...
206
 
236
 
207
    /**
237
    /**
208
     * Convenience method to check whether we have any entries in the host blocklist or ports allowlist admin settings.
238
     * Convenience method to check whether we have any entries in the host blocklist or ports allowlist admin settings.
Línea 289... Línea 319...
289
        }
319
        }
290
        return array_filter(array_map('trim', explode("\n", $CFG->curlsecurityblockedhosts)), function($entry) {
320
        return array_filter(array_map('trim', explode("\n", $CFG->curlsecurityblockedhosts)), function($entry) {
291
            return !empty($entry);
321
            return !empty($entry);
292
        });
322
        });
293
    }
323
    }
-
 
324
 
-
 
325
    /**
-
 
326
     * Helper that returns host, IP and port information for the URL that has passed the blocked hosts/allowed ports checks.
-
 
327
     *
-
 
328
     * This data is in a format compatible with CURLOPT_RESOLVE, so it can be passed directly into that option.
-
 
329
     * Doing so will prevent cURL re-fetching the info from DNS, preventing subsequent requests to the remote host from
-
 
330
     * modifying the IP/port to ones that haven't been validated.
-
 
331
     *
-
 
332
     * @return array of strings in the format hostname:port:ip_address.
-
 
333
     * @throws \coding_exception
-
 
334
     */
-
 
335
    public function get_resolve_info(): array {
-
 
336
        if (empty($this->host || empty($this->allowedips) || empty($this->allowedport))) {
-
 
337
            $exception = 'In the curl_security_helper class, url_is_blocked() must be called before get_resolve_info() is called.';
-
 
338
            throw new \core\exception\coding_exception($exception);
-
 
339
        }
-
 
340
 
-
 
341
        return array_map(fn($ip) => "$this->host:$this->allowedport:$ip", $this->allowedips);
-
 
342
    }
294
}
343
}