Bremse gegen Passwortraten
Nach fuenf Fehlversuchen wird eine E-Mail-Adresse gesperrt, erst eine Minute, dann doppelt so lang, hoechstens 15 Minuten. Gezaehlt wird je Adresse, auch fuer unbekannte - sonst verriete die Sperre, welche Konten es gibt. Waehrend der Sperre kommt auch das richtige Passwort nicht durch. Jeder Versuch zaehlt sofort und wird bei Erfolg zurueckgenommen. Zwischen Sperrpruefung und Zaehlen liegt damit kein await; gleichzeitige Anfragen kommen so nicht alle an der Sperre vorbei. Der Zaehler liegt im Speicher des einen Prozesses. Ein Neustart setzt ihn zurueck - der Notausgang, falls sich das einzige Ausbilderkonto aussperrt. Beim Aufraeumen wird eine laufende Sperre nie verdraengt. Die Containerabnahme prueft die Sperre im laufenden Abbild. Das Abnahmeprotokoll ist gegen diesen Stand neu erzeugt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5fbf1ac4de
commit
31d7779f45
@@ -10,7 +10,8 @@ import { spawnSync } from 'node:child_process';
|
||||
* es nie, und ein frisch aufgesetzter Server stand ohne jedes Konto da.
|
||||
*
|
||||
* Dieser Lauf baut das Abbild, startet es mit leerem Volume und geht den Weg
|
||||
* aus der README: Lebenszeichen, erstes Konto, Anmeldung, Sicherung.
|
||||
* aus der README: Lebenszeichen, erstes Konto, Anmeldung, Sperre bei
|
||||
* Fehlversuchen, Sicherung.
|
||||
*
|
||||
* node scripts/pruefungen/container.mjs
|
||||
*
|
||||
@@ -90,6 +91,23 @@ async function anmelden(email, passwort) {
|
||||
return angekommen;
|
||||
}
|
||||
|
||||
/** Ein Anmeldeversuch, der die angezeigte Meldung zurückgibt. */
|
||||
async function meldungNachAnmeldung(email, passwort) {
|
||||
const kontext = await browser.newContext({ locale: 'de-DE' });
|
||||
const seite = await kontext.newPage();
|
||||
seite.setDefaultTimeout(30000);
|
||||
await seite.goto(`${BASIS}/anmelden`);
|
||||
await seite.fill('#email', email);
|
||||
await seite.fill('#passwort', passwort);
|
||||
await seite.click('button[type=submit]');
|
||||
const text = await seite
|
||||
.locator('.hinweis-fehler')
|
||||
.innerText({ timeout: 15000 })
|
||||
.catch(() => '');
|
||||
await kontext.close();
|
||||
return text;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (docker(['info'], { stdio: 'ignore' }).status !== 0) {
|
||||
console.error('Docker ist nicht erreichbar.');
|
||||
@@ -141,9 +159,25 @@ async function main() {
|
||||
pruefe(neuesPw && (await anmelden(AUSBILDER.email, neuesPw)), 'Mit dem neuen Passwort geht die Anmeldung');
|
||||
pruefe(!(await anmelden(AUSBILDER.email, AUSBILDER.pw)), 'Das alte Passwort gilt nicht mehr');
|
||||
|
||||
// --- C3 Sicherung im Container -------------------------------------------
|
||||
// --- C3 Bremse gegen Passwortraten ----------------------------------------
|
||||
|
||||
abschnitt('C3 · Sicherung im Container');
|
||||
abschnitt('C3 · Bremse gegen Passwortraten');
|
||||
|
||||
// Eine Adresse, die es nicht gibt: Die Sperre muss genauso greifen, sonst
|
||||
// verriete sie, welche Konten existieren.
|
||||
const unbekannt = 'niemand@betrieb.test';
|
||||
for (let i = 0; i < 5; i += 1) await meldungNachAnmeldung(unbekannt, `geraten-${i}`);
|
||||
const gesperrt = await meldungNachAnmeldung(unbekannt, 'geraten-6');
|
||||
pruefe(gesperrt.includes('Zu viele Fehlversuche'), 'Nach fünf Fehlversuchen wird gesperrt – auch für eine unbekannte Adresse', gesperrt);
|
||||
|
||||
pruefe(neuesPw && (await anmelden(AUSBILDER.email, neuesPw)), 'Ein anderes Konto ist davon nicht betroffen');
|
||||
|
||||
for (let i = 0; i < 5; i += 1) await meldungNachAnmeldung(AUSBILDER.email, `geraten-${i}`);
|
||||
pruefe(!(await anmelden(AUSBILDER.email, neuesPw)), 'Während der Sperre kommt auch das richtige Passwort nicht durch');
|
||||
|
||||
// --- C4 Sicherung im Container -------------------------------------------
|
||||
|
||||
abschnitt('C4 · Sicherung im Container');
|
||||
|
||||
const sicherung = imContainer('/app/werkzeuge/sicherung.sh', '/daten/sicherungen');
|
||||
pruefe(sicherung.ende === 0, 'Die Sicherung läuft im Container durch', sicherung.ausgabe.trim().split('\n').at(-1));
|
||||
|
||||
Reference in New Issue
Block a user