• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

get variablen verschlüsseln

mustang

Mitglied
hallo leute,

ich habe auf meiner seite einige daten, die ich per get übergebe (lässt sich auch nicht ändern). ich möchte aber nicht, dass der user diese getvariablen sieht, bzw nicht weiß, was da übergeben wird.

ich habe nun schon einige lösungen im internet gefunden. unteranderem die variablen vor dem verwenden mit base64 zu verschlüsseln und danach wieder zu entschüsseln, oder ein frameset zu verwenden.

die sache mit der base64-veschlüsselung finde ich aber recht nervig, da ich meine komplette seite nach übergebenen variablen durchsuchen müsste und jedesmal die get-parameter ändern müsste. außerdem sieht jeder trotzdem die verschlüsselung.
beim frameset ist das schon wieder besser. da sieht man das ganze nicht auf den ersten blick. aber leider nur auf den ersten, denn alle leute, die sich einigermaßen auskennen, können auch ohne frameset auf meine seite zugreifen und sich die variablen anschauen.

gibt es vielleicht noch eine elegantere variante?
 
ist mir auch grad eingefallen. wollte das grad noch ändern, da hattest du aber schon gepostet^^

also es sind keine abolut geheimen daten, aber ich möchte nicht, dass ein user sofort meinen seitenaufbau, etc. erkennt. also wenn jemand will, soll er sich die mühe machen das ganze zu decoden, dann ist er happy und fertig, aber es soll nicht direkt ersichtlich sein, was gemacht wird.
insofern finde ich die idee mit base64 ganz ok, aber alles get's suchen, habe ich nicht wirklich lust, bzw. hoffe ich, dass es eine generelle verschlüsselung gibt. irgendwas, was get automatisch verschlüsselt und wieder entschlüsselt.
 
Nenne lieber die genauen Gründe und versuch gar nicht erst weiter drüber Nachzudenken. ;P
Die meisten solcher Ideen die man hat sind einfach nur unnötig. ^^

//Edit:
Was sind es genau für Daten die du verschlüsseln willst?
 
also ich übergebe zum beispiel den seitenname (da die seite komplett auf einer datenbank aufbaut), daten, welche unterseite genau aufgerufen werden soll, wenn etwas gelöscht wird, was gelöscht wird, welche aktion ausgeführt werden soll (löschen, einfügen, etc.).
viele sachen werden halt per get übergeben, da sie per klick auf ein bild (papierkorb, etc.) passieren sollen.
 
Und warum will man sowas verschlüsseln? Es erhöht in keinster Weise die Sicherheit. Mal davon angesehen das base64 keine Verschlüsselung ist.
 
Es ginge mit auto_prepend_file und auto_append_file (siehe hier: PHP: Description of core php.ini directives - Manual), Output-Buffer und Post-Processing der Ausgaben.

- Entsprechende PHP-Config-Werte setzen (zum Beispiel per .htaccess, falls es die Umgebung zulässt).

.htaccess

Code:
php_value auto_append_file "auto_append.php"
php_value auto_prepend_file "auto_prepend.php"

- Zu Beginn jedes Scripts den Output-Buffer anschmeißen und eventuell verschlüsselte GET-Werte wieder entschlüsseln.

auto_prepend.php

PHP:
<?php

require_once './GetObfuscator.php';

if (isset($_GET['data']) && count($_GET) === 1) {
    $obfuscator = new GetObfuscator();
    $obfuscator->deobfuscate($_GET['data']);
}

ob_start();

- Zum Ende jedes Scripts die generierte Ausgabe parsen und jedes href-Attribut eines a-Elements, das nicht mit http oder ftp beginnt (also ein interner Link ist), verschlüsseln.

auto_append.php

PHP:
<?php

require_once './GetObfuscator.php';

$content = ob_get_clean();

$doc = new DOMDocument();
$doc->loadHTML($content);

$xpath = new DOMXPath($doc);

$obfuscator = new GetObfuscator();

foreach ($xpath->query('//a[@href]') as $element) {
    /* @var $element DOMElement */
    $href = $element->getAttribute('href');

    if (0 === preg_match('/^http|ftp/', $href)) {
        $obfuscatedHref = $obfuscator->obfuscate($href);

        $element->setAttribute('href', $obfuscatedHref);
    }
}

echo $doc->saveHTML();

- Zuletzt die Logik hinter der Geschichte.

GetObfuscator.php

PHP:
<?php

/**
 * @author Marc Ermshaus <http://www.ermshaus.org/>
 * @license GPL <http://www.gnu.org/licenses/gpl.html>
 */
class GetObfuscator
{
    const SALT = 'This is a salt value. Change this to something else.';

    public function obfuscate($href)
    {
        $queryPart = parse_url($href, PHP_URL_QUERY);

        $encodedQueryPart = '';

        $saltLength = strlen(self::SALT);

        $len = strlen($queryPart);
        for ($i = 0; $i < $len; $i++) {
            $encodedQueryPart .= chr(ord(substr($queryPart, $i, 1))
                    ^ ord(substr(self::SALT, $i % $saltLength, 1)));
        }

        $encodedQueryPart = base64_encode($encodedQueryPart);

        $newHref = parse_url($href, PHP_URL_PATH) . '?data=' . $encodedQueryPart;

        if (parse_url($href, PHP_URL_FRAGMENT) !== null) {
            $newHref .= '#' . parse_url($href, PHP_URL_FRAGMENT);
        }

        return $newHref;
    }

    public function deobfuscate($data)
    {
        unset($_GET['data']);
        
        $data = base64_decode($data);
        $len = strlen($data);
        $deobfuscated = '';

        $saltLength = strlen(self::SALT);

        for ($i = 0; $i < $len; $i++) {
            $deobfuscated .= chr(ord(substr($data, $i, 1))
                    ^ ord(substr(self::SALT, $i % $saltLength, 1)));
        }

        $queryParts = explode('&', $deobfuscated);

        foreach ($queryParts as $part) {
            list($key, $value) = explode('=', $part);

            $_GET[$key] = $value;
        }
    }
}

Das habe ich gerade zusammengeschrieben. Es wäre gelogen, zu behaupten, dass der Code robust oder erprobt ist.

- Eine Beispielseite.

index.php

PHP:
<!DOCTYPE html>

<html lang="en">

    <head>
        <meta charset="utf-8" />
        <title>Test</title>
    </head>

    <body>

<?php

if (count($_GET) > 0) {
    echo '<p>Content of $_GET</p>';
    echo '<pre>';
    var_dump($_GET);
    echo '</pre>';
}

?>

<p>Some links</p>

<ul>
    <li><a href="./?x=abc&amp;y=def&amp;z=ghi#test">test with fragment identifier</a></li>
    <li><a href="./?x=abc&amp;y=def&amp;z=ghi">test</a></li>
    <li><a href="./?foo=bar&amp;hello=world&amp;id=12">test</a></li>

    <li><a href="http://example.org/">don't touch this</a></li>
</ul>

    </body>

</html>

Hieraus wird automatisch:

HTML:
<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>Test</title></head><body>


<p>Some links</p>

<ul><li><a href="./?data=LFUIEUNPCh0FRRVHFklHHgg=#test">test with fragment identifier</a></li>
    <li><a href="./?data=LFUIEUNPCh0FRRVHFklHHgg=">test</a></li>
    <li><a href="./?data=MgcGTkIIAQYJRR8NA0lXGRMAEUNHRH5ZUw==">test</a></li>

    <li><a href="http://example.org/">don't touch this</a></li>
</ul></body></html>

Bei Klick auf ersten Link:

Code:
Content of $_GET

array
  'x' => string 'abc' (length=3)
  'y' => string 'def' (length=3)
  'z' => string 'ghi' (length=3)

Eventuell musst du für die Angabe der *_append- und *_prepend-Dateien absolute Pfade nutzen, falls die Geschichte auch in Unterverzeichnissen funktionieren soll. Das habe ich nicht getestet.

Noch kurz zum Algorithmus: Der Query-Teil des URL (alles zwischen „?“ und eventuell „#“) wird hergenommen und zeichenweise mit dem angegebenen SALT-Wert ver-xor-t. Das Ergebnis davon wird dann base64-kodiert. Bei der Entschlüsselung wird die Operation rückgängig gemacht.

Das ist auf gar keinen Fall sicher. Wenn es für Besucher an irgendeiner Stelle die Möglichkeit gibt, selbst einen Link zu erstellen, der auf diese Weise bearbeitet wird (also die Eingabe zur Ausgabe zu kennen), kann dir ein halbwegs fähiger Mensch relativ sicher den SALT-Wert knacken. Ich sag's nur. ;)

* * *​

Und sonderlich effizient ist es natürlich nicht, alles zu buffern und dann durch einen XML-Parser zu schicken.

Es ist in dem Zusammenhang sowieso zu empfehlen, alle internen Links durch eine Funktion generieren zu lassen. Siehe etwa die url-Funktion hier:

- http://www.html.de/wiki/MVC#Ausgabe_an_den_Browser

In dieser Funktion könntest du dann auch das Verschlüsseln vornehmen.
 
Zuletzt bearbeitet:
Wen es interessiert: Ein Beispiel, wie „einfach“ so ein Angriff auf den Salt in diesem Fall durchgeführt werden kann.

PHP:
<?php

$myAttackHref = './?' . str_repeat("\xFF", 200);

// Angriffs-Href wird verschlüsselt (simuliert das, was die Webseite machen
// würde)
require_once './GetObfuscator.php';
$obfuscator = new GetObfuscator();
$obfuscated = $obfuscator->obfuscate($myAttackHref);

// Die Rückgabe in $obfuscated kann ich aus dem Quellcode entnehmen
echo $obfuscated . "\n\n";

// Alles hinter ./?data= sieht mir verdächtig nach Base64 aus, dekodieren wir
// das
$decoded = base64_decode(substr($obfuscated, 8));

echo $decoded . "\n\n";

// Okay, gibt mir nichts sinnvolles zurück, gucken wir es im Hexeditor an
echo hexView($decoded);

echo "\n\n";

// Da sehe ich wiederkehrende Byte-Folgen.
// Zum Beispiel: 9198 DF9A 938C 9AD1 AB97 968C
//               (etwa ab Offset 60 und ab Offset 94)

// Das deutet darauf hin, dass hier eine Operation auf den Eingabedaten
// stattgefunden hat, die sich ab einer gewissen Eingabelänge wiederholt.
//
// Da greift sicherlich:
// - http://de.wikipedia.org/wiki/Polyalphabetische_Substitution#Kryptoanalyse
//
// Solche Operation werden -- das weiß ich als Angreifer aus Erfahrung -- gerne
// mit der bit-weisen Operation XOR verknüpft, da hier die doppelte Anwendung
// wieder verlustfrei den ursprünglichen Eingabestring erzeugt

// Probieren wir also einfach mal...

foreach (str_split($decoded) as $char) {
    echo chr(ord($char) ^ ord("\xFF"));
}

echo "\n\n";

// Bingo







/**
 * Displays data in hexadecimal encoding
 *
 * @param string $data Data to display in hex viewer
 * @return string Hex representation of input data
 */
function hexView($data)
{
    $data = (string) $data;

    $chunklen = 16;
    $l = strlen($data);

    if ($l === 0) {
        return '';
    }

    $ret = '00000000  ';

    $origLine = '';

    $lc = 0; // line counter
    $rc = 0; // row counter

    for ($i = 0; $i < $l; $i++) {
        $ret .= sprintf('%02X', ord(substr($data, $i, 1)));

        $n = ord(substr($data, $i, 1));

        if ($n <= 32 || $n === 127) {
            $origLine .= '.';
        } else {
            $origLine .= substr($data, $i, 1);
        }

        $rc++;
        if ($rc === 2) {
            $origLine .= '';
            $ret .= ' ';
            $rc = 0;
        }

        if (($i + 1) % $chunklen === 0) {

            $ret .= ' ' . $origLine;
            $origLine = '';

            $ret .= "\n";
            $lc++;

            if ($lc === 4) {
                $ret .= "\n";
                $lc = 0;
            }
            $rc = 0;

            if ($i < $l - 1) {
                $ret .= sprintf('%08X  ', $i + 1);
            }
        }
    }

    if ($origLine !== '') {
        $k = $chunklen - ($i) % $chunklen;

        for ($i = 0; $i < $k; $i++) {
            $ret .= '  ';

            if ($i % 2 === 0) {
                $ret .= ' ';
            }
        }

        $ret .= ' ' . $origLine;
    }

    return $ret;
}

Ausgabe:

Code:
./?data=q5eWjN+WjN+e34yek4vfiZ6TiprR37yXnpGYmt+Ll5aM34uQ34yQkpqLl5aRmN+ak4ya0auXlozflozfnt+MnpOL34mek4qa0d+8l56RmJrfi5eWjN+LkN+MkJKai5eWkZjfmpOMmtGrl5aM35aM357fjJ6Ti9+JnpOKmtHfvJeekZia34uXlozfi5DfjJCSmouXlpGY35qTjJrRq5eWjN+WjN+e34yek4vfiZ6TiprR37yXnpGYmt+Ll5aM34uQ34yQkpqLl5Y=

«—–Œß–ŒßžßŒž“‹ß‰ž“ŠšÑß¼—ž‘˜šß‹—–Œß‹ßŒ’š‹—–‘˜ßš“ŒšÑ«—–Œß–ŒßžßŒž“‹ß‰ž“ŠšÑß¼—ž‘˜šß‹—–Œß‹ßŒ’š‹—–‘˜ßš“ŒšÑ«—–Œß–ŒßžßŒž“‹ß‰ž“ŠšÑß¼—ž‘˜šß‹—–Œß‹ßŒ’š‹—–‘˜ßš“ŒšÑ«—–Œß–ŒßžßŒž“‹ß‰ž“ŠšÑß¼—ž‘˜šß‹—–Œß‹ßŒ’š‹—–

00000000  AB97 968C DF96 8CDF 9EDF 8C9E 938B DF89  «—–Œß–ŒßžßŒž“‹ß‰
00000010  9E93 8A9A D1DF BC97 9E91 989A DF8B 9796  ž“ŠšÑß¼—ž‘˜šß‹—–
00000020  8CDF 8B90 DF8C 9092 9A8B 9796 9198 DF9A  Œß‹ßŒ’š‹—–‘˜ßš
00000030  938C 9AD1 AB97 968C DF96 8CDF 9EDF 8C9E  “ŒšÑ«—–Œß–ŒßžßŒž

00000040  938B DF89 9E93 8A9A D1DF BC97 9E91 989A  “‹ß‰ž“ŠšÑß¼—ž‘˜š
00000050  DF8B 9796 8CDF 8B90 DF8C 9092 9A8B 9796  ß‹—–Œß‹ßŒ’š‹—–
00000060  9198 DF9A 938C 9AD1 AB97 968C DF96 8CDF  ‘˜ßš“ŒšÑ«—–Œß–Œß
00000070  9EDF 8C9E 938B DF89 9E93 8A9A D1DF BC97  žßŒž“‹ß‰ž“ŠšÑß¼—

00000080  9E91 989A DF8B 9796 8CDF 8B90 DF8C 9092  ž‘˜šß‹—–Œß‹ßŒ’
00000090  9A8B 9796 9198 DF9A 938C 9AD1 AB97 968C  š‹—–‘˜ßš“ŒšÑ«—–Œ
000000A0  DF96 8CDF 9EDF 8C9E 938B DF89 9E93 8A9A  ß–ŒßžßŒž“‹ß‰ž“Šš
000000B0  D1DF BC97 9E91 989A DF8B 9796 8CDF 8B90  Ñß¼—ž‘˜šß‹—–Œß‹

000000C0  DF8C 9092 9A8B 9796                      ߌ’š‹—–

This is a salt value. Change this to something else.This is a salt value. Change this to something else.This is a salt value. Change this to something else.This is a salt value. Change this to somethi

Gut, ich wusste jetzt natürlich, wie es in diesem Fall geht.

Aber, na ja, es ist immer richtig, davon auszugehen, dass ein potentieller Angreifer cleverer ist als man selbst. Also Vorsicht mit hausgemachten „Verschlüsselungen“.

Und ja, ich weiß, dass das hier nicht sicherheitsrelevant ist und für den Anwendungsfall im Thread keine Rolle spielt. Ich wollte nur unangebrachte Illusionen zerstören. ;)
 

Neueste Beiträge

Zurück
Oben