diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c46bf30c549227d08fea8edb880d63c57b7dc45a
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="BranchesTreeState">
+    <expand>
+      <path>
+        <item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
+        <item name="LOCAL_ROOT" type="e8cecc67:BranchNodeDescriptor" />
+      </path>
+    </expand>
+    <select />
+  </component>
+  <component name="ChangeListManager">
+    <list default="true" id="f54bb93f-1ebd-4e7e-a94e-f90b5ecaf90a" name="Default Changelist" comment="">
+      <change afterPath="$PROJECT_DIR$/docker-compose.yml" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/app.py" beforeDir="false" />
+      <change beforePath="$PROJECT_DIR$/main.py" beforeDir="false" afterPath="$PROJECT_DIR$/main.py" afterDir="false" />
+      <change beforePath="$PROJECT_DIR$/requirements.txt" beforeDir="false" afterPath="$PROJECT_DIR$/requirements.txt" afterDir="false" />
+    </list>
+    <option name="SHOW_DIALOG" value="false" />
+    <option name="HIGHLIGHT_CONFLICTS" value="true" />
+    <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+    <option name="LAST_RESOLUTION" value="IGNORE" />
+  </component>
+  <component name="Git.Settings">
+    <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+  </component>
+  <component name="ProjectId" id="249a0qEgfC8HD9PTFP9mlVwxDOa" />
+  <component name="ProjectViewState">
+    <option name="hideEmptyMiddlePackages" value="true" />
+    <option name="showLibraryContents" value="true" />
+  </component>
+  <component name="PropertiesComponent">
+    <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
+    <property name="last_opened_file_path" value="$PROJECT_DIR$" />
+    <property name="settings.editor.selected.configurable" value="com.jetbrains.python.configuration.PythonContentEntriesConfigurable" />
+  </component>
+  <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
+  <component name="TaskManager">
+    <task active="true" id="Default" summary="Default task">
+      <changelist id="f54bb93f-1ebd-4e7e-a94e-f90b5ecaf90a" name="Default Changelist" comment="" />
+      <created>1643045037022</created>
+      <option name="number" value="Default" />
+      <option name="presentableId" value="Default" />
+      <updated>1643045037022</updated>
+    </task>
+    <servers />
+  </component>
+  <component name="Vcs.Log.Tabs.Properties">
+    <option name="TAB_STATES">
+      <map>
+        <entry key="MAIN">
+          <value>
+            <State />
+          </value>
+        </entry>
+      </map>
+    </option>
+  </component>
+  <component name="WindowStateProjectService">
+    <state x="-1496" y="270" key="#com.intellij.execution.impl.EditConfigurationsDialog" timestamp="1643045084941">
+      <screen x="-1920" y="71" width="1920" height="1080" />
+    </state>
+    <state x="-1496" y="270" key="#com.intellij.execution.impl.EditConfigurationsDialog/-1920.71.1920.1080/0.0.1920.1200@-1920.71.1920.1080" timestamp="1643045084941" />
+    <state x="-1237" y="417" key="#com.intellij.fileTypes.FileTypeChooser" timestamp="1643052698194">
+      <screen x="-1920" y="71" width="1920" height="1080" />
+    </state>
+    <state x="-1237" y="417" key="#com.intellij.fileTypes.FileTypeChooser/-1920.71.1920.1080/0.0.1920.1200@-1920.71.1920.1080" timestamp="1643052698194" />
+    <state x="-1451" y="247" key="SettingsEditor" timestamp="1643045118299">
+      <screen x="-1920" y="71" width="1920" height="1080" />
+    </state>
+    <state x="-1451" y="247" key="SettingsEditor/-1920.71.1920.1080/0.25.1920.1175@-1920.71.1920.1080" timestamp="1643045118299" />
+    <state x="-1295" y="312" width="670" height="676" key="search.everywhere.popup" timestamp="1643052713613">
+      <screen x="-1920" y="71" width="1920" height="1080" />
+    </state>
+    <state x="-1295" y="312" width="670" height="676" key="search.everywhere.popup/-1920.71.1920.1080/0.0.1920.1200@-1920.71.1920.1080" timestamp="1643052713613" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/README.md b/README.md
index d2dbac82007821ed3a0e47fbcce485d77298c8d4..132fe26847ef76089fd3e4b154e3b40723913368 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # challenge-security-web-applications
 
-## Datenbank, tabelle und Benutzer anlegen
+## Datenbank, Tabelle und Benutzer anlegen
 
 Die Datenbank wird in einem PostgreSQL Docker Container erstellt, der über `docker-compose` gestartet wird.
 
@@ -21,13 +21,39 @@ Im nächsten Schritt wird die Tabelle `users` angelegt und drei Benutzer hinzuge
 ```sql
 CREATE TABLE users (
     username varchar(10),
-    admin boolean
+    is_admin boolean
 );
 
 INSERT INTO users
-    (username, admin)
+    (username, is_admin)
 VALUES
     ('alice', true),
     ('bob', false),
     ('mallory', false);
 ```
+
+
+## Erklärung
+
+Das Python Programm wird wie folgt aufgerufen: `python main.py "<username>"`
+
+Mit der Übergabe eines Benutzernamens, wird überprüft, ob dieser ein Administrator ist. Aufgrund einer Schwachstelle in der `SELECT` Abfrage des Programm Codes, besteht nun aber die Möglichkeit Benutzern Administrator Rechte zu geben, ohne sich auf der Datenbank einzuloggen.
+
+```
+# Überprüfen ob der Benutzer 'mallory' ein Adminstrator ist
+python main.py "mallory"
+
+# Schwachstelle ausnutzen und 'mallory' Administrator Rechte geben
+python main.py "'; update users set is_admin = 'true' where username = 'mallory'; select true; --"
+```
+
+Ruft man nun die Funktion wieder mit dem Benutzernamen auf `python main.py "mallory"` bekommt man statt `False` nun ein `True` zurückgegeben.
+Die Schwachstelle in der Abfrage besteht darin, da keine Überprüfung erfolgt, welcher `string` in die Abfrage übergeben wird. Das Semikolon innerhalb der Abfrage spielt eine Entscheide Rolle, da es SQL Abfragen terminiert. Da keine weitere Überprüfung, des Inhalts erfolgt, den wir an die Funktion übergeben, können wir nun mithilde eines `UPDATE` Befehls Werte innerhalb der Tabelle anpassen.
+
+Die Schwachstelle im Code (`SQL Abfrage`) kann wie folgt behoben werden:
+
+```
+"""SELECT is_admin FROM users WHERE username = %(username)s """, {'username': username}
+```
+
+Die Query wird nicht mehr mittels String Interpolation (`'%s' """ % username`) zusammengesetzt und an den Datenbankserver gesendet. Durch Abfrageparameter `%(username)s """, {'username': username}` wird nun sichergestellt, das der richtige Typ und Wert als `Parameter` an die Abfrage übergeben wird.
\ No newline at end of file
diff --git a/main.py b/main.py
index 59d8061476b45a302de0a77ea2f73552ae8cff22..c59eb4d52749f25fd48b0ef71ac226f0321598c5 100644
--- a/main.py
+++ b/main.py
@@ -3,27 +3,19 @@ import psycopg2
 
 
 def get_connection():
-    db_connect = psycopg2.connect(
-        host="localhost",
-        database="postgres",
-        user="postgres",
-        password="postgres",
-    )
+    db_connect = psycopg2.connect(host="localhost", database="postgres", user="postgres", password="postgres")
     db_connect.set_session(autocommit=True)
     return db_connect
 
 
 def is_admin(username: str) -> bool:
     conn = get_connection()
-    with conn.cursor() as cursor:
-        # UNSECURE
-        cursor.execute("""SELECT admin FROM users WHERE username = '%s' """ % username)
-
-        # SECURE
-        #cursor.execute("""SELECT admin FROM users WHERE username = %(username)s """, {'username': username})
 
+    with conn.cursor() as cursor:
+        cursor.execute("""SELECT is_admin FROM users WHERE username = '%s' """ % username)
         result = cursor.fetchone()
 
+    # fetchone gibt NONE zurück, falls kein Benutzer gefunden wird
     if result is None:
         return False
 
@@ -33,5 +25,4 @@ def is_admin(username: str) -> bool:
 
 if __name__ == "__main__":
     username = str(argv[1])
-    # is_admin("'; update users set admin = 'true' where username = 'mallory'; select true; --")
     print(username + " is an admin: " + str(is_admin(username)))
\ No newline at end of file