ASP.NET: Vertauschte Sessions (OutputCache und Cookieless Sessions)

by wolfgang@gehirnwindung.de (Wolfgang) März 22, 2013 22:50

Ich wurde vor kurzem mit einem Problem konfrontiert, bei dem ich meinem Kunden natürlich weiterhelfen wollte. Bei einem Web-Projekt wurden sporadisch Sessions "vertauscht" - so sah ein Benutzer A plötzlich die Userdaten eines Benutzers B. Das kam eher selten vor, aber jeder einzelne Fall ist natürlich unschön.

Meine erste Vermutung war, dass das Session-Objekt (oder eine der darin enthaltenen Variablen) evtl. in statischen Variablen gelandet ist. Das soll wohl öfter mal vorkommen und sieht z.B. so aus.

private static Session _sess;
public static void DoSomething() {
    if (_sess == null) {
        _sess = HttpContext.Current.Session;
    }
    if (_sess != null) {
        // ...
    }
}

Zugegeben, sieht recht harmlos aus - ist aber folgenschwer. Ich hab den Ersteller der Webseite kontaktiert und ihn gefragt, ob so etwas ähnliches evtl. enthalten ist. Der machte sich auch direkt auf die Suche nach ähnlichen Konstrukten, blieb aber erfolglos. Danach bekam ich sogar direkt Zugriff auf den Quellcode.

Ich hab den Code natürlich nochmal durchforstet (und die Fremd-Assemblies analysiert) - aber auch ich blieb ohne Erfolg bei meiner Suche (war ja auch überheblich zu denken, dass die anderen nicht richtig suchen würden - ich schäm mich *g*). Die Cache-Einstellungen schienen in Ordnung. Ich hab daraufhin mehrere Tests mit PhantomJS erstellt und durchgehend geprüft, ob die Session irgendwann verloren geht oder die Daten andere werden - aber auch hier ohne jeden Lichtblick. So ging das jetzt mehrere Tage.

Heute hatte ich was ganz anderes vor. Dabei musste ich Cookies in meinem Browser deaktiviert und kam eher zufällig auf die Seite - da hab ich es dann auch endlich mal gesehen: Userdaten eines anderen Benutzers. Und nun war auch endlich klar, wie es zum "vertauschen" der Sessions kam - nämlich gar nicht ;) Wir haben vielmehr - in einem Teilbereich - alle das Gleiche gesehen.

Die ASP.NET - Seite verwendet Cookies im "AutoDetect"-Modus (<session cookieless="AutoDetect" />). Es hätte aber auch "UseUrl" sein können - damit wäre es ebenso falsch gelaufen (allerdings wahrscheinlich leichter entdeckt).

Zusätzlich war bei einem ASP.NET Control (ein Footer) angegeben, dass die Ausgabe gecached werden kann. Das ist mir bei der vorherigen Durchforstung zwar aufgefallen, aber nicht wirklich negativ. Die Angabe sah so aus

<%@ OutputCache Duration="6000" VaryByParam="none" %>

Also auch hier an sich nichts schlimmes. Die HTML-Elemente waren allesamt Links zum Impressum und ähnlichen Seiten. Damit die Cookieless-Session beim Aufruf des Impressums nicht verloren geht, müssen natürlich auch diese Links mit Response.ApplyAppPathModifier() angepasst werden. Argh. Selbstverständlich wird die SessionID hier mitgecached - nur gesehen hab ich es nicht.

Der erste User nach den 6000 Sekunden gibt vor, wie der Footer aussieht.
Sind bei dem User Session-Cookies im Browser erlaubt, klappt es überall (die Cookieless-User verlieren Ihre Session, aber das ist weitaus weniger schlimm als fremde Userdaten zu sehen).
Ist der Browser des "führenden" Users dagegen so eingestellt, dass Session-Cookies abgelehnt werden, bekommen alle dessen Session angezeigt...

Nun kann man entweder den OutputCache ganz abstellen, oder aber die Angabe etwas erweitern zu

<%@ OutputCache Duration="6000" VaryByParam="none" VaryByCustom="session" %>

Hierfür muss aber in der global.asax noch die Funktion GetVaryByCustomString überschrieben werden, in etwa so:

public override string GetVaryByCustomString( HttpContext context, string custom ) {
    if (custom == "session") {
        if( context.Session != null ) {
            return context.Session.SessionID;
        }
    }
    return base.GetVaryByCustomString(context, custom);
}

So funktionieren auch OutputCache und Cookieless Sessions problemlos zusammen... Und beim nächsten Mal seh ich das auch gleich ;)

Kommentare

25.03.2013 07:48:59 #

Hannes Preishuber

Sehr spannend. Wenn man das Caching auf die Session aufmacht ist natürlich der Performance gewinn bescheiden.
Was ich nicht ganz verstehe warum man hier im Usercontrol Benutzerdaten anzeigt.

Hannes Preishuber Deutschland |

25.03.2013 21:58:51 #

Wolfgang

wie meinst Du das mit den Benutzerdaten? Das sind einfach nur Links... aber die Session darf ja nicht verloren gehen. Alternative waren noch relative Links - aber das geht (in dem Fall) genauso wenig (unterschiedliche Pfade)...

Wolfgang Deutschland |

Kommentare sind geschlossen

Powered by BlogEngine.NET 1.6.1.6
Theme by Mads Kristensen | Modified by Mooglegiant and me ;)