diff --git a/20231207/Zeichen_123.pdf b/20231207/Zeichen_123.pdf new file mode 120000 index 0000000000000000000000000000000000000000..fdbc897227df059cfda790a16555e6e417682116 --- /dev/null +++ b/20231207/Zeichen_123.pdf @@ -0,0 +1 @@ +../common/Zeichen_123.pdf \ No newline at end of file diff --git a/20231207/dbs-20231207.pdf b/20231207/dbs-20231207.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0ed5fc0a3320efa5dec3a3c373b1e2c3ed4775fe Binary files /dev/null and b/20231207/dbs-20231207.pdf differ diff --git a/20231207/dbs-20231207.tex b/20231207/dbs-20231207.tex new file mode 100644 index 0000000000000000000000000000000000000000..2296ae2843ec63b2d755855dbfda23f9323fc86b --- /dev/null +++ b/20231207/dbs-20231207.tex @@ -0,0 +1,278 @@ +% dbs-20221207.pdf - Lecture Slides on Databases and Information Security +% Copyright (C) 2023 Peter Gerwinski +% +% This document is free software: you can redistribute it and/or +% modify it either under the terms of the Creative Commons +% Attribution-ShareAlike 3.0 License, or under the terms of the +% GNU General Public License as published by the Free Software +% Foundation, either version 3 of the License, or (at your option) +% any later version. +% +% This document is distributed in the hope that it will be useful, +% but WITHOUT ANY WARRANTY; without even the implied warranty of +% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +% GNU General Public License for more details. +% +% You should have received a copy of the GNU General Public License +% along with this document. If not, see <http://www.gnu.org/licenses/>. +% +% You should have received a copy of the Creative Commons +% Attribution-ShareAlike 3.0 Unported License along with this +% document. If not, see <http://creativecommons.org/licenses/>. + +% README: Funktionen, Trigger, SQL Injection + +\documentclass[10pt,t]{beamer} + +\usepackage{pgslides} + +\newcommand{\vfilll}{\vspace{0pt plus 1filll}} + +\newcommand{\underconstruction}{% + \begin{picture}(0,0) + \put(11,1.2){\makebox(0,0)[b]{\includegraphics[width=1.5cm]{Zeichen_123.pdf}}} + \put(11,0.9){\makebox(0,0)[t]{\shortstack{Änderungen\\vorbehalten}}} + \end{picture}} + +\title{Datenbanken und Datensicherheit} +\author{Prof.\ Dr.\ rer.\ nat.\ Peter Gerwinski} +\date{7.\ Dezember 2023} + +\begin{document} + +\maketitleframe + +\nosectionnonumber{\inserttitle} + +\begin{frame} + + \shownosectionnonumber + + \begin{itemize} + \item[\textbf{1}] \textbf{Einführung} + \hfill\makebox(0,0)[br]{\raisebox{2.25ex}{\url{https://gitlab.cvh-server.de/pgerwinski/dbs}}}% + \item[\textbf{2}] \textbf{Kurzeinführung Unix} + \item[\textbf{3}] \textbf{Kurzeinführung TCP/IP} + \item[\textbf{4}] \textbf{Relationale Datenbanken} + \begin{itemize} + \vspace*{-\smallskipamount} + \item[\textbf{\dots}] + \item[4.7] Datensicherung + \color{medgreen} + \item[4.8] Transaktionen + \item[4.9] Indizierung + \color{red} + \item[4.10] Funktionen und Trigger + \color{orange} + \item[4.11] GUI-Zugriff + \color{red} + \item[4.12] SQL Injection + \color{black} + \item[4.13] Sonstige Datenbanken + \end{itemize} + \item[\textbf{5}] \textbf{Kryptographie} + \begin{itemize} + \item[5.1] Einführung + \vspace*{-\smallskipamount} + \item[\textbf{\dots}] + \end{itemize} + \vspace*{-\smallskipamount} + \item[\textbf{\dots}] + \end{itemize} + + \vfilll + \underconstruction + +\end{frame} + +\setcounter{section}{3} +\section{Relationale Datenbanken} +\setcounter{subsection}{7} +\subsection{Transaktionen} + +\begin{frame}[fragile] + + \showsection + \showsubsection + + \begin{itemize} + \item + Ziel: Wahrung der Konsistenz + \item + Methode: zusammengehörige Aktionen zu einer \newterm{Transaktion} zusammenfassen + \item + Beispiel: Überweisung\\ + Betrag von einem Konto subtrahieren\\ + und "`gleichzeitig"' zu einem anderen Konto addieren + \item + Realisierung in PostgreSQL: + \lstinline[style=cmd]{BEGIN;} \dots\ \lstinline[style=cmd]{COMMIT;} + \item + Realisierung in MariaDB: + \lstinline[style=cmd]{START TRANSACTION;} \dots\ \lstinline[style=cmd]{COMMIT;} + \item + Abbruch einer Transaktion: + \lstinline[style=cmd]{ROLLBACK;} statt \lstinline[style=cmd]{COMMIT;} + \end{itemize} + +\end{frame} + +\subsection{Indizierung} + +\begin{frame}[fragile] + + \showsection + \showsubsection + + \begin{itemize} + \item + Ziel: Performanzgewinn + \item + Methode: Spalten, in denen häufig gesucht wird, sortieren + \item + Beispiel: Datenbank mit Kontaktdaten\\ + Suche nach Name, Adresse, Telefonnummer + \item + Realisierung in PostgreSQL und MariaDB: + \begin{lstlisting}[style=cmd,gobble=8] + CREATE INDEX <Indexname> ON <Tabellenname> + ( + <Spaltenname>, + ... + ); + \end{lstlisting} + \item + Vorteil: schnellere Suche (\lstinline[style=cmd]{SELECT}) in indizierten Spalten +% \pause + \item + Nachteil: langsameres Einfügen/Ändern/Löschen + \end{itemize} + +\end{frame} + +\subsection{Funktionen und Trigger} + +\begin{frame} + + \showsection + \showsubsection + + Funktionen: + \begin{itemize} + \item + \lstinline[style=cmd]{PROCEDURE} entspricht einer \lstinline{void}-Funktion in C. + \item + \url{https://www.postgresql.org/docs/15/sql-createprocedure.html} + \end{itemize} + + \bigskip + + Trigger: + \begin{itemize} + \item + \url{https://www.sqltutorial.org/sql-triggers/} + \item + \url{https://www.postgresqltutorial.com/postgresql-triggers/creating-first-trigger-postgresql/} + \end{itemize} + +\end{frame} + +\subsection{GUI-Zugriff} + +\begin{frame} + + \showsection + \showsubsection + + \begin{itemize} + \item + Anwendung nutzt DBMS-Client-Bibliothek\\ + GUI-Programmierung: wie gewohnt + \item + Spezialfall: Web-Anwendung + \end{itemize} + + \bigskip + + Beispiel: Programmiersprache PHP + \begin{itemize} + \item + Integration in HTML-Quelltext: \lstinline{<?php ... ?>} + \item + Objekt zur Kommunikation mit Datenbanken: \lstinline{PDO} + \end{itemize} + + \bigskip + + Literatur: + \begin{itemize} + \item + \url{https://www.postgresqltutorial.com/postgresql-php/connect/} + \item + \url{https://www.phptutorial.net/php-pdo/pdo-connecting-to-postgresql/} + \end{itemize} + +\end{frame} + +\subsection{SQL Injection} + +\begin{frame} + + \showsection + \showsubsection + + Literatur: + \begin{itemize} + \item + \url{https://xkcd.com/327/} + \end{itemize} + +\end{frame} + +\iffalse + +\subsection{Sonstige Datenbanken} + +\begin{frame} + + \showsection + \showsubsection + + \begin{itemize} + \item + Eingebettete Datenbanken:\\ + Berkeley DB, SQLite\\ + Software-Bibliothek, keine Client-Server-Struktur + \item + Nicht-relationale Datenbanken:\\ + dokumentenorientierte Datenbanken, noSQL\\ + Performanz wichtiger als Konsistenz\\ + \textarrow\ Applikationen stärker in Konsistenzprüfung eingebunden + \end{itemize} + +\end{frame} + +\section{Kryptographie} +\subsection{Einführung} + +\begin{frame} + + \showsection + \showsubsection + + \begin{itemize} + \item + Verschlüsselung: symmetrisch, asymmetrisch, hybrid + \item + Hashes: Einwegfunktionen, Salt + \item + Signaturen, Zertifikate + \item + Schlüsselaustausch + \end{itemize} + +\end{frame} + +\fi + +\end{document} diff --git a/20231207/functions-01.txt b/20231207/functions-01.txt new file mode 100644 index 0000000000000000000000000000000000000000..bb84b14be75de373bfec371af3d2b9ec84182f7b --- /dev/null +++ b/20231207/functions-01.txt @@ -0,0 +1,154 @@ +testdb=> \d + Liste der Relationen + Schema | Name | Typ | Eigentümer +--------+------------------+---------+------------ + public | account | Tabelle | dbs + public | account_id_seq | Sequenz | dbs + public | cd | Tabelle | dbs + public | cd_cd_id_seq | Sequenz | dbs + public | customer | Tabelle | dbs + public | customer_id_seq | Sequenz | dbs + public | interpret | Tabelle | dbs + public | interpret_id_seq | Sequenz | dbs + public | lied | Tabelle | dbs + public | lied_auf_cd | Sicht | dbs + public | test | Tabelle | dbs + public | tier | Tabelle | dbs + public | tier_id_seq | Sequenz | dbs +(13 Zeilen) + +testdb=> \d customer + Tabelle »public.customer« + Spalte | Typ | Sortierfolge | NULL erlaubt? | Vorgabewert +------------+---------+--------------+---------------+-------------------------------------- + id | integer | | not null | nextval('customer_id_seq'::regclass) + lastname | text | | | + firstname | text | | | + account_id | integer | | | +Indexe: + "customer_pkey" PRIMARY KEY, btree (id) +Fremdschlüssel-Constraints: + "customer_fkey_account_id" FOREIGN KEY (account_id) REFERENCES account(id) + +testdb=> \d account + Tabelle »public.account« + Spalte | Typ | Sortierfolge | NULL erlaubt? | Vorgabewert +---------+---------+--------------+---------------+------------------------------------- + id | integer | | not null | nextval('account_id_seq'::regclass) + number | text | | | + balance | integer | | | +Indexe: + "account_pkey" PRIMARY KEY, btree (id) + "index_account_number" btree (number) +Fremdschlüsselverweise von: + TABLE "customer" CONSTRAINT "customer_fkey_account_id" FOREIGN KEY (account_id) REFERENCES account(id) + +testdb=> create procedure transfer (sender integer, receiver integer, amount integer) language sql as 'BEGIN; UPDATE account SET balance = balance + amount WHERE id = receiver; UPDATE account SET balance = balance - amount WHERE id = sender; COMMIT;'; +CREATE PROCEDURE +testdb=> select * from customer; + id | lastname | firstname | account_id +----+------------+-----------+------------ + 2 | Mustermann | Erika | 1 + 4 | Rich | Richie | 2 +(2 Zeilen) + +testdb=> select * from account; + id | number | balance +----+-----------------------------+--------- + 1 | DE12 3456 7890 ABCD EFGH IJ | 1000001 + 2 | DE98 7654 3210 ABCD EFGH IJ | 3999999 +(2 Zeilen) + +testdb=> call transfer (2, 4, 1); +FEHLER: BEGIN ist in SQL-Funktionen nicht erlaubt +KONTEXT: SQL-Funktion »transfer« beim Start +testdb=> create or replace procedure transfer (sender integer, receiver integer, amount integer) language sql as 'UPDATE account SET balance = balance + amount WHERE id = receiver; UPDATE account SET balance = balance - amount WHERE id = sender;'; +CREATE PROCEDURE +testdb=> call transfer (2, 4, 1); CALL testdb=> select * from account; id | number | balance ----+-----------------------------+--------- + 1 | DE12 3456 7890 ABCD EFGH IJ | 1000001 + 2 | DE98 7654 3210 ABCD EFGH IJ | 3999998 +(2 Zeilen) + +testdb=> call transfer (1, 2, 1); +CALL +testdb=> select * from account; + id | number | balance +----+-----------------------------+--------- + 2 | DE98 7654 3210 ABCD EFGH IJ | 3999999 + 1 | DE12 3456 7890 ABCD EFGH IJ | 1000000 +(2 Zeilen) + +testdb=> call transfer (select account_id from customer where lastname = 'Mustermann', select account_id from customer where lastname = 'Rich', 1); +FEHLER: Syntaxfehler bei »select« +ZEILE 1: call transfer (select account_id from customer where lastnam... + ^ +testdb=> call transfer ((select account_id from customer where lastname = 'Mustermann'), (select account_id from customer where lastname = 'Rich'), 1); +FEHLER: Unteranfragen können nicht in CALL-Argument verwendet werden +ZEILE 1: call transfer ((select account_id from customer where lastna... + ^ +testdb=> Query failed: Error: Error(s) encountered during statement execution: no such table: moz_hosts +Query failed: Error: Error(s) encountered during statement execution: no such table: moz_hosts +sender integer; +FEHLER: Syntaxfehler bei »sender« +ZEILE 1: sender integer; + ^ +testdb=> declare sender integer; +FEHLER: Syntaxfehler bei »integer« +ZEILE 1: declare sender integer; + ^ +testdb=> set var.sender = 1; +SET +testdb=> set var.sender = ( select account_id from customer where lastname = 'Mustermann' ); +FEHLER: Syntaxfehler bei »(« +ZEILE 1: set var.sender = ( select account_id from customer where las... + ^ +testdb=> var.sender = ( select account_id from customer where lastname = 'Mustermann' ); +FEHLER: Syntaxfehler bei »var« +ZEILE 1: var.sender = ( select account_id from customer where lastnam... + ^ +testdb=> set var.sender = ( select account_id from customer where lastname = 'Mustermann' ); +FEHLER: Syntaxfehler bei »(« +ZEILE 1: set var.sender = ( select account_id from customer where las... + ^ +testdb=> set var.sender = select account_id from customer where lastname = 'Mustermann'; +FEHLER: Syntaxfehler bei »select« +ZEILE 1: set var.sender = select account_id from customer where lastn... + ^ +testdb=> DECLARE sender INTEGER; +FEHLER: Syntaxfehler bei »INTEGER« +ZEILE 1: DECLARE sender INTEGER; + ^ +testdb=> select account_id from customer where lastname = 'Mustermann'; + account_id +------------ + 1 +(1 Zeile) + +testdb=> call transfer (1, 2, 1); CALL +testdb=> select * from account; + id | number | balance +----+-----------------------------+--------- + 2 | DE98 7654 3210 ABCD EFGH IJ | 4000000 + 1 | DE12 3456 7890 ABCD EFGH IJ | 999999 +(2 Zeilen) + +testdb=> \d + Liste der Relationen + Schema | Name | Typ | Eigentümer +--------+------------------+---------+------------ + public | account | Tabelle | dbs + public | account_id_seq | Sequenz | dbs + public | cd | Tabelle | dbs + public | cd_cd_id_seq | Sequenz | dbs + public | customer | Tabelle | dbs + public | customer_id_seq | Sequenz | dbs + public | interpret | Tabelle | dbs + public | interpret_id_seq | Sequenz | dbs + public | lied | Tabelle | dbs + public | lied_auf_cd | Sicht | dbs + public | test | Tabelle | dbs + public | tier | Tabelle | dbs + public | tier_id_seq | Sequenz | dbs +(13 Zeilen) + +testdb=> diff --git a/20231207/logo-hochschule-bochum-cvh-text-v2.pdf b/20231207/logo-hochschule-bochum-cvh-text-v2.pdf new file mode 120000 index 0000000000000000000000000000000000000000..4aa99b8f81061aca6dcaf43eed2d9efef40555f8 --- /dev/null +++ b/20231207/logo-hochschule-bochum-cvh-text-v2.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum-cvh-text-v2.pdf \ No newline at end of file diff --git a/20231207/logo-hochschule-bochum.pdf b/20231207/logo-hochschule-bochum.pdf new file mode 120000 index 0000000000000000000000000000000000000000..b6b9491e370e499c9276918182cdb82cb311bcd1 --- /dev/null +++ b/20231207/logo-hochschule-bochum.pdf @@ -0,0 +1 @@ +../common/logo-hochschule-bochum.pdf \ No newline at end of file diff --git a/20231207/pgslides.sty b/20231207/pgslides.sty new file mode 120000 index 0000000000000000000000000000000000000000..5be1416f4216f076aa268901f52a15d775e43f64 --- /dev/null +++ b/20231207/pgslides.sty @@ -0,0 +1 @@ +../common/pgslides.sty \ No newline at end of file diff --git a/20231207/trigger-01.txt b/20231207/trigger-01.txt new file mode 100644 index 0000000000000000000000000000000000000000..b47a7d934bde6e03b8e44141d4e7d4f233ec4b71 --- /dev/null +++ b/20231207/trigger-01.txt @@ -0,0 +1,62 @@ +testdb=> create table account_log ( account_id integer, change integer, timestamp timestamp ); +CREATE TABLE +testdb=> alter table account_log drop column timestamp; +ALTER TABLE +testdb=> alter table account_log create column datetime timestamp; +FEHLER: Syntaxfehler bei »create« +ZEILE 1: alter table account_log create column datetime timestamp; + ^ +testdb=> alter table account_log add column datetime timestamp; +ALTER TABLE +testdb=> \d account_log + Tabelle »public.account_log« + Spalte | Typ | Sortierfolge | NULL erlaubt? | Vorgabewert +------------+-----------------------------+--------------+---------------+------------- + account_id | integer | | | + change | integer | | | + datetime | timestamp without time zone | | | + +testdb=> create trigger after_update_account after update on account for each row begin if new.balance <> old.balance then insert into account_log ( account_id, change, datetime ) values ( new.id, new.balance - old.balance, now () ) end; +FEHLER: Syntaxfehler bei »begin« +ZEILE 1: ...date_account after update on account for each row begin if n... + ^ +testdb=> create procedure log_change (account_id integer, change integer) language sql as 'INSERT INTO account_log (account_id, change, datetime) values (account_id, change, now ())'; CREATE PROCEDURE +testdb=> create trigger after_update_account after update on account for each row log_change (old.account_id, new.balance - old. balance); FEHLER: Syntaxfehler bei »log_change« +ZEILE 1: ...date_account after update on account for each row log_change... + ^ +testdb=> create trigger after_update_account after update on account for each row call log_change (old.account_id, new.balance - old. balance); +FEHLER: Syntaxfehler bei »call« +ZEILE 1: ...date_account after update on account for each row call log_c... + ^ +testdb=> drop procedure log_change; +DROP PROCEDURE +testdb=> create function log_change (account_id integer, change integer) returns trigger language sql as 'INSERT INTO account_log (account_id, change, datetime) values (account_id, change, now ())'; +FEHLER: SQL-Funktionen können keinen Rückgabetyp »trigger« haben +testdb=> create function log_change (account_id integer, change integer) returns trigger language plpgsql as 'BEGIN; INSERT INTO account_log (account_id, change, datetime) values (account_id, change, now ()); END;'; +FEHLER: Triggerfunktionen können keine deklarierten Argumente haben +TIP: Auf die Argumente des Triggers kann stattdessen über TG_NARGS und TG_ARGV zugegriffen werden. +KONTEXT: Kompilierung der PL/pgSQL-Funktion »log_change« nahe Zeile 1 +testdb=> create function log_change () returns trigger language plpgsql as 'BEGIN; INSERT INTO account_log (account_id, change, datetime) values (account_id, change, now ()); END;'; FEHLER: Syntaxfehler bei »;« +ZEILE 1: ...ange () returns trigger language plpgsql as 'BEGIN; INSERT I... + ^ +testdb=> create function log_change () returns trigger language plpgsql as $$ testdb$> if new.balance <> old.balance then +testdb$> insert into log + +testdb$> insert into log_change (account_id, change, datetime) values (old.id, new.balance - old.balance, now ()); +testdb$> end if; +testdb$> return new; +testdb$> end; +testdb$> $$ +testdb-> ; +FEHLER: Syntaxfehler bei »if« +ZEILE 2: if new.balance <> old.balance then + ^ +testdb=> create function log_change () returns trigger language plpgsql as $$ begin if new.balance <> old.balance then insert into log_change (account_id, change, datetime) values (old.id, new.balance - old.balance, now ()); +end if; +return new; +end; +$$ +; +CREATE FUNCTION +testdb=> create trigger after_update_account after update on account for each row execute procedure log_change (); +CREATE TRIGGER testdb=> diff --git a/20231207/trigger-02.txt b/20231207/trigger-02.txt new file mode 100644 index 0000000000000000000000000000000000000000..11c7709bbdd358a504c4c0f6c7e92ff48ff20d46 --- /dev/null +++ b/20231207/trigger-02.txt @@ -0,0 +1,26 @@ +testdb=> \d Liste der Relationen + Schema | Name | Typ | Eigentümer +--------+------------------+---------+------------ + public | account | Tabelle | dbs + public | account_id_seq | Sequenz | dbs + public | account_log | Tabelle | dbs + public | cd | Tabelle | dbs + public | cd_cd_id_seq | Sequenz | dbs + public | customer | Tabelle | dbs + public | customer_id_seq | Sequenz | dbs + public | interpret | Tabelle | dbs + public | interpret_id_seq | Sequenz | dbs + public | lied | Tabelle | dbs + public | lied_auf_cd | Sicht | dbs + public | test | Tabelle | dbs + public | tier | Tabelle | dbs + public | tier_id_seq | Sequenz | dbs +(14 Zeilen) + +testdb=> call transfer (2, 1, 10); FEHLER: Relation »log_change« existiert nicht +ZEILE 1: insert into log_change (account_id, change, datetime) values... + ^ +ANFRAGE: insert into log_change (account_id, change, datetime) values (old.id, new.balance - old.balance, now ()) +KONTEXT: PL/pgSQL-Funktion log_change() Zeile 3 bei SQL-Anweisung +SQL-Funktion »transfer« Anweisung 1 +testdb=> diff --git a/20231207/trigger-03.txt b/20231207/trigger-03.txt new file mode 100644 index 0000000000000000000000000000000000000000..0c307ff7b17641af9382752311c91fae17a01f11 --- /dev/null +++ b/20231207/trigger-03.txt @@ -0,0 +1,21 @@ +testdb=> create function log_change () returns trigger language plpgsql as $$ begin if new.balance <> old.balance then insert into account_log (account_id, change, datetime) values (old.id, new.balance - old.balance, now ()); +end if; +return new; +end; +$$ +; +FEHLER: Funktion »log_change« existiert bereits mit den selben Argumenttypen +testdb=> drop function log_change; +FEHLER: kann Funktion log_change() nicht löschen, weil andere Objekte davon abhängen +DETAIL: Trigger after_update_account für Tabelle account hängt von Funktion log_change() ab +TIP: Verwenden Sie DROP ... CASCADE, um die abhängigen Objekte ebenfalls zu löschen. +testdb=> create or replace function log_change () returns trigger language plpgsql as $$ +begin if new.balance <> old.balance then + insert into account_log (account_id, change, datetime) values (old.id, new.balance - old.balance, now ()); +end if; +return new; +end; +$$ +; +CREATE FUNCTION +testdb=> diff --git a/20231207/trigger-04.txt b/20231207/trigger-04.txt new file mode 100644 index 0000000000000000000000000000000000000000..3f043fd90266375f886a79acdd5fcd8e114c7ad9 --- /dev/null +++ b/20231207/trigger-04.txt @@ -0,0 +1,22 @@ +testdb=> call transfer (2, 1, 10); CALL +testdb=> select * from customer; + id | lastname | firstname | account_id ----+------------+-----------+------------ + 2 | Mustermann | Erika | 1 + 4 | Rich | Richie | 2 +(2 Zeilen) + +testdb=> select * from account; + id | number | balance +----+-----------------------------+--------- + 1 | DE12 3456 7890 ABCD EFGH IJ | 1000009 + 2 | DE98 7654 3210 ABCD EFGH IJ | 3999990 +(2 Zeilen) + +testdb=> select * from account_log; + account_id | change | datetime +------------+--------+---------------------------- + 1 | 10 | 2023-12-07 12:07:38.614305 + 2 | -10 | 2023-12-07 12:07:38.614305 +(2 Zeilen) + +testdb=>