From: Antonio Ospite Date: Sun, 30 Oct 2016 10:34:22 +0000 (+0100) Subject: Fix information leakage by validating the URL scheme X-Git-Tag: v1.0.0~14 X-Git-Url: https://git.ao2.it/tweeper.git/commitdiff_plain/21601a9299810f223341ff4bed4f9649f5ea0359 Fix information leakage by validating the URL scheme Validate the scheme to prevent leaking information by abusing the file:// scheme. Before this change it was possible to see what files are available on the system running tweeper. The script in tests/test_information_leakage.sh shows the problem on earlier versions. Here is an execution with tweeper-0.6: ----------------------------------------------------------------------- URL file://twitter.com//etc/passwd --> /etc/passwd exists URL file://twitter.com//etc/file_with_an_unlikely_name ... /etc/file_with_an_unlikely_name does not exist Staring a test server URL file://twitter.com//etc/passwd --> /etc/passwd on http://localhost:8000 exists URL file://twitter.com//etc/file_with_an_unlikely_name ... /etc/file_with_an_unlikely_name on http://localhost:8000 does not exist Shutting down the test server ----------------------------------------------------------------------- Here is an execution after this fix: ----------------------------------------------------------------------- PHP Fatal error: unsupported scheme: file in /home/ao2/Proj/Tweeper/tweeper/tweeper.php on line 323 URL file://twitter.com//etc/passwd ... /etc/passwd does not exist PHP Fatal error: unsupported scheme: file in /home/ao2/Proj/Tweeper/tweeper/tweeper.php on line 323 URL file://twitter.com//etc/file_with_an_unlikely_name ... /etc/file_with_an_unlikely_name does not exist Staring a test server URL file://twitter.com//etc/passwd ... /etc/passwd on http://localhost:8000 does not exist URL file://twitter.com//etc/file_with_an_unlikely_name ... /etc/file_with_an_unlikely_name on http://localhost:8000 does not exist Shutting down the test server ----------------------------------------------------------------------- --- diff --git a/tests/test_information_leakage.sh b/tests/test_information_leakage.sh new file mode 100755 index 0000000..061d917 --- /dev/null +++ b/tests/test_information_leakage.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +set -e + +TWEEPER="/usr/share/php/tweeper/tweeper" +#TWEEPER="./tweeper" + +check_result() { + URL="$1" + FILE="$2" + RESULT="$3" + + echo "URL $URL" + if [ "$RESULT" ]; + then + echo "--> $FILE" + echo " exists" + else + echo "... $FILE" + echo " does not exist" + fi + echo +} + +file_exists() { + FILE="$1" + URL="file://twitter.com/$FILE" + OUTPUT=$($TWEEPER $URL) + check_result "$URL" "$FILE" "$OUTPUT" +} + +file_exists_on_server() { + SERVER="$1" + FILE="$2" + URL="file://twitter.com/$FILE" + OUTPUT=$(curl $SERVER/tweeper.php?src_url=$URL 2> /dev/null) + check_result "$URL" "$FILE on $SERVER" "$OUTPUT" +} + +file_exists /etc/passwd || true +file_exists /etc/file_with_an_unlikely_name || true + +echo "Staring a test server" +echo + +php -S localhost:8000 -t $(dirname $TWEEPER) > /dev/null 2>&1 & +SERVER_PID=$! +sleep 1 + +file_exists_on_server http://localhost:8000 /etc/passwd || true +file_exists_on_server http://localhost:8000 /etc/file_with_an_unlikely_name || true + +echo "Shutting down the test server" +kill $SERVER_PID diff --git a/tweeper.php b/tweeper.php index 0955a11..87efd60 100644 --- a/tweeper.php +++ b/tweeper.php @@ -318,6 +318,12 @@ class Tweeper { return NULL; } + $scheme = $url["scheme"]; + if (!in_array($scheme, array("http", "https"))) { + trigger_error("unsupported scheme: $scheme", E_USER_ERROR); + return NULL; + } + // Strip the leading www. to be more forgiving on input URLs. $host = preg_replace('/^www\./', '', $url["host"]);