pedant
Goto Top

Biete einfache (webbasierte) Stempeluhr mit Exportfunktion

Hallo liebe Kollegen,

2016 stellte ein Forumskollege eine Suchanfrage:
Suche einfache (webbasierte) Stempeluhr mit Exportfunktion

Aus diesem Thread heraus ergab es sich, dass ich eine solches Zeiterfassungssystem schrieb und in dem Thread zur Verfügung stellte.
Es ist im Wesentlichen eine Sammlung von PHP-Scripten, die aber auf einer veralteten php-Version basiert.

Ich habe jetzt die alten Skripte umgeschrieben, sodass sie auch mit aktuellen Apache/MySQL/php-Kombinationen (Windows und Linux) kompatibel sind.
Die Datenbankanbindung erfolgt jetzt per PDO-Treiber.
Es kamen in dem Zuge auch ein paar kleine, neue Funktionen und Bugfixes hinzu.

Es gibt auch ein Demosystem, damit man sehen kann, um was es sich eigentlich handelt.
http://zeiterfassung.pedant.de

Die Zugangsdaten zum Demosystem, alle Informationen und ein Downloadlink sind auf meiner Webseite zu finden:
https://www.pedant.de/html/tools_zeiterfassung.php

Wer das alte System schon nutzt und umsteigen möchte, der kann seine alte Datenbank weiter nutzen.
Es muss nur eine neue, zusätzliche Tabelle eingefügt werden.
Dazu gibt es im neuen System, im Unterordner "sicherungen" eine SQL-Datei namens
"Tabelle_status_hinzufuegen.sql", die einfach importiert werden kann.

Ich freue mich auf Eure Kommentare.

Gruß Frank

Content-ID: 5898588752

Url: https://administrator.de/contentid/5898588752

Ausgedruckt am: 21.11.2024 um 16:11 Uhr

Epixc0re
Epixc0re 07.02.2023 um 19:03:04 Uhr
Goto Top
Servus,

da gibts einen Security Bug:

http://zeiterfassung.pedant.de/common/log.php?meldung=%3Cscript%3Ealert(document.cookie)%3C/script%3E
tk1234
tk1234 07.02.2023 um 20:15:21 Uhr
Goto Top
Zitat von @Epixc0re:
da gibts einen Security Bug:

Einen? Da werden jegliche Kontextwechsel ignoriert, ich würde dringend davon abraten das Script einzusetzen!
LordGurke
LordGurke 07.02.2023 um 20:31:32 Uhr
Goto Top
Wenn es der einzige wäre face-wink
Nach kurzem Überfliegen der Quelle sehe ich noch eine Menge potentieller SQLi-Lücken, da Variablen ungesehen in SQL-Queries übernommen werden. Anstatt es mit Prepared Statements der PDO zu machen.

Alles in allem ist das eine nette Idee, allerdings ist (leider) allzu offensichtlich, dass grundlegende Kenntnisse in PHP und objektorientierter Entwicklung fehlen face-sad
Nicht nur wegen der Sicherheitslücken sondern auch wie der Code insgesamt aussieht.
Wenn du zart besaitet bist, bitte hier aufhören zu lesen. Wenn du an aufrichtigter, wenn auch harter Kritik interessiert bist:

Mal als unvollständige Liste dessen, was mir sofort ins Auge springt:
  • Englisch + Deutsch wild gemischt
  • Die Einrückung im Code ist auch eher nach Zufall als nach einer festen Regel
  • Die wild versprengten Tabs in den echo-Blöcken (Tabs hätten dem Code an sich gut getan). Einrückung im ausgegebenen HTML-Code ist eigentlich nicht wichtig, wenn man mit den Browser-Tools debugged, macht aber den PHP-Code lesbarer. Das fällt extrem in html/login.php auf, wo mit über 50 aufeinanderfolgenden "echo()"-Zeilen und ohne Ende Tab-Zeichen irgendwelcher HTML- und Javascript-Code ausgegeben wird. Dafür hat uns PHP die HEREDOC-Marker gegeben. Oder Template-Systeme.
  • Dass dort ein Kennwort vorausgefüllt im Input-Feld mitgeliefert wird, ist ziemlich unschön.
  • Die Art und Weise, wie du Eingabevariablen in der common/get_post_session.php behandelst, lässt darauf schließen, dass du die Funktionsweise des dankenswerterweise schon lange verstorbenen "register_globals"-Verhaltens nachbilden willst. Es hat einen Grund, warum man keine Variablen von außen akzeptiert, die im Code eine Funktion abbilden können. Ich kann dir mit entsprechenden GET-Parametern einfach eine Session zusammenknuppern, wie ich sie benötige. Einfach
    ?_SESSION[angemeldet]=1
    an die URL anhängen müsste genügen, ist aber ungetestet.
  • Die Stempelzeiten in der Tabelle werden separat als Datum und Uhrzeit gespeichert, das macht eigentlich aus Programmsicht wenig Sinn - denn Nachtschichten mit Datumswechsel sind damit prinzipbedingt nicht möglich
  • Charset "latin1" zerfällt dir mit Nicht-Lateinischen Zeichen (kyrillisch, griechisch,...)
  • Kennwörter werden als SHA1-Hash gespeichert, das ist mittlerweile auch nicht mehr State Of The Art
  • Btw: SQL-Injection-Lücke beim Login: Gib mal als Benutzername
    x"; UPDATE users SET user_password="2e0a7cbdc90eb7a866e23e4125b37b6b293126a0"; --  
    ein, dann hat jeder User ab dem Moment das Kennwort "apfelsine"
  • Das inhärente Problem der SQL-Injections im Code würde theoretisch mit der PDO sehr gut abgefangen, wenn du denn Prepared Statements verwenden würdest. Allerdings sehe ich auch überall dass du explizit "$dbdatenbank.tabellenname" in den SQL-Queries benutzt, was auch unnötig ist, wenn man denn mit PDO einmal nach der Verbindung die Datenbank auswählt.


Das würde ich meinem aktuellen Azubi so nicht durchgehen lassen face-wink
Mystery-at-min
Mystery-at-min 07.02.2023 um 21:52:12 Uhr
Goto Top
habe bei PHP 7.1.x aufgehört zu überfliegen...die 7.4 ist depre...
maretz
maretz 08.02.2023 um 07:27:00 Uhr
Goto Top
Nun - man sollte eben mal schauen: Es wird was für umsonst angeboten - es steht ja jedem frei das zu nutzen oder nicht. Und da sind sicher einige "unschöne" Dinge drin - andersrum steht es ja jedem Frei den Code entsprechend (ggf. auch nur für sich selbst) zu verbessern... Man sollte lediglich da dazu erwähnen das man solchen Code natürlich _NICHT_ einfach so irgendwo auf nem öffentlichen Webserver ballern sollte u. hoffen das nix passiert. Für ne 3-Personen-Bude die jetzt eben grad von der Zeiterfassungspflicht überrollt wurde und wo es nur intern aufm Server läuft kanns aber ja interessant sein.

WAS man da aber natürlcih primär sehen muss wäre für mich nen ganz anderer Punkt der gegen sowas spricht: Wer ist für die WARTUNG der Software da, wer kann im Zweifel auch Support leisten? Ich stelle mir das schon eher schwer vor wenn man da jetzt fröhlich munter 1-2 Jahre Daten reinklöppelt und dann bei ner "Buchprüfung" plötzlich rauskommt das leider irgendwo nen Fehler war u. die Daten im Nirvana sind... und den Prüfer wird da dann schon interessieren was da los ist u. ich denke "ich habe mal nen Freeware-Script genommen, auf meinen Server gehauen und naja,... doof gelaufen halt" ist da keine valide Antwort :D
evgnbz
evgnbz 08.02.2023 um 10:55:23 Uhr
Goto Top
kann mir jemand sagen wo ich etwas über sowas wie sql injection lesen kann wie man das macht und wie man sich davon schützt
Lochkartenstanzer
Lochkartenstanzer 08.02.2023 aktualisiert um 11:17:48 Uhr
Goto Top
Zitat von @evgnbz:

kann mir jemand sagen wo ich etwas über sowas wie sql injection lesen kann wie man das macht und wie man sich davon schützt

SQL injection how to

Und dann an den Informationen entlanghangeln.

lks
evgnbz
evgnbz 08.02.2023 um 12:29:45 Uhr
Goto Top
Zitat von @maretz:
nen Fehler war u. die Daten im Nirvana sind... und den Prüfer wird da dann schon interessieren was da los ist u. ich denke "ich habe mal nen Freeware-Script genommen, auf meinen Server gehauen und naja,... doof gelaufen halt" ist da keine valide Antwort :D


deswegen gibt es backups
Mystery-at-min
Mystery-at-min 08.02.2023 um 12:37:13 Uhr
Goto Top
hilft nicht, wenn die Daten korrupt sind.
evgnbz
evgnbz 08.02.2023 um 13:10:22 Uhr
Goto Top
Zitat von @Mystery-at-min:

hilft nicht, wenn die Daten korrupt sind.

100%
Pedant
Pedant 08.02.2023 um 20:48:22 Uhr
Goto Top
Hallo,

zuerst mal meinen Dank für Eure Kommentare und Meinungen und für Eure Zeit.

Zitat von @maretz:

Man sollte lediglich da dazu erwähnen das man solchen Code natürlich _NICHT_ einfach so irgendwo auf nem öffentlichen Webserver ballern sollte
Warum der Konjunktiv?
Genau diese Erwähnung ist vorhanden...
Zitat von www.pedant.de

Es wird noch einige Schlupflöcher geben, die Manipulation oder Sabotage zulassen.
Gedacht ist es als Zeiterfassung für einen kleineren Betrieb, in dem Vertrauenswürdigkeit vorausgesetzt werden darf.

Der Webserver sollte vorzugsweise ein eigener Webserver im lokalen Netzwerk sein.
Wer einen öffentlich zugänglichen Webserver verwenden möchte, sollte sich Klarheit über vorhandene Sicherheitsrisiken verschaffen.

Zitat von @maretz:

...und dann bei ner "Buchprüfung" plötzlich rauskommt das leider irgendwo nen Fehler war u. die Daten im Nirvana sind...
Es ist ein Zeiterfassungssystem und da liegt der Schwerpunkt auf der Datenerfassung und nicht der Datenverarbeitung.
Die Überprüfung ob die Mitarbeiter ihre Sollstunden erreicht oder wieviel Überstunden sie angesammelt und rechtzeitig abgefeiert haben, erfolgt nicht in der Zeiterfassung.
Gedacht ist es so:
Man exportiert die Daten regelmäßig (monatlich) und die Auswertung und weitere Verarbeitung erfolgt beispielsweise in Excel.
Wenn irgendwann eine externe Prüfung kommen sollte, liegen die Daten nicht im Nirvana, man hat mindestens die exportierten csv-Dateien (=Excel-Tabellen) vorliegen.

Zitat von @Mystery-at-min:

habe bei PHP 7.1.x aufgehört zu überfliegen...die 7.4 ist depre...
Es läuft auch mit php 8


Mal ganz allgemein zu den geäußerten Sicherheitsbedenken:

Diese Zeiterfassung ist nicht für Betriebe gedacht, in denen die Mitarbeiter als Sicherheitsrisiko angesehen werden.
Wer die Sorge hat, dass seine Kollegen den Zeiterfassungsserver hacken, der sollte ein anderes System verwenden.
Abgesehen davon riskiert jemand, der die Server im eigenen Betrieb hackt, eine fristlose Kündigung und weitere zivil- oder gar strafrechtliche Konsequenzen.
Wer kein Vertauen in die Belegschaft hat, kann eigentlich keinem Zeiterfassungssystem vertrauen, denn die Daten können auch ohne IT-Hack, bei ihrer Erhebung korrumpiert werden.


Etwas konkreter zu den Sicherheitsbedenken:

Die von Euch erwähnten Lücken und Stichworte schau ich mir gerne an und versuche sie nachzuvollziehen:
- SQL-Injection
- Prepared Statements
- Kontextwechsel


Die Punkte in Einzelnen:

Zitat von @Epixc0re

http://zeiterfassung.pedant.de/common/log.php?meldung=%3Cscript%3Ealert(document.cookie)%3C/script%3E
Die resultierende Ausgabe ist:
PHPSESSID=n3ue3rlongd1cdhqqrui20lm2v
Geht es tatsächlich um diese PHPSESSID oder darum, dass man der log.php Javascript unterjubeln könnte, das dann aber doch nur im aufrufenden Browser ausgeführt wird?
Ich schreib mir mal auf die ToDo-Liste $meldung etwas zu filtern/bereinigen bevor es zum echo kommt.

Zitat von @tk1234

Da werden jegliche Kontextwechsel ignoriert ...
Hast Du ein konkretes Beispiel, das zeigt was Du damit meinst?
Deinen Link habe ich verfolgt aber noch nicht durchgelesen.

Zitat von @LordGurke

Englisch + Deutsch wild gemischt
Ich habe Kollegen, die nicht nur so schreiben, sondern auch so sprechen.
Vielleicht schau ich mal, dass ich meine Variablen durchgehend in Deutsch benenne.
Ich vermute, dass das aber auch für Dich nicht das dringenste Problem ist.

Zitat von @LordGurke

Die Einrückung im Code ist auch eher nach Zufall als nach einer festen Regel
Das ist eine Kritik, die ich wirklich von mir weise.
Ich habe da ganz feste Regeln und ich wage zu behaupten, dass ich weder im php, noch im davon generiertem html nicht an einer Stelle davon abweiche.

Zitat von @LordGurke

... in html/login.php auf, wo mit über 50 aufeinanderfolgenden "echo()"-Zeilen und ohne Ende Tab-Zeichen irgendwelcher HTML- und Javascript-Code ausgegeben wird.
Dafür hat uns PHP die HEREDOC-Marker gegeben.
Der Teil ist im php wirklich nicht so gut lesbar.
Im erzeugten html aber schon.
Ich denke mal darüber nach, ob ich mich mit HEREDOC-Marker anfreunden kann.

Zitat von @LordGurke

Dass dort ein Kennwort vorausgefüllt im Input-Feld mitgeliefert wird, ist ziemlich unschön.
Ich vermute Du meinst login.php, Zeile 146
echo "\t\t\t\t\t<td class=blank><input name=\"passwort\" type=\"password\" value=\"".$passwort."\" ...
Bei Aufruf der Loginseite sind das Benutzername- und Passwort-Feld zunächst leer.
Vorausgefüllt werden sie nur, wenn dort zum Login eine ungültige Kombinationen eingegeben wurde.
Vorausgefüllt werden sie dann mit den Werten, die der User soeben selbst eingegeben hatte.
Da sehe ich weiter kein Problem.
Wer sich also nur bei Benutzername oder Passwort vertippt hatte, muss nur eins korrigieren statt beides neu einzutippen.

Zitat von @LordGurke

Die Art und Weise, wie du Eingabevariablen in der common/get_post_session.php behandelst, lässt darauf schließen, dass du die Funktionsweise des dankenswerterweise schon lange verstorbenen "register_globals"-Verhaltens nachbilden willst.
Es hat einen Grund, warum man keine Variablen von außen akzeptiert, die im Code eine Funktion abbilden können.
Ich kann dir mit entsprechenden GET-Parametern einfach eine Session zusammenknuppern, wie ich sie benötige.
Was ist die Alternative zu den lange verstorbenen "register_globals"?

Zitat von @LordGurke

Die Stempelzeiten in der Tabelle werden separat als Datum und Uhrzeit gespeichert, das macht eigentlich aus Programmsicht wenig Sinn - denn Nachtschichten mit Datumswechsel sind damit prinzipbedingt nicht möglich
Wenn jemand nach Mitternacht ausstempelt, wird vom System ein zweiter Datensatz angelegt.
Der angefangene Datensatz wird mit 24:00 Uhr beendet und es wird ein zweiter erzeugt der von 0:00 Uhr bis Feierabend geht.
Ich fand das sinnvoll, da dann jeder Zeiteneintrag immer eindeutig und vollständig einem Tag oder auch Woche, Monat, Jahr zugeordnet ist.

Zitat von @LordGurke

Charset "latin1" zerfällt dir mit Nicht-Lateinischen Zeichen (kyrillisch, griechisch,...)
Auf meinen Rechner und im Demosystem zerfällt es nicht, daher war mir das nicht aufgefallen, aber die Datenbank sollte ich auch auf utf8 umstellen.

Zitat von @LordGurke

Kennwörter werden als SHA1-Hash gespeichert, das ist mittlerweile auch nicht mehr State Of The Art
Soll es lieber SHA256 sein oder etwas anderes?

Zitat von @LordGurke

Btw: SQL-Injection-Lücke beim Login: Gib mal als Benutzername
x"; UPDATE users SET user_password="2e0a7cbdc90eb7a866e23e4125b37b6b293126a0"; --
ein, dann hat jeder User ab dem Moment das Kennwort "apfelsine"
Wenn ich das beim Login eingebe kommt ein Alert:
"Der Benutername oder das Passwort ist falsch."
Dieser konkrete Hack funktioniert so nicht.
Damit will ich aber nicht behaupten, dass das System nicht anfällig für SQL-Injection wäre.

Zitat von @LordGurke

Das inhärente Problem der SQL-Injections im Code würde theoretisch mit der PDO sehr gut abgefangen, wenn du denn Prepared Statements verwenden würdest.
Das Thema "Prepared Statements" schau ich mir an.

Zitat von @LordGurke

Allerdings sehe ich auch überall dass du explizit "$dbdatenbank.tabellenname" in den SQL-Queries benutzt, was auch unnötig ist, wenn man denn mit PDO einmal nach der Verbindung die Datenbank auswählt.
Das hat mir auch nicht gefallen und fand es eigentlich unnötig.
Ich hab nur kein Beispiel gefunden wie ich die Angabe der Datenbank mit unterbringe in $link = new PDO(...
Wenn ich Dich richtig verstehe, schlägst Du vor am Ende meiner connect.php ein USE database; als Abfrage auszuführen.

Zitat von @LordGurke

Wenn du zart besaitet bist, bitte hier aufhören zu lesen.
Alles gut. Danke für die bisherigen Kommentare.

Gruß Frank
tk1234
tk1234 08.02.2023 um 21:33:02 Uhr
Goto Top
Zitat von @Pedant:
Geht es tatsächlich um diese PHPSESSID oder darum, dass man der log.php Javascript unterjubeln könnte, das dann aber doch nur im aufrufenden Browser ausgeführt wird?

Oder. Es lässt sich aber auch ein script-Element einbauen welches ein externes Script nachlädt - und damit lässt sich dann allerhand Unfug anstellen wie das Ausführen von irgendwelchen Schädlingen oder dem Verschicken von Daten.

Ich schreib mir mal auf die ToDo-Liste $meldung etwas zu filtern/bereinigen bevor es zum echo kommt.

Du musst einfach nur die Kontextwechsel richtig behandeln, dann kann dem Benutzer auch kein Javascript-Code untergejubelt werden.

Zitat von @tk1234

Da werden jegliche Kontextwechsel ignoriert ...
Hast Du ein konkretes Beispiel, das zeigt was Du damit meinst?
Deinen Link habe ich verfolgt aber noch nicht durchgelesen.

Dann mach das mal, dort ist das Problem beschrieben, auch mit Beispielen. Das Prinzip ist aber eigentlich ganz einfach: wenn man bei dir z.B. beim Login ein Anführungszeichen im Namen verwendet wird das 1:1 im Query eingebaut und die Datenbank haut dir eine Fehlermeldung um die Ohren (bzw. die genaue Fehlermeldung sollte ein Benutzer garnicht zu sehen bekommen!). Wenn der Kontextwechsel nach SQL richtig behandelt worden wäre, wäre das Anführungszeichen maskiert worden und der Query würde keinen Fehler mehr werfen.

Dass dort ein Kennwort vorausgefüllt im Input-Feld mitgeliefert wird, ist ziemlich unschön.
Ich vermute Du meinst login.php, Zeile 146
echo "\t\t\t\t\t<td class=blank><input name=\"passwort\" type=\"password\" value=\"".$passwort."\" ...
Bei Aufruf der Loginseite sind das Benutzername- und Passwort-Feld zunächst leer.
Vorausgefüllt werden sie nur, wenn dort zum Login eine ungültige Kombinationen eingegeben wurde.
Vorausgefüllt werden sie dann mit den Werten, die der User soeben selbst eingegeben hatte.
Da sehe ich weiter kein Problem.
Wer sich also nur bei Benutzername oder Passwort vertippt hatte, muss nur eins korrigieren statt beides neu einzutippen.

Ein Passwort sollte niemals irgendwo im Klartext ausgegeben werden (auch nicht im Quelltext als Wert des value-Attributs) - welches Zeichen falsch war sieht der Benutzer ohnehin nicht und das Passwort ganz neu einzugeben geht dann ohnehin schneller.
Was an der Stelle auch noch auffällt: du verwendest Layouttabellen - die sind seit vielen Jahren nicht mehr notwendig. Tabellen sind nur für tabellarische Daten gedacht was das Login-Formular nicht ist (das könnte man als Definitionsliste (dl usw.) auszeichnen, zum Formatieren gibt es grid- und flex-Layouts).

Was ist die Alternative zu den lange verstorbenen "register_globals"?

Direkt mit $_GET/$_POST arbeiten. So ist der Code unles- bzw. unwartbar da ständig irgendwelche Variablen auftauchen bei denen nicht klar ist woher die eigentlich kommen. Wenn Variablen nicht anständig initialisiert werden wird das ganze (wie schon geschrieben wurde) auch noch potentiell gefährlich.

Zitat von @LordGurke

Charset "latin1" zerfällt dir mit Nicht-Lateinischen Zeichen (kyrillisch, griechisch,...)
Auf meinen Rechner und im Demosystem zerfällt es nicht, daher war mir das nicht aufgefallen, aber die Datenbank sollte ich auch auf utf8 umstellen.

Verwende als Charset utf8mb4, nicht utf8 (das ist ein Alias für utf8mb3 und veraltet). Denk daran dass du nicht nur die Datenbank (Datenbank selbst, Tabellen und Spalten!) umstellen musst sondern auch die Verbindung zur Datenbank und auch alle PHP-Dateien!

Zitat von @LordGurke

Kennwörter werden als SHA1-Hash gespeichert, das ist mittlerweile auch nicht mehr State Of The Art
Soll es lieber SHA256 sein oder etwas anderes?

Verwende zum Speichern bzw. Überprüfen von Passwörtern password_hash() bzw. passwort_verify().


Wenn ich Dich richtig verstehe, schlägst Du vor am Ende meiner connect.php ein USE database; als Abfrage auszuführen.

Nein. Im DSN (erster Parameter bei new PDO(…)) einfach den Datenbanknamen angeben, siehe Handbuch.
Pedant
Pedant 09.02.2023 um 17:15:59 Uhr
Goto Top
Hallo tk1234,

danke für Deine detaillierte Antwort.

Gruß Frank
Wolfsblut76
Wolfsblut76 12.02.2023 um 18:25:50 Uhr
Goto Top
Hallo Frank,

vielen vielen Dank dafür. Auch wenn wir eine 3 Mann Bude sind hilft es uns schon weiter.

Gibt es die Möglichkeit noch auf https umzustellen?

Danke und Gruß aus Gera
Pedant
Pedant 13.02.2023 um 08:50:33 Uhr
Goto Top
Hallo Wolfsblut76,

meinen Skripten ist es egal ob http oder https genutzt wird.
Wenn Du https statt http nutzen möchtest, dann musst Du das an Deinem Webserver umstellen (aufrüsten).
Welchen Webserver nutzt Du?
Software und Version, Betriebssystem?

Ankündigung:
Ich werde (wahrscheinlich heute) eine neue Version meiner Skripte hochladen, bei der einiges vom Feedback aus diesem Thread umgesetzt ist.

Gruß Frank
Pedant
Pedant 13.02.2023 um 20:15:37 Uhr
Goto Top
Hallo,

wie heutemorgen erwähnt, habe ich jetzt eine neue Version (2.0.1) hochgeladen.

Hier eine Liste der Änderungen in Bezug auf Eure Kommentare:

http://zeiterfassung.pedant.de/common/log.php?meldung=%3Cscript%3Ealert(document.cookie)%3C/script%3E
Der Inhalt von "meldung" wird jetzt in log.php zur Ausgabe im HTML gefiltert und umformatiert um Code-Injection zu vermeiden.

Englisch + Deutsch wild gemischt
weitgehend unverändert

aufeinanderfolgenden "echo()"-Zeilen und ohne Ende Tab-Zeichen irgendwelcher HTML- und Javascript-Code ausgegeben wird.
Bei größeren HTML-Blöcken, die ohne Fallunterscheidung auszugeben sind, habe ich das HTML jetzt direkt ins Dokument geschrieben, statt es per echo auszugeben.

Kennwort vorausgefüllt im Input-Feld
Ausgefüllt wird nur noch Benutzername und nicht mehr Passwort

Eingabevariablen in der common/get_post_session.php
Vorerst unverändert

Charset "latin1"
Die Datenbank-Tabellen sind jetzt utf8mb4

Das inhärente Problem der SQL-Injections im Code würde theoretisch mit der PDO sehr gut abgefangen, wenn du denn Prepared Statements verwenden würdest.
Alle SQL-Abfragen, die Variablen enthalten werden jetzt als Prepared Statement angewendet.
Manuelle SQL-Befehle werden vorerst weiter akzeptiert, wenn sie per Post an sqlausfuehren.php übergeben werden.

Kennwörter werden als SHA1-Hash gespeichert
Für die Kennwörter wird jetzt password_hash() bzw. passwort_verify() verwendet.

explizit "$dbdatenbank.tabellenname" in den SQL-Queries benutzt
Der Datenbankname ist jetzt bei new PDO(…) angeben und nicht mehr in den Queries.

Ich bin mir sicher, dass meine ganzen Änderungen an ein paar Stellen Bugs verursacht haben, die die eigentliche Funktionalität stören werden.
Weitere Änderungen und Funktionstests stehen noch aus.

Gruß Frank
Pedant
Pedant 14.02.2023 um 11:14:19 Uhr
Goto Top
Hallo,

ein Bugfix => Version 2.0.2
https://www.pedant.de/html/tools_zeiterfassung.php

Gruß Frank
Wolfsblut76
Wolfsblut76 14.02.2023 um 12:09:00 Uhr
Goto Top
Hallo Frank,

Nochmals vielen vielen Dank das du dich so ins Zeug legst. Sowas ist nicht selbstverständlich.

Gruß aus Gera
andreas.wb
andreas.wb 28.02.2023 um 15:39:56 Uhr
Goto Top
Hi,
ich bekomme immer diesen Fehler beim klick auf "Zeiten ansehen"
Meldung: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
SQLState: HY093
Error-Code: 0
Datei: /mnt/web413/a3/38/5201438/htdocs/zeiterfassung/common/connect.php
Zeile: 8

Der Fehler wird auch hier in der Demo angezeigt.
Wolfsblut76
Wolfsblut76 28.02.2023 um 22:47:09 Uhr
Goto Top
Bei mir ist der Fehler nicht replizierbar.
Was mir aufgefallen ist, wenn der Mitarbeiter sein Passwort ändert, dass der Name und das Bild gelöscht wird.
andreas.wb
andreas.wb 01.03.2023 um 09:08:29 Uhr
Goto Top
Zitat von @Wolfsblut76:

Bei mir ist der Fehler nicht replizierbar.
Was mir aufgefallen ist, wenn der Mitarbeiter sein Passwort ändert, dass der Name und das Bild gelöscht wird.

Wie gesagt, das wird unabhängig vom Browser selbst bei der Demo so ausgespielt: http://zeiterfassung.pedant.de/index.php
Also muss es ja was Grundsätzliches sein.
evgnbz
evgnbz 01.03.2023 um 13:15:39 Uhr
Goto Top
könnte mal jemand den quelcode von connect.php hochladen zwecks bugfixing , vtl kann ich bisl helfen
Wolfsblut76
Wolfsblut76 04.04.2023 um 15:16:31 Uhr
Goto Top
Schade, die ganze Zeit lief es durch und nach ein Update auf phpMyAdmin 5.2.1.0 kommt nun der gleiche Fehler.

Meldung: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
SQLState: HY093
Error-Code: 0
Datei: /share/CACHEDEV1_DATA/Web/zeiterfassung/common/connect.php
Zeile: 81


<?php

include_once('fehlerbehandlung.php');  


/* Verbindung zur Datenbank */

$dbbenutzer  = "XXXXXXXXX"; // Hier sollte ein minderpreviligierter MySQL-User angegeben werden, der nur auf die Datenbank "zeiterfassung" Zugriffrechte hat.  
$dbkennwort  = "XXXXXXXX";  
$dbserver    = "localhost";  
$dbport      = "3306";  
$dbdatenbank = "zeiterfassung";  

$serverundportunddatenbank = "mysql:host=".$dbserver."; port=".$dbport."; dbname=".$dbdatenbank;  
$pdo = new PDO($serverundportunddatenbank, $dbbenutzer, $dbkennwort);
$pdo -> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


/* Aufrufbare Funktion für Datenbankabfragen */
/*
Anwendungsbeispiel:

$abfrage = "SELECT * FROM users WHERE user_id = :user_id AND user_alias = :user_alias";  
$parameter = array(':user_id' => $user_id, ':user_alias' => $user_alias); 

$pdostatement = abfragen($pdo, $abfrage, $parameter);

$anzahl = $pdostatement -> rowCount();
$ergebnis = $pdostatement -> fetchAll(PDO::FETCH_ASSOC);

abfragen($pdo, "standsetzen", ""); 

*/


function abfragen($pdo, $abfrage, $parameter)
	{
	//echo "abfrage: ".$abfrage."<br>\n"; 
	if ($abfrage == "") {return ("");};  

	//if ($parameter == "" || $parameter == "manuellessql") {echo "parameter = \"".$parameter."\"<br>\n";} else {foreach ($parameter as $var => $wert) {echo $var." = ".$wert."<br>\n";};}; 

	if ($abfrage == "standsetzen")  
		{
		$abfrage = "UPDATE status SET stand = NOW() WHERE status_id = :status_id;";  
		$parameter = array(':status_id' => 1);  
		};

	// Abfragen, die keine Variablen enthalten werden nicht mit "prepare" durchgeführt sondern mit "query" oder "exec" oder gar nicht. 
	if ($parameter == "" || $parameter == "manuellessql")  
		{
		// Das erste Wort der Abfrage ($abfrage) ermitteln und auswerten
		$anweisungsart = explode (" ", $abfrage);  
		$anweisungsart = strtolower($anweisungsart[0]);
		//echo "anweisungsart: ".$anweisungsart."<br>\n"; 
		switch ($anweisungsart)
			{
			case "select":  
			case "show":  
				$methode = "query";  
				break;
			case "insert":  
			case "update":  
			case "replace":  
			case "delete":  
				$methode = "exec";  
		        	break;
			default:
				if ($parameter == "manuellessql") {$methode = "query";}  
				else {$methode = "keine";};  
			};

		}
	else {$methode = "prepare";};  

	//echo "methode: ".$methode."<br>\n"; 

 	if ($methode == "prepare")  
 		{
 		$pdostatement = $pdo -> prepare($abfrage);
 		$pdostatement -> execute($parameter);
 		return ($pdostatement);
 		};

	if ($methode == "query")  
		{
		$pdostatement = $pdo -> query($abfrage);
		return ($pdostatement);
		};

	if ($methode == "exec")  
		{
		$anzahl = $pdo -> exec($abfrage);
		return ($anzahl);
		};

	if ($methode == "keine")  
		{
		// keine Abfrage
		return ("");  
		};

	return ("");  
	}

function testfehler($pdo)
	{
	$jetzt = date("H:m:s");  
	$abfrage = "SELECT ".$jetzt; // ungültige Abfrage  
	abfragen($pdo, $abfrage, "");  
	return ("");  
	}

?>
Pedant
Pedant 14.05.2023 um 10:45:24 Uhr
Goto Top
Hallo,

Zitat von @andreas.wb:

Hi,
ich bekomme immer diesen Fehler beim klick auf "Zeiten ansehen"
...
Der Fehler wird auch hier in der Demo angezeigt.

verzeiht bitte, dass ich mich so lange nicht gemeldet hatte.
Ein Bugfix => Version 2.0.3
https://www.pedant.de/html/tools_zeiterfassung.php

Gegenüber der Version 2.0.2 hat sich kaum etwas geändert.
In der zeitenauswahl.php
gibt es eine neue, zusätzliche Zeile Nummer 100:
$parameter = "";
In der Datei config.php ist die Versionsnummer aktualisiert:
$softwareversion = "Pedants Zeiterfassung Ver. 2.0.3";

Zitat von @Wolfsblut76:

Was mir aufgefallen ist, wenn der Mitarbeiter sein Passwort ändert, dass der Name und das Bild gelöscht wird.
Den Fehler kann ich nicht nachvollziehen.
Soweit ich das sehe tritt er in der Demo auch nicht auf.
Welche PHP und MySQL Version nutzt Du?

Gruß Frank
KlaDiWi
KlaDiWi 16.05.2023 aktualisiert um 22:41:16 Uhr
Goto Top
Hallo Frank,
ich kann das Problem mit dem Bild nachvollziehen,
Ich habe als Benutzer nur das Kennwort geändert und bekomme folgende Hinweise in Grün:

"Der Vorname wurde geändert.
Der Nachname wurde geändert.
Das Passwort wurde geändert.
Die E-Mail-Adresse wurde geändert.
Ein anderes Bild wurde zugeordnet,"


Mein Setup:

Apple Rechner mit
MAMP 6.8
PHP 7.4.33
MySql 5.7.39

Zusätzliches Problem:

1. Wenn ich auf "Zeiten ansehen" klicke, kommt folgende Meldung:

"SQLState: 42000
Error-Code: 1055

Meldung: Expression"


2. Auf Deiner Website als admin angemeldet und auf "Zeiten verwalten" geklickt, bekomme ich nur den Text und die Buttons angezeigt.
Unterhalb der Eintragsfilter kommt nichts und nur der Button "Alle Angezeigten löschen" bewirkt ein Hinweis PopUp, sonst aber nichts,

Die andere Meldung vom VorPoster ist jedenfalls weg,
Vielen Dank für Deine Arbeit und die zur Verfügungstellung
Grüße vom Klaus