diff --git a/.lycheeignore b/.lycheeignore index 49be24e1..d0cc92f1 100644 --- a/.lycheeignore +++ b/.lycheeignore @@ -97,4 +97,8 @@ https://api.open-meteo.com/v1/forecast # 20260619 gjw konapod failures -https://blog.kumo.dev/2024/05/22/reverse_engineering_hkg_apps.html \ No newline at end of file +https://blog.kumo.dev/2024/05/22/reverse_engineering_hkg_apps.html + +# 20260816 tonypioneer solidpod failures +https://anushkavidanage.github.io/solidpod/example/redirect.html +https://anushkavidanage.github.io/solidpod/example/client-profile.jsonld diff --git a/analysis_options.yaml b/analysis_options.yaml index 42239ef8..6f3026d4 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -28,3 +28,10 @@ analyzer: exclude: - ignore/** - ignore/ + - build/** + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** diff --git a/example/analysis_options.yaml b/example/analysis_options.yaml index 0d290213..bf8d4218 100644 --- a/example/analysis_options.yaml +++ b/example/analysis_options.yaml @@ -7,6 +7,15 @@ # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. +analyzer: + exclude: + - build/** + - android/** + - ios/** + - web/** + - windows/** + - macos/** + - linux/** include: package:flutter_lints/flutter.yaml linter: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index aa98c932..d4635c1f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -14,8 +14,8 @@ dependencies: intl: ^0.20.2 markdown_tooltip: ^0.0.10 rdflib: ^0.2.12 - solidpod: ^1.0.10 - solidui: ^1.0.11 + solidpod: ^1.0.15 + solidui: ^1.0.32 universal_io: ^2.3.1 window_manager: ^0.5.1 diff --git a/lib/src/solid/constants/common.dart b/lib/src/solid/constants/common.dart index e0bd7ae0..604e910d 100644 --- a/lib/src/solid/constants/common.dart +++ b/lib/src/solid/constants/common.dart @@ -189,13 +189,16 @@ const String demoWebID = /// NOT migrated to a new device via encrypted backups / iCloud. Losing the /// DPoP key on device migration simply forces a re-login, which is expected /// since the OIDC client is registered dynamically per session anyway. -/// - Web: values ARE encrypted at rest — AES-GCM (256-bit) via the browser's -/// Web Crypto API, stored in localStorage. The caveat is the encryption key: -/// with the default options (no `wrapKey` in `WebOptions`, which we don't -/// set) the AES key is stored unwrapped in the same localStorage, so any -/// same-origin script (e.g. via XSS) can recover both key and ciphertext. -/// Web therefore provides encryption-at-rest but not the full trust-no-one -/// guarantee unless a `wrapKey` is supplied. +/// - Web: values are AES-GCM-encrypted (256-bit) via the browser's Web Crypto +/// API. The caveat is the encryption key: with the default options the AES +/// key is stored *unwrapped* in the same storage as the ciphertext, so any +/// same-origin script (e.g. via XSS) could recover both. To limit exposure +/// we set `useSessionStorage: true`, which places everything in +/// `sessionStorage` rather than `localStorage`. The store is then scoped to +/// the browsing session: it is per-tab, is not shared with other tabs, and +/// is cleared when the tab/window is closed — so the security key is not left +/// on disk across sessions. (Note `sessionStorage` does survive an in-tab +/// reload/refresh; only closing the tab clears it.) FlutterSecureStorage secureStorage = const FlutterSecureStorage( iOptions: IOSOptions( @@ -204,6 +207,10 @@ FlutterSecureStorage secureStorage = const FlutterSecureStorage( mOptions: MacOsOptions( accessibility: KeychainAccessibility.first_unlock_this_device, ), + // Web only: use sessionStorage instead of localStorage so cached secrets + // (security key, DPoP key, tokens) do not persist beyond the browsing + // session. Ignored on native platforms. + webOptions: WebOptions(useSessionStorage: true), ); /// Enum of resource status