Modernized script

This commit is contained in:
Daniel Winzen
2020-10-17 11:21:13 +02:00
parent 62f0e057f5
commit 0cb6055bd4

58
url.php
View File

@ -14,11 +14,13 @@ if(!empty($_REQUEST['r'])){
redirect($_REQUEST['r']); redirect($_REQUEST['r']);
} }
try{ try{
$db=new PDO("mysql:host='.DB_HOST.';dbname=" . DB_NAME . ';charset=' . DB_CHARSET, DB_USER, DB_PASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>true]); $db=new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=' . DB_CHARSET, DB_USER, DB_PASS, [PDO::ATTR_ERRMODE=>PDO::ERRMODE_WARNING, PDO::ATTR_PERSISTENT=>true]);
}catch(PDOException $e){ }catch(PDOException $e){
} }
if(empty($_GET['id'])){ if(empty($_GET['id'])){
echo '<!DOCTYPE html><html><head>'; $style = '.red{color:red}';
send_headers([$style]);
echo '<!DOCTYPE html><html lang="en"><head>';
echo '<title>URL-Shortener/Redirector</title>'; echo '<title>URL-Shortener/Redirector</title>';
echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">'; echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">';
echo '<meta name="author" content="Daniel Winzen">'; echo '<meta name="author" content="Daniel Winzen">';
@ -26,20 +28,19 @@ if(empty($_GET['id'])){
echo '</head><body>'; echo '</head><body>';
echo '<h1>URL-Shortener/Redirector</h1>'; echo '<h1>URL-Shortener/Redirector</h1>';
echo '<p>Shorten a URL or strip referrers by redirecting via '.CANONICAL_URL.'?r=LINK</p>'; echo '<p>Shorten a URL or strip referrers by redirecting via '.CANONICAL_URL.'?r=LINK</p>';
exit;
if(!isset($db)){ if(!isset($db)){
echo '<p><b style="color:red">ERROR:</b> No database connection!</p></div>'; echo '<p><b class="red">ERROR:</b> No database connection!</p></div>';
echo '</body></html>'; echo '</body></html>';
exit; exit;
} }
echo "<form action=\"$_SERVER[SCRIPT_NAME]\" method=\"POST\">"; echo '<form action="'.htmlspecialchars($_SERVER['SCRIPT_NAME']).'" method="POST">';
echo "<p>Link: <br><input name=\"addr\" size=\"30\" placeholder=\"$_SERVER[HTTP_HOST]\" value=\""; echo '<p>Link: <br><input name="addr" size="30" placeholder="'.htmlspecialchars($_SERVER['HTTP_HOST']).'" value="';
if(!empty($_POST['addr'])){ if(!empty($_POST['addr'])){
echo htmlspecialchars($_POST['addr']); echo htmlspecialchars($_POST['addr']);
} }
echo '" required></p>'; echo '" required></p>';
echo '<input type="submit" name="action" value="Shorten"></form><br>'; echo '<input type="submit" name="action" value="Shorten"></form><br>';
echo "<form action=\"$_SERVER[SCRIPT_NAME]\" method=\"POST\">"; echo '<form action="'.htmlspecialchars($_SERVER['SCRIPT_NAME']).'" method="POST">';
echo '<p>Show info of shortlink-ID: <br><input name="info" type="number" size="10" value="'; echo '<p>Show info of shortlink-ID: <br><input name="info" type="number" size="10" value="';
if(!empty($_POST['info'])){ if(!empty($_POST['info'])){
echo htmlspecialchars($_POST['info']); echo htmlspecialchars($_POST['info']);
@ -53,10 +54,10 @@ if(empty($_GET['id'])){
$stmt->execute([$_REQUEST['info']]); $stmt->execute([$_REQUEST['info']]);
if($url=$stmt->fetch(PDO::FETCH_ASSOC)){ if($url=$stmt->fetch(PDO::FETCH_ASSOC)){
$url=$url['url']; $url=$url['url'];
echo '<p>Short link is: <a href="'.CANONICAL_URL."?id=$_REQUEST[info]\" rel=\"nofollow\">".CANONICAL_URL."?id=$_REQUEST[info]</a></p>"; echo '<p role="alert">Short link is: <a href="'.CANONICAL_URL."?id=$_REQUEST[info]\" rel=\"nofollow\">".CANONICAL_URL."?id=$_REQUEST[info]</a></p>";
echo "<p>Redirects to: <a href=\"$url\" rel=\"nofollow\">$url</a></p>"; echo "<p role='alert'>Redirects to: <a href=\"$url\" rel=\"nofollow\">$url</a></p>";
}else{ }else{
echo '<p>Sorry, this redirect doesn\'t exist.</p>'; echo '<p role="alert">Sorry, this redirect doesn\'t exist.</p>';
} }
}elseif($_SERVER['REQUEST_METHOD']==='POST' && !empty($_POST['addr'])){ }elseif($_SERVER['REQUEST_METHOD']==='POST' && !empty($_POST['addr'])){
if(!( if(!(
@ -70,12 +71,12 @@ if(empty($_GET['id'])){
|| preg_match('~^((?:[a-z0-9\-]+\.)*[a-z2-7]{16}\.onion)(?![^<>]*>)$~i', $_POST['addr'])// *.onion || preg_match('~^((?:[a-z0-9\-]+\.)*[a-z2-7]{16}\.onion)(?![^<>]*>)$~i', $_POST['addr'])// *.onion
) )
){ ){
echo '<p style="color:red">ERROR: Invalid address given.</p>'; echo '<p class="red">ERROR: Invalid address given.</p>';
}else{ }else{
$id=$db->query("SELECT COUNT(*) FROM link;")->fetch(PDO::FETCH_NUM); $id=$db->query("SELECT COUNT(*) FROM link;")->fetch(PDO::FETCH_NUM);
$id=$id[0]+1; $id=$id[0]+1;
$db->prepare("INSERT INTO link (id, url) VALUES (?, ?);")->execute([$id, $_POST['addr']]); $db->prepare("INSERT INTO link (id, url) VALUES (?, ?);")->execute([$id, $_POST['addr']]);
echo '<p>Your link is: <a href="'.CANONICAL_URL."?id=$id\" rel=\"nofollow\">".CANONICAL_URL."?id=$id</a></p>"; echo '<p role="alert">Your link is: <a href="'.CANONICAL_URL."?id=$id\" rel=\"nofollow\">".CANONICAL_URL."?id=$id</a></p>";
} }
} }
echo '</body></html>'; echo '</body></html>';
@ -92,26 +93,47 @@ if(empty($_GET['id'])){
redirect($url); redirect($url);
} }
function redirect($url){ function redirect(string $url){
preg_match('~^(.*)://~', $url, $match); preg_match('~^(.*)://~', $url, $match);
$url=preg_replace('~^(.*)://~', '', $url); $url=preg_replace('~^(.*)://~', '', $url);
$escaped=htmlspecialchars($url); $escaped=htmlspecialchars($url);
send_headers();
if(isset($match[1]) && ($match[1]==='http' || $match[1]==='https')){ if(isset($match[1]) && ($match[1]==='http' || $match[1]==='https')){
header("Refresh: 0; URL=$match[0]$url"); header("Refresh: 0; URL=$match[0]$url");
echo '<!DOCTYPE html>'; echo '<!DOCTYPE html>';
echo "<html><head><meta http-equiv=\"Refresh\" content=\"0; url=$match[0]$escaped\">"; echo "<html lang='en'><head><meta http-equiv=\"Refresh\" content=\"0; url=$match[0]$escaped\">";
echo '<meta name="robots" content="noindex, nofollow"></head><body>'; echo '<meta name="robots" content="noindex, nofollow"></head><body>';
echo "<p>Redirecting to: <a href=\"$match[0]$escaped\" rel=\"nofollow\">$match[0]$escaped</a>.</p>"; echo "<p>Redirecting to: <a href=\"$match[0]$escaped\" rel=\"noopener nofollow\">$match[0]$escaped</a>.</p>";
echo '</body></html>'; echo '</body></html>';
}else{ }else{
if(!isset($match[0])){ if(!isset($match[0])){
$match[0]=''; $match[0]='';
} }
echo '<!DOCTYPE html>'; echo '<!DOCTYPE html>';
echo '<html><head><meta name="robots" content="noindex, nofollow"></head><body>'; echo '<html lang="en"><head><meta name="robots" content="noindex, nofollow"></head><body>';
echo "<p>Non-http link requested: <a href=\"$match[0]$escaped\" rel=\"nofollow\">$match[0]$escaped</a>.</p>"; echo "<p>Non-http link requested: <a href=\"$match[0]$escaped\" rel=\"noopener nofollow\">$match[0]$escaped</a>.</p>";
echo "<p>If it's not working, try this one: <a href=\"http://$escaped\" rel=\"nofollow\">http://$escaped</a>.</p>"; echo "<p>If it's not working, try this one: <a href=\"http://$escaped\" rel=\"noopener nofollow\">http://$escaped</a>.</p>";
echo '</body></html>'; echo '</body></html>';
} }
exit; exit;
} }
function send_headers(array $styles = []){
header('Content-Type: text/html; charset=UTF-8');
header('Pragma: no-cache');
header('Cache-Control: no-cache, no-store, must-revalidate, max-age=0, private');
header('Expires: 0');
header('Referrer-Policy: no-referrer');
header("Permissions-Policy: accelerometer 'none'; ambient-light-sensor 'none'; autoplay 'none'; battery 'none'; camera 'none'; cross-origin-isolated 'none'; display-capture 'none'; document-domain 'none'; encrypted-media 'none'; geolocation 'none'; fullscreen 'none'; execution-while-not-rendered 'none'; execution-while-out-of-viewport 'none'; gyroscope 'none'; magnetometer 'none'; microphone 'none'; midi 'none'; navigation-override 'none'; payment 'none'; picture-in-picture 'none'; publickey-credentials-get 'none'; screen-wake-lock 'none'; sync-xhr 'none'; usb 'none'; web-share 'none'; xr-spatial-tracking 'none'; clipboard-read 'none'; clipboard-write 'none'; gamepad 'none'; speaker-selection 'none'; conversion-measurement 'none'; focus-without-user-activation 'none'; hid 'none'; idle-detection 'none'; sync-script 'none'; vertical-scroll 'none'; serial 'none'; trust-token-redemption 'none';");
$style_hashes = '';
foreach($styles as $style) {
$style_hashes .= " 'sha256-".base64_encode(hash('sha256', $style, true))."'";
}
header("Content-Security-Policy: base-uri 'self'; default-src 'none'; form-action 'self'; frame-ancestors 'none'; style-src $style_hashes");
header('X-Content-Type-Options: nosniff');
header('X-Frame-Options: deny');
header('X-XSS-Protection: 1; mode=block');
if($_SERVER['REQUEST_METHOD'] === 'HEAD'){
exit; // headers sent, no further processing needed
}
}