289 lines
No EOL
14 KiB
Text
289 lines
No EOL
14 KiB
Text
---
|
|
title: "Git Commits analysieren"
|
|
author: "Jannis von Hagen (PFWC123A)"
|
|
date: "`r Sys.Date()`"
|
|
output: html_document
|
|
---
|
|
<div style="font-family=sans-serif; font-size:1.5rem; line-height:2;">
|
|
|
|
|
|
|
|
|
|
```{r echo=FALSE, include=FALSE, warning = FALSE}
|
|
|
|
#system("get.data.bat")
|
|
#system("format.data.bat")
|
|
|
|
diffs <- read.delim("data/diffs.txt")
|
|
commits <- read.csv("data/commits.txt", sep=";")
|
|
|
|
install.packages('plyr', repos = "http://cran.us.r-project.org")
|
|
install.packages('dplyr', repos = "http://cran.us.r-project.org")
|
|
install.packages('anytime', repos = "http://cran.us.r-project.org")
|
|
library('plyr')
|
|
library('dplyr')
|
|
library('anytime')
|
|
library('ggplot2')
|
|
library('lubridate')
|
|
library('solitude')
|
|
```
|
|
|
|
<hr />
|
|
|
|
## 0 Inhalt
|
|
|
|
- 0 Inhalt
|
|
- 1 Einleitung
|
|
- 1.0 Was ist git ?
|
|
- 1.1 Angriffsvektor
|
|
- 1.2 Hypothese
|
|
- 2 Aufbereitung der Daten
|
|
- 2.0 Quelle
|
|
- 2.1 Variablen
|
|
- 2.2 Bedeutungen
|
|
- 3 Untersuchung
|
|
- 3.1 Commits über Zeit
|
|
- 3.2 Tageszeit der Commits einer Person
|
|
- 3.3 Menge an Commits pro Person
|
|
- 3.4 Menge an Änderungen pro Person
|
|
- 3.5 Unterzeichnete Commits
|
|
- 4 Aufstellung eines Prädiktiven Models
|
|
- 5 Fazit
|
|
- Quellen
|
|
- Dependencies
|
|
- Worterklärungen
|
|
|
|
## 1 Einleitung
|
|
|
|
### 1.0 Was ist git ?
|
|
|
|
**[Git](https://git-scm.com/)** ist ein Programm zur Versionskontrolle von Software und ermöglicht das Kollaborieren von mehreren Personen an einem Projekt. Alle Änderungen im Quellcode werden aufgezeichnet und können bei Fehlern zurückgezogen werden um immer stabile Funktionalität zu gewährleisten. Häufig gibt es einen oder mehrere Benutzer oder Organisationen, welche die Kontrolle über ein sogenanntes git *"Repository"* haben in dem sie Änderungen von Mitarbeitern akzeptieren können. Bei Quelloffener Software werden auch Änderungen von anderen, nicht zum Projekt gehörigen Personen akzeptiert.
|
|
|
|
|
|
### 1.1 Angriffsvektor
|
|
|
|
Git zeichnet zwar Änderungen auf aber von sich aus findet keine automatische Validierung der Änderung statt.
|
|
Wenn der Zugang eines Projektmitarbeiters kompromisiert wird, kann es einem Angreifer möglich sein ohne Probleme schädlichen Code in ein Softwareprojekt zu schleußen. Auch kann ein Angreifer einfach eine schädliche Änderung anfragen und falls diese Änderung nicht richtig überprüft wird, könnte sie in das Projekt gelangen.
|
|
|
|
Der Vorteil von diesem Angriffsvektor gegenüber anderen Methoden ist, dass es eine potenziell größere Gruppe trifft.
|
|
Die Ausführbaren Versionen einer Software werden aus dem Quellcode generiert sodass jede Verbreitungsquelle der Software infiziert wird, anstatt nur eine einzige. Auch umgeht diese Methode eine Verteidigungsmethode, bei der der Hash der Software geprüft wird, indem sie vor dem Hashprozess funktioniert.
|
|
|
|
### 1.2 Hypothese
|
|
|
|
Git speichert alle Änderungen und Metadaten über jede Änderung im Repository. Somit sollte es also möglich sein anhand von verschiedenen Faktoren eine Wertung für jeden einzelnen Commit zu erstellen der die Auffälligkeit der Änderung im Vergleich zu anderen Änderungen im Repository beschreibt. Dies kann automatisiert passieren und kann auch von Dritten eingesetzt werden, um Repositories zu überwachen, welche man nicht direkt kontrolliert aber mit dem eigenen Projekt zu tun haben.
|
|
|
|
Wichtig zu erwähnen ist hier, dass es sich dabei nur um eine Auffälligkeit handelt und jede Auffälligkeit manuell geprüft werden muss. Die Nutzererfahrung bei falsch positiven Ergebnissen sollte nur minimal beeinträchtigt werden.
|
|
|
|
*Das Ziel dieser Arbeit ist nicht praktischer realer Nutzen, denn es existieren bereits ähnliche, weitaus komplexere Konzepte zum Schutz von Repositories. Commits werden meistens schon von mindestens einer anderen Person analysiert, sodass einfach Auffälligkeiten schnell herausgefiltert werden, und echte Angreifer nutzen meist weit **[diskretere](https://nvd.nist.gov/vuln/detail/CVE-2024-3094)** Angriffswege die durch diese Analyse nicht gefunden werden können.*
|
|
|
|
Ziel ist also eine Wertung für jeden Commit zu erstellen und die potentiell relevanten Faktoren für diese Wertung in dieser Arbeit zu analysieren.
|
|
|
|
<hr />
|
|
|
|
## 2 Aufbereitung der Daten
|
|
|
|
### 2.0 Quelle
|
|
Solange genug Datenpunkte vorhanden sind, soll das System jedes beliebiges Repository analysieren können, aber um den Anforderungen dieser Arbeit gerecht zu werden und um meine Analysen validieren zu können werde ich ein Beispiel Repository benutzen. Hierbei habe ich mich für das Git Repository von **[SDL](https://www.libsdl.org/)**entschieden.
|
|
SDL ist eine Softwarebibliothek für Platformübergreifende Software. Es wird sehr häufig zur Entwicklung von unter anderen Videospielen benutzt, hat 17000 Commits und ist inzwischen 26 Jahre alt.
|
|
|
|
### 2.1 Variablen
|
|
Die Variablen, die analysiert werden, sind in zwei Dateien vorhanden, da eine 1:n Beziehung besteht.
|
|
Ein einzelner Commit kann mehrere Änderungen an Dateien besitzen, sodass dort diese Beziehung entsteht.
|
|
|
|
|
|
#### Commits
|
|
|
|
| Name | Bedeutung |
|
|
| -----| --------- |
|
|
| Commit Hash | Repräsentiert die Id des jeweiligen Commits |
|
|
| Name | Benutzername des Autors des Commits |
|
|
| Email | Email des Autors des Commits |
|
|
| Time | Unix Zeit Code des Erstellungszeitpunktes des Commmits |
|
|
| Signed | Ob der Commit mit einem Schlüssel "unterschrieben" wurde |
|
|
| Binaries | Wie viele binäre Dateien in dem Commit verändert wurden |
|
|
|
|
|
|
#### Diffs
|
|
|
|
| Name | Bedeutung |
|
|
| -----| --------- |
|
|
| Commit Hash | Repräsentiert die Id des jeweiligen Commits |
|
|
| Add | Menge an hinzugefügten Codezeilen |
|
|
| Remove | Menge an entfernten Codezeilen |
|
|
| File | Die spezifische Datei die verändert wurde |
|
|
|
|
### 2.2 Bedeutungen
|
|
|
|
In den Beispieldaten ist kein Fehler enthalten da sie von Git aus dem Repository extrahiert wurden.
|
|
Zwar sind manche Einträge auffällig, allerdings ist es das Ziel dieser Arbeit auffällige Commits ausfindig machen zu können,
|
|
weshalb sie hier nicht aus dem Datensatz entfernt werden.
|
|
Zur Extraktion der Daten wird ein Skript über die Roh Ausgabe von Git laufen gelassen und danach noch ein Paar Veränderungen in diesem Dokument vorgenommen,
|
|
um die Daten nutzbar zu machen.
|
|
|
|
|
|
**Time** Ist eine Unix Timestamp, welche die Zeit in Sekunden seit 1970 angibt,
|
|
da für die Analyse aber die Tageszeit eine Rolle spielt müssen die Daten erst umgewandelt werden.
|
|
|
|
```{r}
|
|
commits$time <- anytime(commits$time)
|
|
```
|
|
|
|
**Signed** nutzt ein einzelnes Zeichen um anzuzeigen, ob der Commit signiert wurde,
|
|
dies kann bei der Analyse berücksichtigt werden und benötigt keine Umwandlung.
|
|
|
|
**add** und **remove** aus **diffs** hat manche Einträge die ein "-" anstatt einer Zahl besitzen.
|
|
Dies wird von Git benutzt, um anzuzeigen, dass es sich um eine binäre Datei handelt, bei welcher Zeilen Unterschiede keine logische Bedeutung haben.
|
|
Diese Einträge werden mithilfe eines Skriptes entfernt und die Anzahl pro Commit, wird zu dem Commit als **binaries** hinzugefügt.
|
|
|
|
## 3 Untersuchung
|
|
|
|
### 3.1 Commits über Zeit
|
|
```{r}
|
|
ggplot(as.data.frame(
|
|
table(paste(
|
|
format(na.omit(anydate(commits$time)), "%Y"), #Get the year
|
|
sprintf("%02i", na.omit((as.POSIXlt(commits$time)$mon)) %/% 3L + 1L), #Quarter of the year
|
|
sep = "/"))),
|
|
aes(x=Var1, y=Freq)) + geom_point() + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
|
|
xlab("Zeit") +
|
|
ylab("Commits")
|
|
```
|
|
|
|
Die vorhergehende Graphik zeigt an, wie viele Commits pro Quartal eines Jahres angefallen sind.
|
|
Interessant ist hier, dass die Commits in Monaten, in welchen eine neue Version der Software veröffentlicht wurde, besonders hoch sind. Auch gibt es einen Commit der angeblich 1970 erstellt wurde. Dies zeigt eine der ersten Möglichkeiten auf, mit der man auffällige Commits erkennen kann.
|
|
|
|
|
|
### 3.2 Tageszeit der Commits einer Person
|
|
|
|
Man kann theoretisch die Tageszeit des Datensatzes analysieren, allerdings gäbe das keine guten Ergebnisse, da Zeit Zohnen existieren und theoretisch von jedem Land aus commited werden kann. Eine Bewertung der muss daher von den anderen Commits der Person abhängen.
|
|
|
|
```{r warning = FALSE}
|
|
times <- aggregate(as.numeric(hm(format(as.POSIXlt(time), "%H %M"))) ~ email, commits, mean)
|
|
times$`as.numeric(hm(format(as.POSIXlt(time), "%H %M")))` <- as.POSIXlt(times$`as.numeric(hm(format(as.POSIXlt(time), "%H %M")))`)
|
|
|
|
ggplot(times,
|
|
aes(x=as.POSIXct(`as.numeric(hm(format(as.POSIXlt(time), "%H %M")))`, "%H %M"))) + geom_histogram(bins=48) +
|
|
scale_x_datetime(date_labels = "%H:%M") +
|
|
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
|
|
xlab("Uhrzeit") +
|
|
ylab("Commit Menge")
|
|
```
|
|
Das Diagramm zeigt das Arithmetische Mittel der Zeiten, wann ein Nutzer einen Commit erstellt hat. Auffällig hier ist, dass trotz der Theoretischen Zeitzonenverteilung ein Großteil der Nutzer zu ähnlichen Zeiten Commited.
|
|
Dies ist dadurch zu erklären, dass ein Großteil der Nutzer aus den USA bzw. Europa kommt und das somit diese Zeiten besonders häufig vorkommen.
|
|
Zum bestimmen, von auffälligen Commits sollte die Abweichung von eines Commits von der sonstigen Tageszeit des Nutzers benutzt werden. Hierzu muss ein Nutzer aber schon eine gewisse Menge an Commits haben.
|
|
|
|
|
|
### 3.3 Menge an Commits pro Person
|
|
|
|
```{r warning = FALSE}
|
|
i <- as.data.frame(table(commits$name))
|
|
i <- filter(i, Freq < 50)
|
|
ggplot(i, aes(x=Freq)) + geom_histogram(bins=30) +
|
|
theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) +
|
|
xlab("Nutzer Anzahl") +
|
|
ylab("Commits Anzahl")
|
|
```
|
|
|
|
|
|
Bei diesem Datensatz fällt auf, dass die Menge an Commits pro Person ein Faktor mit wenig Einfluss ist.
|
|
Das Problem liegt darin, dass bei diesem Repository ein Großteil der Nutzer nur wenige Commits hat.
|
|
Es ist also nicht möglich eine Abweichung von der Norm als Indikator für auffällige Commits zu verwenden.
|
|
Allerdings sollte Personen mit keinem existierenden Commit etwas weniger vertraut werden, auch ist diese Graphik nur
|
|
auf den einen Datensatz abgestimmt. In anderen Projekten kann es vorkommen, dass weniger Menschen an dem Projekt beteiligt sind, aber sie dafür mehr
|
|
Commits pro Person haben.
|
|
|
|
|
|
### 3.4 Dateien die Geändert wurden
|
|
|
|
```{r warning = FALSE}
|
|
i <- as.data.frame(table(diffs$file))
|
|
i <- i[!grepl("=>", i$Var1), ]
|
|
ggplot(i, aes(x=Freq)) + geom_histogram(bins=100) +
|
|
xlab("Änderungen") +
|
|
ylab("Häufigkeit")
|
|
```
|
|
|
|
Wenn man die veränderten Dateien visualisiert, ist bemerkbar, dass sehr viele Dateien nur wenig verändert werden.
|
|
Im Gegensatz zu der Vorherigen Analyse hat dies hier aber positive Konnotationen, da es aufzeigt das im diesem Datensatz die meisten der ~2000 Dateien nur
|
|
wenige Male verändert werden, wodurch jede weitere Veränderung als Auffällig angesehen werden kann.
|
|
|
|
|
|
### 3.5 Unterzeichnete Commits
|
|
|
|
```{r warning = FALSE}
|
|
i <- as.data.frame(table(commits$signed))
|
|
ggplot(i, aes(x=Var1, y=Freq)) + geom_bar(stat = "identity") +
|
|
xlab("Signiert") +
|
|
ylab("Häufigkeit")
|
|
```
|
|
|
|
Signierte Commits existieren, um den Urheber eines Commits festzustellen zu können, sodass keine Commits unter falschen Namen veröffentlicht werden können, Ein Commit der signiert wurde ist somit vertrauenswürdiger als andere Commits. In diesem Datensatz sind die meisten Commits unsigniert, weshalb die Implikationen eines unsignierten Commits eher gering sind.
|
|
|
|
## 4 Aufstellung eines Prädiktiven Models
|
|
|
|
Bei der Aufstellung eines Prädiktiven Models ist leider ein Problem aufgetreten, welches ich zeitlich nicht mehr in der Lage war zu korrigieren.
|
|
Die Annahme besteht, dass der Datensatz keine schädlichen Einträge enthält und die die einzelnen Einträge ebenfalls nicht gelabeled sind.
|
|
Dadurch sind viele ML-Ansätze für diesen Datensatz nicht zu gebrauchen.
|
|
Mein gewählter Ansatz wäre ein Isolation Forest gewesen, allerdings hat das Package nicht funktioniert und ich habe zeitlich keine andere Lösung mehr finden können.
|
|
|
|
|
|
|
|
## 5 Fazit
|
|
Zusammenfassend lässt sich feststellen, dass dieser Datensatz nicht meinen Vorhersagen entsprochen hat.
|
|
|
|
- Bei der Tageszeit des Commits lässt sich ein deutliches Bias zu Arbeitszeiten in dem Amerikanischen und Europäischen Raum feststellen.
|
|
- Wenige Personen nutzen das Signieren von Commits als Sicherheitsfunktion.
|
|
- Ein Großteil der Dateien in einem Repository wird nur wenig verändert.
|
|
|
|
Verbesserte Funktionalität währe durch die Analyse von weiteren Faktoren möglich die nicht in dieser Analyse einbezogen wurden,
|
|
da sie zu komplex währen und das Thema dieser Arbeit überschreiten würden.
|
|
Zur weiteren Verbesserung wäre eine Änderung der Sprache hilfreich, um eine höhere Geschwindigkeit zu erreichen,
|
|
sowie in der Lage zu sein das Programm automatisiert zu nutzen und einzubinden.
|
|
Auch sollte die Analyse nicht jedes Mal für das ganze Repository erfolgen, sondern einzeln für neue Commits berechnet werden.
|
|
|
|
## Quellen
|
|
|
|
Sämtlicher Quellcode dieser Arbeit ist online verfügbar unter:
|
|
https://code.booklordofthe.dev/Booklordofthedings/Watchtower
|
|
|
|
- Git
|
|
- Url: https://git-scm.com/
|
|
- Zugriff: 20.11.2024
|
|
- Diskrete Code Backdoor
|
|
- Url: https://nvd.nist.gov/vuln/detail/CVE-2024-3094
|
|
- Zugriff: 20.11.2024
|
|
- SDL
|
|
- Url: https://www.libsdl.org/
|
|
- Zugriff: 20.11.2024
|
|
|
|
## Dependencies
|
|
- **Git**
|
|
*Repository herunterladen und Statistiken extrahieren*
|
|
- **Windows**
|
|
*Die Setup Skripts sind aktuell nur als .bat Dateien vorhanden*
|
|
- **Beef**
|
|
*C# Ähnliche Sprache, welche ich als Skriptsprache verwende*
|
|
- **R**
|
|
*Analysesprache für dieses Projekt*
|
|
- **R Markdown**
|
|
*Um dieses Dokument zu generieren*
|
|
- **Anytime**
|
|
*Unix Timestamp zu Zeit Objekt umwandeln*
|
|
- **Plyr**
|
|
*Utility Funktionen für Datensätze*
|
|
- **Dplyr**
|
|
*Datenmanipulations Bibliothek*
|
|
- **GGplot2**
|
|
*Bessere Plotting Funktionalität*
|
|
- **lubridate**
|
|
*Vereinfachtes verarbeiten von Datum und Zeitobjekten*
|
|
|
|
## Worterklärungen
|
|
- Repository
|
|
*Ein Aufbewahrungs/Sammlungs -ort für Software Quellcode*
|
|
- Commit
|
|
*Eine bestimmte Änderung an einem Repository. Kann Datein hinzufügen, entfernen oder Ändern*
|
|
- Binäre Datei
|
|
*Ein Dateityp, welcher ein bestimmtes Program zum lesen braucht und nicht in Textform vorhanden ist. Die meisten Bild Dateien sind zum Beispiel Binäre Dateien*
|
|
|
|
</div> |