Abou Chleih

{the magic lies between the brackets}

Menü Schließen

Monat: Februar 2013

MySQL DataGridView variabel füllen

Wer öfter mit MySQL und dessen Connector arbeitet, möchte sicher einmal die Daten geordnet in einem DataGridView anzeigen. Damit dies aber variabel ist, möchte man die Header natürlich nicht selbst anlegen.

Wie geht man also vor, sodass es möglichst einfach ist?
Zuerst einmal benötigen wir eine DataTable. Um diese zu benutzen, müssen wir den Namespace System.Data mittels

using System.Data;

hinzufügen.

Danach brauchen wir eine Methode, welche natürlich die Daten bezieht und dann zurückgibt. Und genau hier brauchen wir etwas spezielles. Nämlich den MySQLDataAdapter, welcher die Möglichkeit bietet, die empfangenen Daten direkt in eine DataTable zu speichern. Die Methode gibt diese dann zurück

        public DataTable executeSQLQuery()
        {
            DataTable queryTable = new DataTable();
            MySqlConnection connection = new MySqlConnection("SERVER=localhost;UID=user;PASSWORD=passw0rd;DATABASE=db;");
            MySqlCommand command = connection.CreateCommand();
            command.CommandText = "SELECT * FROM table";
            MySqlDataAdapter adapter = new MySqlDataAdapter(command.CommandText, connection);

            try
            {
                adapter.Fill(queryTable);//Öffnet die Verbindung, füllt die DatenTabelle und schließt die Verbindung
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
            return queryTable;
        }

Und wie bekommen wir nun die Daten in das DataGridView-Steuerelement?
Ganz einfach mittels DataSource:

dataGridView.DataSource = executeSQLQuery();

Textausrichtung einer ListView

Normalerweise sollte es kein Problem darstellen, die Ausrichtung eines Textes in einer ListView einzustellen.
Dazu gibt es die Eigenschaft

 TextAlign 

der Klasse

 ColumnHeader 

, welche auch von die ListView zur Darstellung ihrer Spalten nutzt.

Die Ausrichtung lässt sich sehr einfach per Editor oder mit folgendem Code ändern:

 myListView.Columns[myIndex].TextAlign = HorizontalAlignment.Right; 

Zur Auswahl stehen:

  • HorizontalAlignment.Righ
  • HorizontalAlignment.Center
  • HorizontalAlignment.Left

Bisher scheint das auch alles soweit schön zu funktionieren.
Das einzige Probelem ist, dass die Einstellung nicht in der ganz linken Spalte anwendbar ist.
Die ist von Microsoft auch so gewünscht und soll nicht geändert werden.
Man soll es als gegeben hinnehmen.

Ein einfacher Workaround ist nun, eine weitere Spalte davor zu erstellen.
Dieser gibt man einfach die Breite 0.
Nun einfach der Spalte immer Dummywerte zuweisen.

                    
                    myListView.Columns.Add("myDummyColumn");
                    myListView.Columns[myListView.Columns.Count - 1].DisplayIndex = 0;
                    myListView.Columns[myListView.Columns.Count - 1].Width = 0;

Beispielsweise:

  overViewitemDon_lstVw.Items.Add(""); 

Und dann natürlich der zweiten Spalte die Ausrichtung zuweisen:

 myListView.Columns[1].TextAlign = HorizontalAlignment.Right; 

Betarelease von OTRS AD Config Creator

Gestern Abend wurde die erste Beta des OTRS Active Directory Configuration Creator für Windows fertiggestellt und released.
Über Feedback (positiv sowie negativ) würde ich mich sehr freuen.
Link: OTRS Active Directory Configuration Creator

Threadübergreifende Zugriffe(Invoke)

Zu Threading verweise ich auf: Threading mit :Net 2.0

Oftmals ist es nötig aus externen Threads heraus auf die GUI zuzugreifen. Da diese meist in dem Hauptthread der Anwendung läuft bzw. in einem eigenständigen GUI-Thread, wird der direkte Zugriff auf das Control während des Debuggings(nicht bei einer kompilierten Anwendung!) mit einer InvalidOperationException quittiert.

Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement richTextBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.

In .NET gilt nämlich, dass nur der Thread, welcher das Control erstellt hat, auf dieses zugreifen darf. Hier werde ich nun zwei mögliche Arten beschreiben, die es ermöglichen das Control zu verändern.

1. Möglichkeit

Umleitung in den Thread, welcher das Control erstellt hat.

Dazu brauchen wir einen Delegaten

Zuerst einmal wird der Import des Namespaces
System.Threading

Danach erstellen wir ein nicht initialisiertes Objekt eines Threads:

Thread demoThread;

Gefolgt von einer Methode, welche das Control anspricht.

private void DemoThreadMethod()
        {
            for (int i = 0; i < 100; i++)
            {
                // Sicher auf das Steuerelement zugreifen
                // Dazu wird ein s.g. generischer Delegat benötigt,
                //in welchem ein voller GUI-Zugriff möglich ist
                if (this.resultLabel.InvokeRequired)
                {
                    MethodInvoker UpdateLabel = delegate
                    {
                        resultLabel.Text = i.ToString();
                    };
                    Invoke(UpdateLabel);
                }
                else
                {
                    // Der Zugriff erfolgt in demselben Thread
                    this.resultLabel.Text = i.ToString();
                }

                // Kleine Pause zur Veranschaulichung der Threadaktivität
                Thread.Sleep(50);
            }
        }

Zu guter Letzt müssen wir nur noch den Thread initialisieren:

            demoThread = new Thread(DemoThreadMethod);
            demoThread.Start(); 

Um den Unterschied zwischen threaded und unthreaded sehen möchte, muss einfach die Methode DemoThreadMethod direkt aufrufen.
Da dadurch das Label vom Mainthread aus geändert werden soll, gibt InvokeRequired „false“ zurück.

Beim Beenden des Programms muss darauf geachtet werden, dass der Thread in welchem der Invoke ausgeführt wird, beendet wird. Ansonsten kommt es zu einem ObjectDisposedException, da der Thread noch läuft, das Objekt(der Invoke des Labels), auf welches er aber zugreift bereits durch das Beenden verworfen wurde.

2. Möglichkeit

Über die Komponente BackgroundWorker.

Der BackgroundWorker selbst bietet bereits eine Methode um die GUI zu aktualisieren: Die ReportProgress-Methode

Um diese zu verwenden muss die Eigenschaft WorkerReportsProgress auf ‚true‘ gesetzt werden, ansonsten tritt eine InvalidOperationException auf.

Die Methode ruft das ProgressChanged-Event auf, welche eine Methode aufruft, welche sich im Thread befindet, der den BackgroundWorker aufgerufen hat.

Folgender Code ruft die oben beschrieben Vorgehensweise auf.
Zuerst benötigen wir zwei Eventhandler, welche unsere Methoden aufrufen. Diese platziert man am besten im Konstruktor

backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);

Folgende Methode wird aufgerufen, wenn der BackgroundWorker mittels RunWorkerAsync gestartet wird.

void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
	for (int i = 0; i <= maxAmount; i++)
	{
		if (backgroundWorker.CancellationPending)
		{
			e.Cancel = true;
		}
		int percentage = (int)((i/(double)maxAmount) * 100);
		this.backgroundWorker.ReportProgress(percentage); //Ruft das ProgressChanged-Event auf, welches die unten stehende Methode aufruft (definiert beim EventHandler)
 }
 e.Result = "Finished";
}

Folgende Methode wird im Thread aufgerufen, welche den BackgroundWorker gestartet hat. Meistens also im Thread, in welchem sich die GUI befindet

void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    BackgroundWorker_progressBar.Value = e.ProgressPercentage;
}

Cross Site Scripting #2 – Bekannte Beispiele

Um sich die Wirkung und das Ausmaß eines XSS-Angriffs auszumalen, möchte ich einige Beispiele aus den letzten Jahren einbringen:

Im Jahre 2010 verschafften sich Cracker (im Sinne von destruktiven Hackern) Zugang zu verschiedenen Servern der Apache Foundation [1].
Dieser Angriff wurde durch ein Ticket mit manipulierte Webadresse durchgeführt.
Durch dieses Ticket sollte die Cookie-Session des angemeldeten Users gestohlen werden (Session stealing).

Durch diesen und einen zweiten, parallelen Bruteforce-Angriff erlangten die Angreifer dann die Kontrolle über den JIRA-Server, wo sie ungehindert Dateien durchstöbern und herunterladen konnten. Zusätzlich wurden Passworteingaben abgefangen.

Die Folgen waren, dass die Server für einige Stunden offline waren, die Passwörter geändert, die Sicherheitslücken gestopft und der Hauptserver komplett ausgetauscht werden musste.


Im Oktober 2005 wurde ein XSS-Wurm in MySpace entdeckt, welcher innerhalb von 20 Stunden über eine Millionen Profile befiel.

Der Entwickler des Wurms Samy Kamkar, dessen Vorname auf der Bezeichner des Wurms ist, zielte darauf ab, die Freundesliste des Entwicklers zu füllen.
Sobald jemand auf ein „infiziertes“ Profil klickte, lud das JavaScript-Script und addete Samy Kamkars Account zur Friendlist hinzu.
Zudem erschien ein „Status“-Post mit dem Inhalt: „but most of all, Samy is my hero“.

Nachdem MySpace den Wurm entdeckte, schlossen sie die Lücke und verklagten Kamkar.
Der Entwickler wurde zu drei Jahren Computerabstinenz, 90 Tagen gemeinnütziger Arbeit und einer Entschädigung in unbekannter Höhe verurteilt.
Der Wurm ist und bleibt trotzdem der sich am schnellsten verbreitende Wurm in der Computergeschichte.


Cross Site Scripting #1 – Definition und Einführung

Wer einmal Webseiten gebaut hat oder Datenbanken in seine Homepage integrierte, der wird sicher auch über das Thema XSS (Cross Site Scripting) gestolpert sein.
Aber was ist eigentlich XSS?

Definition
Es ist das Ausnutzen einer Sicherheitslücke über diese man Daten andere Nutzer ausspähen oder manipulieren kann.
Das Scripting kommt daher, dass zur Ausnutzung der Lücken meist Scripts genutzt werden, bspw. in Javascript.

Einführung
Erst einmal. Wessen Schuld ist es, wenn XSS nutzbar ist?
Hier liegt die Schuld ganz beim Admin oder Developer der Seite, denn mit relativ einfachen Mitteln kann man es den Hackern und Scriptern (das schließt Scriptkiddies mit ein) ziemlich schwer machen.
Denn eine Eingabe eines Users, sei es über eine Kommentarfunktion oder über die GET/POST-Parameter in PHP müssen gefiltert, d.h. nach unerlaubten Zeichen, Scripts etc. durchsucht werden.
Achtung: Auch wenn man eines der großen CMS nutzt, ist man davor nicht sicher. Deshalb immer auf neue Versionen updaten! Dort werden dann bekannte Sicherheitslücken geschlossen

Arten:
reflective/non-persistend XSS:
Hier wird ein GET-Parameter auf einer Seite manipuliert um Schadcode auszuführen.
Dies funktionert bspw. so:
Wir haben eine Seite mit einer Suchfunktion, welche den eingegebenen Suchbegriff als GET-Parameter weiterverarbeitet.
http://www.xyztestsiteabc123.com?search=Hier ist mein Suchbegriff
Falls die Seite den Suchbegriff irgendwann also wieder ausgibt, würde das auf der Seite so aussehen:

Sie suchten nach: Hier ist mein Suchbegriff

Nun kann man, falls die Eingaben der Suchfunktion nicht gefiltert werden, jeglichen Code eingegeben:

 http://www.xyztestsiteabc123.com?search=<img alt="" src="http://abouchleih.de/spaceinv_code1.png" width="42" height="42" /> 

Das ist noch nicht so schlimm, denn es wird hier „nur“ ein Bild auf eine Seite eingefügt, dennoch sollten solche Eingaben verboten werden, da sie erstens störend wirken und zweitens auch JavaScript so ausgeführt werden kann.

Das Ergebnis würde also beim obigen eingeben so aussehen:

Sie suchten nach:

Allerdings ist diese Methode recht harmlos, da man die User erst auf die manipulierte Seite locken müsste und die Seite auch nicht gespeichert ist.

persistend XSS:
Hier wird im Gegensatz zu oben, der Code in der Website gespeichert und bleibt so sichtbar.
Nutzbar ist dies bei ungefilterten Kommentarfunktionen in einem Gästebuch.
Wird nun ein Kommentar mit Code gepostet, so wird dieser bei jedem Aufruf der Website ausgeführt.

Beispielcode:

Hallo!<script type="“text/javascript“">
alert("Dies ist ein Script, welches zur anschaulichen Darstellung von XSS auf einer Website verwendet wurde. Lies den Artikel für mehr Info 😉 ");
</script>

Das Ergebnis könnt ihr beim Klick auf den Button begutachten.

dombasiertes XSS:
Ähnlich dem reflective XSS, nur dass hier die Webanwendung/-site nicht beteiligt ist.
Der Code wird also nur auf dem Clientrechner verarbeitet.

Zu Part 2 hier geht’s hier entlang.

© 2018 Abou Chleih. Alle Rechte vorbehalten.

Thema von Anders Norén.