- Navidrome-Salt wieder kryptographisch sicher (Random.secure, 16 Bytes) - Regression: v2.31-Redesign (36c744d) hatte den Security-Audit-Fix aus77a2042stillschweigend auf Timestamp zurueckgesetzt - Server-IDs (Navidrome s.id, Registry sid) vor Dateinamen defensiv sanitized (sanitizeDateiname) — kein Path-Traversal ueber Server-Werte - MANAGE_EXTERNAL_STORAGE entfernt: deklariert aber nie angefragt (toter Berechtigungs-Surface, Play-Store-Policy-Risiko) - Neuer Test: navidrome_salt_test.dart (Salt != Timestamp, 16 Bytes, eindeutig) Verifiziert: flutter analyze 0 Issues, flutter test 156/156
33 lines
1.2 KiB
Dart
33 lines
1.2 KiB
Dart
import 'dart:convert';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:melo_app/services/navidrome_service.dart';
|
|
|
|
void main() {
|
|
group('NavidromeService — Salt-Qualität (Security-Regression)', () {
|
|
test('Salt ist base64-codiert und KEIN vorhersagbarer Timestamp', () {
|
|
final nav = NavidromeService();
|
|
nav.setCredentials('https://musik.example.de', 'user', 'pass');
|
|
final salt = nav.saltFuerTests;
|
|
|
|
// Timestamp-Salt (alte, unsichere Variante) wäre rein numerisch
|
|
expect(RegExp(r'^\d+$').hasMatch(salt), isFalse,
|
|
reason: 'Salt darf kein reiner Timestamp sein');
|
|
|
|
// base64-Decodierung muss 16 Zufallsbytes ergeben (128 Bit Entropie)
|
|
final bytes = base64Decode(salt);
|
|
expect(bytes.length, 16);
|
|
});
|
|
|
|
test('Zwei setCredentials-Aufrufe erzeugen unterschiedliche Salts', () {
|
|
final nav = NavidromeService();
|
|
nav.setCredentials('https://musik.example.de', 'user', 'pass');
|
|
final salt1 = nav.saltFuerTests;
|
|
nav.setCredentials('https://musik.example.de', 'user', 'pass');
|
|
final salt2 = nav.saltFuerTests;
|
|
|
|
// Kollisionswahrscheinlichkeit bei Random.secure (16 Byte) ≈ 0
|
|
expect(salt1, isNot(equals(salt2)));
|
|
});
|
|
});
|
|
}
|