BY:Mitgliederbefragung 2010.1/Technik
Bezüglich der BY:Mitgliederbefragung 2010.1 wurden einige Fragen bezüglich Datenschutz und Anonymität gestellt. Diese Seite soll dazu dienen die dahinter stehende Technik zu erläutern.
Inhaltsverzeichnis
Zusammenfassung
- Software: LimeSurvey
- Mitgliederdaten: aus Mitgliederverwaltung exportiert am 14.01.10. Vorname und Email_Adresse werden durch Limesurvey verwendet (mehr nicht).
- die Antworten werden völlig unabhängig zu den Zugangsschlüsseln und dadurch zu den Email_Adressen gespeichert. Eine Rückverfolgung ist nicht möglich
- IP-Adressen speichert unser Server ebenso wenig.
Technik
Für die Befragung nutzen wir die freie Software LimeSurvey in Version 1.87+ (build 8243). Bis auf das config-file und eine Fehlerbehebung im Sprachpaket sind keine Änderungen vorgenommen worden. (der Sprachpaket-Fehler ist im limesurvey-bugtracker geloggt und wird bei der nächsten Version behoben)
Daten werden in einer mySQL-Datenbank in folgenden Tabellen gehalten:
- Umfrage selbst wird in einigen Tabellen gehalten die ich jetzt hier nicht im Detail erläutere. Dazu gehören lime_surveys; lime_answers; lime_labels usw - alle Beschreiben nur die Struktur der Umfrage selbst. Aber keine Antworten oder Zugangsschlüssel.
- Zugangsschlüssel
- lime_tokens_47497 (47497 ist die Umfrage-ID)
+---------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +---------------+-------------+------+-----+---------+----------------+ | tid | int(11) | NO | PRI | NULL | auto_increment | | firstname | varchar(40) | YES | | NULL | | | lastname | varchar(40) | YES | | NULL | | | email | text | YES | MUL | NULL | | | emailstatus | text | YES | | NULL | | | token | varchar(36) | YES | MUL | NULL | | | language | varchar(25) | YES | | NULL | | | sent | varchar(17) | YES | | N | | | remindersent | varchar(17) | YES | | N | | | remindercount | int(11) | YES | | 0 | | | completed | varchar(17) | YES | | N | | | validfrom | datetime | YES | | NULL | | | validuntil | datetime | YES | | NULL | | | mpid | int(11) | YES | | NULL | | +---------------+-------------+------+-----+---------+----------------+
Die "tid" ist einfach eine fortlaufende Nummer, damit es in der Tabelle eine PK gibt. Von uns werden nur Firstname und Email Benutzt, Lastname ist auf "unnoetig" gesetzt, da wir es nicht benötigen. Firstname wird nur gebraucht, damit wir Euch in den Emails mit Vornamen ansprechen können. emailstatus ist einfach "ok" oder "invalid" wenn die mail-adresse offensichtlich nicht passen kann (regex validitäts-check: "#!falsche.@email-com" kann keine gültige Mail-Adresse sein)
Der Token (Zugangsschlüssel) wird zufällig vor dem Versenden der mails generiert und zusammen mit der email-Adresse aufbewahrt. Dies ermöglicht das erneute Versenden als Erinnerung oder bei eventuell auftretenden Problemen (falsche mail-Adresse, Probleme mit Mail-Clients die einen Zeilenumbruch in den Link einfügen etc.).
Im laufe der Umfrage werden Eure Daten angereichert mit:
- Habt ihr eine Einladung bekommen (Feld: sent, gefüllt mit N oder Datum+Uhrzeit)
- habt ihr eine Erinnerung erhalten (Felder: remindersent mit N oder Datum+Uhrzeit, remindercount als einfacher Counter wie viele versendet wurden)
- completed: habt ihr die Umfrage abgeschlossen (N oder Y, kein Datum o.ä.). Ist hier "Y" eingetragen, ist Euer Zugangsschlüssel verbraucht - es ist also sicher gestellt, niemand sonst die Umfrage für Euch ausgefüllt hat. Zudem bekommt ihr dann keine Erinnerungen mehr. Insofern ist tatsächlich nachvollziehbar wer von Euch die Umfrage ausgefüllt hat und wer nicht. Das schadet dem Geheimnis-Grad der Umfrage selbst aber nicht: selbst bei Bundestagswahlen ist nachvollziebar *WER* gewählt hat - aber nicht wie.
- validfrom, validuntil und mpid wird von uns nicht genutzt. Das kann für dauerhafte Umfragen genutzt werden bei denen Zugangsschlüssel nur für eine gewisse Zeit und/oder für mehrere Umfragen gültig sein sollen.
Nach Ablauf der Umfrage werden die Tokens zusammen mit den Mail-Adressen gelöscht.
- Antworten
- die Antwort-Tabelle ist etwas kryptisch, da sie durch die Umfrage-Struktur selbst generiert wird. Unsere Schaut so aus:
+-----------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------------+-------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | submitdate | datetime | YES | | NULL | | | lastpage | int(11) | YES | | NULL | | | startlanguage | varchar(20) | NO | | NULL | | | 47497X1X1 | varchar(5) | YES | | NULL | | | 47497X1X2 | varchar(5) | YES | | NULL | | | 47497X1X27 | varchar(5) | YES | | NULL | | | 47497X1X3 | varchar(5) | YES | | NULL | | | 47497X1X4 | text | YES | | NULL | | | 47497X1X28 | varchar(1) | YES | | NULL | | | 47497X2X5 | varchar(5) | YES | | NULL | | | 47497X2X6 | varchar(5) | YES | | NULL | | | 47497X2X7 | varchar(5) | YES | | NULL | | | 47497X2X8 | text | YES | | NULL | | | 47497X2X29 | varchar(1) | YES | | NULL | | | 47497X3X13 | varchar(5) | YES | | NULL | | | 47497X3X9ST | varchar(5) | YES | | NULL | | | 47497X3X9AG | varchar(5) | YES | | NULL | | | 47497X3X9ML | varchar(5) | YES | | NULL | | | 47497X3X9NS | varchar(5) | YES | | NULL | | | 47497X3X9FO | varchar(5) | YES | | NULL | | | 47497X3X9WK | varchar(5) | YES | | NULL | | | 47497X3X9ZZ | varchar(5) | YES | | NULL | | | 47497X3X10 | varchar(5) | YES | | NULL | | | 47497X3X11 | varchar(5) | YES | | NULL | | | 47497X3X12 | varchar(5) | YES | | NULL | | | 47497X3X141 | varchar(5) | YES | | NULL | | | 47497X3X142 | varchar(5) | YES | | NULL | | | 47497X3X143 | varchar(5) | YES | | NULL | | | 47497X3X144 | varchar(5) | YES | | NULL | | | 47497X3X14other | text | YES | | NULL | | | 47497X3X15 | varchar(5) | YES | | NULL | | | 47497X3X31 | varchar(1) | YES | | NULL | | | 47497X4X16 | varchar(5) | YES | | NULL | | | 47497X4X171 | varchar(5) | YES | | NULL | | | 47497X4X172 | varchar(5) | YES | | NULL | | | 47497X4X173 | varchar(5) | YES | | NULL | | | 47497X4X174 | varchar(5) | YES | | NULL | | | 47497X4X175 | varchar(5) | YES | | NULL | | | 47497X4X176 | varchar(5) | YES | | NULL | | | 47497X4X177 | varchar(5) | YES | | NULL | | | 47497X4X181 | varchar(5) | YES | | NULL | | | 47497X4X182 | varchar(5) | YES | | NULL | | | 47497X4X183 | varchar(5) | YES | | NULL | | | 47497X4X184 | varchar(5) | YES | | NULL | | | 47497X4X185 | varchar(5) | YES | | NULL | | | 47497X4X186 | varchar(5) | YES | | NULL | | | 47497X4X187 | varchar(5) | YES | | NULL | | | 47497X4X32 | varchar(1) | YES | | NULL | | | 47497X5X19 | varchar(5) | YES | | NULL | | | 47497X5X201 | varchar(5) | YES | | NULL | | | 47497X5X202 | varchar(5) | YES | | NULL | | | 47497X5X203 | varchar(5) | YES | | NULL | | | 47497X5X204 | varchar(5) | YES | | NULL | | | 47497X5X205 | varchar(5) | YES | | NULL | | | 47497X5X206 | varchar(5) | YES | | NULL | | | 47497X5X207 | varchar(5) | YES | | NULL | | | 47497X5X208 | varchar(5) | YES | | NULL | | | 47497X5X209 | varchar(5) | YES | | NULL | | | 47497X5X2010 | varchar(5) | YES | | NULL | | | 47497X5X2011 | varchar(5) | YES | | NULL | | | 47497X5X2012 | varchar(5) | YES | | NULL | | | 47497X5X21 | text | YES | | NULL | | | 47497X5X33 | varchar(1) | YES | | NULL | | | 47497X6X221 | varchar(5) | YES | | NULL | | | 47497X6X222 | varchar(5) | YES | | NULL | | | 47497X6X223 | varchar(5) | YES | | NULL | | | 47497X6X224 | varchar(5) | YES | | NULL | | | 47497X6X225 | varchar(5) | YES | | NULL | | | 47497X6X226 | varchar(5) | YES | | NULL | | | 47497X6X227 | varchar(5) | YES | | NULL | | | 47497X6X228 | varchar(5) | YES | | NULL | | | 47497X6X229 | varchar(5) | YES | | NULL | | | 47497X6X2210 | varchar(5) | YES | | NULL | | | 47497X6X22other | text | YES | | NULL | | | 47497X6X23 | varchar(1) | YES | | NULL | | | 47497X6X241 | varchar(5) | YES | | NULL | | | 47497X6X242 | varchar(5) | YES | | NULL | | | 47497X6X243 | varchar(5) | YES | | NULL | | | 47497X6X244 | varchar(5) | YES | | NULL | | | 47497X6X245 | varchar(5) | YES | | NULL | | | 47497X6X246 | varchar(5) | YES | | NULL | | | 47497X6X247 | varchar(5) | YES | | NULL | | | 47497X6X248 | varchar(5) | YES | | NULL | | | 47497X6X249 | varchar(5) | YES | | NULL | | | 47497X6X2410 | varchar(5) | YES | | NULL | | | 47497X6X25 | text | YES | | NULL | | | 47497X6X26 | varchar(1) | YES | | NULL | | +-----------------+-------------+------+-----+---------+----------------+
Ein (zufälliger) Eintrag sieht dort drin so aus:
mysql> select * from lime_survey_47497 where id = 904; +-----+---------------------+----------+---------------+-----------+-----------+------------+-----------+-----------+------------+-----------+-----------+-----------+-----------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+------------+------------+------------+-------------+-------------+-------------+-------------+-----------------+------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+--------------+--------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+-----------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+------------+------------+ | id | submitdate | lastpage | startlanguage | 47497X1X1 | 47497X1X2 | 47497X1X27 | 47497X1X3 | 47497X1X4 | 47497X1X28 | 47497X2X5 | 47497X2X6 | 47497X2X7 | 47497X2X8 | 47497X2X29 | 47497X3X13 | 47497X3X9ST | 47497X3X9AG | 47497X3X9ML | 47497X3X9NS | 47497X3X9FO | 47497X3X9WK | 47497X3X9ZZ | 47497X3X10 | 47497X3X11 | 47497X3X12 | 47497X3X141 | 47497X3X142 | 47497X3X143 | 47497X3X144 | 47497X3X14other | 47497X3X15 | 47497X3X31 | 47497X4X16 | 47497X4X171 | 47497X4X172 | 47497X4X173 | 47497X4X174 | 47497X4X175 | 47497X4X176 | 47497X4X177 | 47497X4X181 | 47497X4X182 | 47497X4X183 | 47497X4X184 | 47497X4X185 | 47497X4X186 | 47497X4X187 | 47497X4X32 | 47497X5X19 | 47497X5X201 | 47497X5X202 | 47497X5X203 | 47497X5X204 | 47497X5X205 | 47497X5X206 | 47497X5X207 | 47497X5X208 | 47497X5X209 | 47497X5X2010 | 47497X5X2011 | 47497X5X2012 | 47497X5X21 | 47497X5X33 | 47497X6X221 | 47497X6X222 | 47497X6X223 | 47497X6X224 | 47497X6X225 | 47497X6X226 | 47497X6X227 | 47497X6X228 | 47497X6X229 | 47497X6X2210 | 47497X6X22other | 47497X6X23 | 47497X6X241 | 47497X6X242 | 47497X6X243 | 47497X6X244 | 47497X6X245 | 47497X6X246 | 47497X6X247 | 47497X6X248 | 47497X6X249 | 47497X6X2410 | 47497X6X25 | 47497X6X26 | +-----+---------------------+----------+---------------+-----------+-----------+------------+-----------+-----------+------------+-----------+-----------+-----------+-----------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+------------+------------+------------+-------------+-------------+-------------+-------------+-----------------+------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+--------------+--------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+-----------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+------------+------------+ | 904 | 1980-01-01 00:00:00 | 6 | de-informal | OBB | 2 | | | | | 2 | | 2 | | | 2 | 5 | | 3 | 4 | 3 | 2 | | 3 | | 2 | | Y | | | | | | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 2 | 1 | 2 | 1 | 3 | | | 2 | 4 | 4 | 4 | 1 | 4 | 3 | 1 | 2 | 4 | 2 | 2 | | | | Y | | | | | Y | | | Y | | Y | | | | | | | | | | | | | +-----+---------------------+----------+---------------+-----------+-----------+------------+-----------+-----------+------------+-----------+-----------+-----------+-----------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+------------+------------+------------+-------------+-------------+-------------+-------------+-----------------+------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+--------------+--------------+------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+-----------------+------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+-------------+--------------+------------+------------+
Ich habe hier absichtlich keinen Eintrag mit Kommentaren in Textfeldern genommen damit man nicht ahnen kann, wessen Antwort das sein könnte. "Submitdate" ist bei uns immer 1980 - weil die Umfrage auf anonym gestellt ist.
Wie man sehen kann, gibt es keinen Bezug zum Token, Token-ID oder email-Adresse.
Mails
- für die Einladung wird aus der Zugangsschlüsseltabelle der Vorname, Email-Adresse und der Schlüssel geladen und versendet
- für die Erinnerungen gilt das gleiche
- ist die Umfrage abgeschlossen wird der Zugangsschlüssel inaktiv gesetzt (completed = Y) und als Bestätigung der Ungültigmachung eine mail versendet.
Zugänge
Bis auf ValiDOM hat niemand Zugang zur Datenbank oder dem LimeSurvey-System. Oliver hat theoretisch Zugang, da er den kompletten Server administriert und sich dadurch per-se auf alles Zugang verschaffen kann.
Audit
Sollte jemand meine Angaben überprüfen wollen kann er sich gern bei mir (ValiDOM) melden. Wir können dann in einer VNC-Session die Config durchgehen. Dafür verlange ich aber, dass der jenige danach ein Statement hier abgibt, dass alles passt.
Zwar habe ich kein Audit durchgeführt, allerdings ValiDOM per Mail gelöchert.
>> Ablauf ist so: >> * Du öffnest mit dem Token die Umfrage >> * bekommst eine Session (in der steht der token nicht) >> * dann kannst Du hin- und herspringen wie du willst >> * die Werte werden tatsächlich schon gespeichert in der >> Antwort-Tabelle aber completed : N. >> * Antworten ohne completed: Y werden bei der Auswertung ignoriert >> * wird completed : Y gesetzt, wird gleichzeitig der token ungültig >> > > Und deswegen ja das N setzen vorneweg - verstanden? Nope, weil das ist doch schon N ;-) > Natürlich müsste mit > dem was du geschildert hast noch geklärt werden wie im Code die Session > hergestellt wird, aber da ja wie du geschrieben hast, tatsächlich wie ich > vermutete die Daten gleich in die Tabelle geschrieben werden, ist ihr die > Verknüpfung der TID mit ID über den Token gegeben, sonst könnte das > Programm die Daten nicht in die Tabelle wegschreiben. Ja, die Verknüpfung ist über die aufgerufene URL gegeben. Da steht der Token drin. Natürlich muss die Applikation zur Laufzeit diese Verbindung herstellen, sonst müsste der Token bei beginn der Umfrage ungültig werden. Und nicht erst beim Abschluss. In der DB gibt es diese Verknüpfung aber nicht. Was mich dazu bringt zu sagen... würde ich die Applikation verändern, könnte ich es herausfinden. Dann kann ich aber auch gleich auf nicht-anonym umschalten dann hab ich das auch ;) Ist sogar ein Feature. Dann gibts halt den Text auf der Startseite nimmer bzw. der wird von Limesurvey angezeigt mit hinweis nicht anonym etc.
Fazit, wenn man entweder die Applikation hackt oder aber die Applikation Limesurvey auf "Nicht anonym" stellt, dann bestünde eine theoretische Möglichkeit. Da es aber auf anonym steht und ein Crack Unsinn ist, weil Limesurvey sowieso auch nicht anonyme Anfragen könnte, ist anonym anonym im Rahmen der eingesetzten Technik. Arnold