Das gezeigte Skript vermeidet zwar (viele) Angriffe auf den lokalen Rechner (DDoS wäre noch möglich...) aber
Wenn Du das Skript verwendest, dann solltest Du
- Einen serverseitigen Cache vorsehen, um ggf. Missbrauch(DDoS zu vermeiden.
- Verhindern, dass ungültige URLs (Protokolle. Hostnamen) eingegeben werden.
- URL-Parameter (alles hinter dem ersten Fragezeichen) sollten blockiert werden. Ansonsten könnte das böse Jungs auf die Idee bringen, den Dienst für Angriffe auf Dritte zu missbrauchen und also die Herkunft des Angriffs zu verschleiern.
- Ich würde URL-Parameter also nur angemeldeten und mir bekannten Benutzern erlauben.
<?php
define ( 'ALLOW_PARAMS', false );
define (
'options',
[
'content_type',
'http_code',
'http_connect',
'http_version',
'num_connects',
'num_redirects',
'redirect_url',
'remote_ip',
'remote_port',
'scheme',
'size_download',
'size_header',
'size_request',
'speed_download',
'time_appconnect',
'time_connect',
'time_namelookup',
'time_pretransfer',
'time_redirect',
'time_starttransfer',
'time_total',
'url_effective'
]
);
# Für Tests in der Konsole:
if ( ! isset( $_GET['URL'] ) ) {
$_GET['URL'] = 'https://www.example.com/';
#$_GET['URL'] = 'https://www.%example.com/';
#$_GET['URL'] = 'https://www.example.com/?foo=bar';
}
@list( $REST, $DELETED ) = explode('#', trim( $_GET['URL'], 2 ) );
@list( $REST, $GET_PARAMS ) = explode('?', trim( $REST, 2 ) );
$REST = strtolower( $REST );
@list( $PROTO, $REST ) = explode( '://', $REST, 2 );
@list( $HOST, $RESSOURCE ) = explode( '/', $REST, 2 );
$t = preg_replace( '/[^\p{L}\p{N}\._-]/', '', $HOST );
if ( $t != $HOST ) {
http_response_code ( 403 );
echo '<h1>Nice Try</h1><hr>';
trigger_error('Nicht erlaubtes Zeichen in URL: "' . $_GET['URL'] . '"', E_USER_ERROR );
}
if (
'http' != $PROTO
and 'https' != $PROTO
) {
http_response_code ( 404 );
echo '<h1>Falsches Protokoll</h1><hr><p>Gehen Sie zurück und geben Sie "http://" oder "https://" als Protokoll an.</p>';
exit;
}
if (
! ALLOW_PARAMS
and $GET_PARAMS
) {
http_response_code ( 403 );
echo '<h1>Verboten: URL enthält Parameter</h1><hr><p>Bitte gehen Sie zurück und geben Sie eine URL ohne Parameter an.</p>';
exit;
}
if ( false == dns_get_record( $HOST ) ) {
http_response_code ( 404 );
echo '<h1>Hostname unbekannt</h1><hr><p>Für den Hostname konnte kein DNS-Rekord ermittelt werden.</p>';
exit;
}
$_GET['URL'] = $PROTO . '://' . $HOST . '/' . $RESSOURCE;
if (
ALLOW_PARAMS
and isset( $GET_PARAMS )
and $GET_PARAMS
) {
$_GET['URL'] = $_GET['URL'] . '?' . $GET_PARAMS;
}
$curl_options = [];
$grepHelper = '___THIS_IS_ONLY_FOR_GREP___';
foreach ( options as $s ) {
$curl_options[] = $grepHelper . $s . ':%{' . $s. '}';
}
$curl_options = implode('\n', $curl_options );
$sys = 'LANG=C curl -s -I --write-out "'
. $curl_options . '" '
. escapeshellarg( $_GET['URL'] )
. ' 2> /dev/null | grep "^' . $grepHelper . '";'
;
$ret = `$sys`;
$ar = explode( "\n", $ret );
$erg = [];
foreach ( $ar as $row ) {
$row = trim( str_replace( $grepHelper, '', $row ) );
if ( $row ) {
list( $name, $value ) = explode( ':', $row, 2);
$erg[$name] = $value;
}
}
print_r( $erg );