\section{App}

\subsection{Beschreibung der App}

Die App soll eine einfache Erstellung von Aufgaben anbieten. Der Task soll erstellt, erledigt und gelöscht werden können. Jeder Benutzer sieht nur seine Tasks und kann auch nur seine eigenen Tasks bearbeiten. Als Frontend wird HTML\footnote{\href{https://developer.mozilla.org/en-US/docs/Web/HTML}{HTML}}, CSS\footnote{\href{https://developer.mozilla.org/en-US/docs/Learn/CSS/First_steps/What_is_CSS}{CSS}} und JavaScript\footnote{\href{https://www.javascript.com/}{JavaScript}} verwendet. Im Backend kommt eine SQLite\footnote{\href{https://sqlite.org/index.html}{SQLite}} und Go\footnote{\href{https://go.dev/}{Go}} zum Einsatz.

\subsection{OWASP Top Ten}

Im Folgenden werden Schwachstellen in Kategorien der OWASP Top Ten eingeteilt.

\cite[vgl. dazu][]{owasp}

\subsection{A7:2021 - Identification and Authentication Failures} \label{first}

\subsubsection{Beschreibung der Schwachstellen}

Der Benutzer muss sich vor der Nutzung der App Registrieren (Abbildung \ref{fig:Registrieren}).

\begin{figure}[H]
    \begin{center}
        \begin{subfigure}[b]{0.48\textwidth}
            \includegraphics[width=\textwidth]{app/app-01}
            \caption{Registrieren}
            \label{fig:Registrieren}
        \end{subfigure}
        \begin{subfigure}[b]{0.48\textwidth}
            \includegraphics[width=\textwidth]{app/app-02}
            \caption{Login}
            \label{fig:Login}
        \end{subfigure}
    \end{center}
    \caption{Authentifizierung}
    \label{fig:Authentifizierung}
\end{figure}

Wenn ein Nutzer schon existiert wird die Fehlermeldung der Datenbank zurückgegeben und angezeigt. Dadurch kann man schon registrierte Benutzernamen leicht erkennen. Sogar wenn ein Feld leer ist wird es zur Überprüfung an das Backend geschickt.

\begin{figure}[H]
    \begin{center}
        \begin{subfigure}[b]{0.48\textwidth}
            \includegraphics[width=\textwidth]{app/app-04}
            \caption{Benutzername existiert}
            \label{fig:Benutzername existiert}
        \end{subfigure}
        \begin{subfigure}[b]{0.48\textwidth}
            \includegraphics[width=\textwidth]{app/app-03}
            \caption{Keine Eingabe des Passwords}
            \label{fig:Keine Eingabe des Passwords}
        \end{subfigure}
    \end{center}
    \caption{Fehler bei der Authentifizierung}
    \label{fig:Fehler bei der Authentifizierung}
\end{figure}

Wenn der Benutzer sich anmeldet, wir ein Cookie mit dem Nutzernamen im Frontend gespeichert (Abbildung \ref{fig:Gespeichertes Cookie}). Zusätzlich wird im Backend vermerkt, dass der Nutzer angemeldet ist. Somit reicht es im Frontend aus, nur den Benutzernamen als Authentifizierung im Header mitzuschicken. Damit kann durch z.B. das Raten von Nutzernamen mit den Registrierung-Fehlermeldungen, unbefugter Zugriff auf die App erfolgen.

\begin{figure}[H]
    \begin{center}
        \includegraphics[width=0.8\textwidth]{app/app-05}
        \caption{Gespeichertes Cookie}
        \label{fig:Gespeichertes Cookie}
    \end{center}
\end{figure}

\newpage

\subsubsection{Schwachstelle ausbessern}

Bei der Registrierung und dem Anmelden sollte sowohl im Frontend als auch im Backend auf Fehler validiert werden. In Frameworks wie Vue, React oder Angular kann dies einfach gemacht werden. Zusätzlich bieten Backends eine Säuberungsfunktion für Form-Daten an, die unerlaubte Zeichen verhindern.

Fehlermeldungen sollten nur das nötigste dem Benutzer verraten. Wenn die Fehlermeldung der Datenbank ans Frontend gesendet wird kann das zu erheblichen Sicherheitslücken führen. Die gezeigte Fehlermeldung ``UNIQUE constraint failed: users.username'' gibt preis, dass der Benutzer schon existiert und kann dadurch zum Anmelden missbraucht werden.

Ein Login mit JWT Token\footnote{\href{https://jwt.io/}{JWT}} erscheint hier sinnvoller, da dies verschiedene Vorteile hat:
\begin{list}{-}{}
    \item Ablaufdatum -> Kann nur für eine bestimmte Zeit ausgenutzt werden
    \item Zufällig -> Kann nicht erraten werden, wie z.B. der Benutzername
    \item Verifizierung möglich
\end{list}

Die Abspeicherung des Login-Status im Backend ist eine große Sicherheitslücke. Damit kann der Angreifer mit einer Liste von Benutzernamen so lange probieren, bis er sich, als einer der Nutzer der eingeloggt ist, anmelden kann. Durch den JWT Token würde der Login-Prozess ohne die Abspeicherung des aktuellen Status des Nutzers ablaufen.

\newpage

\subsection{A3:2021 - Injection}

\subsubsection{Beschreibung der Schwachstellen}

Es kann in der App nach Aufgaben gesucht werden (Abbildung \ref{fig:Suchen im Frontend}). Der eingegebene Filter wird dazu an das Backend geschickt und als Antwort kommt eine liste an Aufgaben zurück (Abbildung \ref{fig:Suchen im Backend}). Die eigentliche Suchfunktion wird hierbei von Backend übernommen.

\begin{figure}[H]
    \begin{center}
        \includegraphics[width=0.7\textwidth]{app/app-07}
        \caption{Suchen im Frontend}
        \label{fig:Suchen im Frontend}
    \end{center}
\end{figure}
\begin{figure}[H]
    \begin{center}
        \includegraphics[width=0.7\textwidth]{app/app-08}
        \caption{Suchen im Backend}
        \label{fig:Suchen im Backend}
    \end{center}
\end{figure}

\newpage

Nun kann allerdings durch eine Injection das Anzeigen aller Aufgaben erzwungen werden (Abbildung \ref{fig:SQL Injection}). Damit kann der Angreifer alle Nutzernamen und deren Aufgaben sehen.

\begin{figure}[H]
    \begin{center}
        \includegraphics[width=0.9\textwidth]{app/app-09}
        \caption{SQL Injection}
        \label{fig:SQL Injection}
    \end{center}
\end{figure}

\newpage

\subsubsection{Schwachstelle ausbessern}

Der Code im Backend ist fehlerhaft. Anstatt die von Go zur Verfügung gestellte ``Sprintf'' Funktion zu nutzen (Abbildung \ref{fig:Fehlerhafter Code}), sollte die von GORM\footnote{\href{https://gorm.io/}{GORM ORM Library}} abgesicherte Art der SQL Query verwendet werden (Abbildung \ref{fig:Korrekter Code}). Damit können Injections verhindert werden (Abbildung \ref{fig:SQL Injection verhindert}).

\begin{figure}[H]
    \begin{center}
        \includegraphics[width=0.9\textwidth]{app/app-06}
        \caption{Fehlerhafter Code}
        \label{fig:Fehlerhafter Code}
    \end{center}
\end{figure}
\begin{figure}[H]
    \begin{center}
        \includegraphics[width=0.9\textwidth]{app/app-10}
        \caption{Korrekter Code}
        \label{fig:Korrekter Code}
    \end{center}
\end{figure}
\begin{figure}[H]
    \begin{center}
        \includegraphics[width=0.8\textwidth]{app/app-11}
        \caption{SQL Injection verhindert}
        \label{fig:SQL Injection verhindert}
    \end{center}
\end{figure}

\newpage

\subsection{A1:2021 - Broken Access Control}

\subsubsection{Beschreibung der Schwachstellen}

CORS im Backend wurde ausgeschaltet um das Entwickeln einfacher zu machen.

Es gibt einen API Endpunkt in dem das Benutzerpassword ohne Authentifizierung geändert werden kann (Abbildung \ref{fig:Password geändert ohne Authentifizierung}). Es müssen lediglich der Nutzer und das neue Passwort angegeben werden. Der Endpunkt wurde beim hochladen auf den Server vergessen.

Das Password wird außerdem im Plaintext in der Datenbank gespeichert und kann von jedem mit Datenbank-Zugriff ausgelesen werden.

\begin{figure}[H]
    \begin{center}
        \includegraphics[width=0.8\textwidth]{app/app-12}
        \caption{Password geändert ohne Authentifizierung}
        \label{fig:Password geändert ohne Authentifizierung}
    \end{center}
\end{figure}
\begin{figure}[H]
    \begin{center}
        \includegraphics[width=0.5\textwidth]{app/app-14}
        \caption{Datenbank}
        \label{fig:Datenbank}
    \end{center}
\end{figure}

\subsubsection{Schwachstelle ausbessern}

Cors sollte eingeschaltet und konfiguriert werden, damit Anfragen auch nur von dem als sicher geltenden Frontend verschickt werden.

Passwortänderungen müssen mit einer eindeutigen Verifizierung über das aktuelle Password, eine E-Mail o.Ä. abgesichert sein. Der Benutzer wird durch die Attacke dauerhaft aus dem System ausgesperrt.

Das Abspeichern der Passwörter darf nur verschlüsselt erfolgen. Zum Beispiel werden im Django Framework\footnote{\href{https://docs.djangoproject.com/en/4.0/topics/auth/passwords/}{Password management in Django}} zu fast jedem Algorithmus Lösungen angeboten.

\subsection{A7:2017 - Cross-Site Scripting (XSS)}

\subsubsection{Beschreibung der Schwachstellen}

Wie schon im Abschnitt \ref{first} beschrieben, findet keinerlei Texteingabe-Validierung statt. Somit kann als Aufgabe beliebiger HTML oder JavaScript Code wie z.B. ein Button, der Cookies anzeigt eingefügt werden (Abbildung \ref{fig:XSS Angriff}). 

\begin{verbatim}
<button onclick="alert(document.cookie)" class="btn btn-primary">Get Cookie</button>
\end{verbatim}

\begin{figure}[H]
    \begin{center}
        \includegraphics[width=0.8\textwidth]{app/app-13}
        \caption{XSS Angriff}
        \label{fig:XSS Angriff}
    \end{center}
\end{figure}

\subsubsection{Schwachstelle ausbessern}

Jeglicher Text der eingegeben oder wieder auf der Website angezeigt wird, sollte auf typische Syntax überprüft werden. URLs oder externe Web-Resources sollten außerdem ausgeschaltet werden. Außerdem, wenn möglich die Interaktion des Nutzers durch Kommentare vermeiden oder nur im geringen Maße zulassen. Eine Überprüfung des Kommentars durch eine Person kann außerdem eingebaut werden.
