收紧移动壳WebView安全开关

移动壳 WebView 显式禁用多窗口、文件访问、混合内容、第三方 Cookie 和远程调试

移动壳检查脚本拒绝 WebView 安全开关被放宽

移动壳导航测试补充协议降级、协议相对外域和危险协议拦截

宿主壳方案和共享决策记录移动 WebView 安全边界
This commit is contained in:
2026-06-18 09:19:05 +08:00
parent 28e5295911
commit 7fabb5ed4c
5 changed files with 32 additions and 0 deletions

View File

@@ -176,8 +176,16 @@ export default function App() {
ref={webViewRef} ref={webViewRef}
source={{ uri: webUrl }} source={{ uri: webUrl }}
javaScriptEnabled javaScriptEnabled
javaScriptCanOpenWindowsAutomatically={false}
domStorageEnabled domStorageEnabled
mixedContentMode="never"
originWhitelist={[allowedWebOrigin]} originWhitelist={[allowedWebOrigin]}
allowFileAccess={false}
allowFileAccessFromFileURLs={false}
allowUniversalAccessFromFileURLs={false}
thirdPartyCookiesEnabled={false}
sharedCookiesEnabled={false}
webviewDebuggingEnabled={false}
onMessage={handleMessage} onMessage={handleMessage}
onShouldStartLoadWithRequest={handleShouldStartLoad} onShouldStartLoadWithRequest={handleShouldStartLoad}
onNavigationStateChange={(event) => { onNavigationStateChange={(event) => {

View File

@@ -295,6 +295,15 @@ for (const snippet of [
'SafeAreaView', 'SafeAreaView',
'MOBILE_SHELL_SAFE_AREA_EDGES', 'MOBILE_SHELL_SAFE_AREA_EDGES',
'resolveMobileShellBaseWebUrl', 'resolveMobileShellBaseWebUrl',
'javaScriptCanOpenWindowsAutomatically={false}',
'mixedContentMode="never"',
'allowFileAccess={false}',
'allowFileAccessFromFileURLs={false}',
'allowUniversalAccessFromFileURLs={false}',
'thirdPartyCookiesEnabled={false}',
'sharedCookiesEnabled={false}',
'webviewDebuggingEnabled={false}',
'setSupportMultipleWindows={false}',
]) { ]) {
if (!appSource.includes(snippet)) { if (!appSource.includes(snippet)) {
throw new Error(`mobile shell App missing ${snippet}`); throw new Error(`mobile shell App missing ${snippet}`);

View File

@@ -19,6 +19,12 @@ describe('shouldOpenInMobileShellWebView', () => {
expect( expect(
shouldOpenInMobileShellWebView('/creation/puzzle', allowedOrigin), shouldOpenInMobileShellWebView('/creation/puzzle', allowedOrigin),
).toBe(true); ).toBe(true);
expect(
shouldOpenInMobileShellWebView(
'http://app.genarrative.world/works/detail?work=PZ-1',
allowedOrigin,
),
).toBe(false);
expect( expect(
shouldOpenInMobileShellWebView('about:blank', allowedOrigin), shouldOpenInMobileShellWebView('about:blank', allowedOrigin),
).toBe(true); ).toBe(true);
@@ -33,6 +39,12 @@ describe('shouldOpenInMobileShellWebView', () => {
expect( expect(
shouldOpenInMobileShellWebView('mailto:hi@example.com', allowedOrigin), shouldOpenInMobileShellWebView('mailto:hi@example.com', allowedOrigin),
).toBe(false); ).toBe(false);
expect(
shouldOpenInMobileShellWebView('//example.com/evil', allowedOrigin),
).toBe(false);
expect(
shouldOpenInMobileShellWebView('javascript:alert(1)', allowedOrigin),
).toBe(false);
expect(shouldOpenInMobileShellWebView('not a url', allowedOrigin)).toBe( expect(shouldOpenInMobileShellWebView('not a url', allowedOrigin)).toBe(
false, false,
); );

View File

@@ -59,6 +59,7 @@
- 2026-06-18 移动壳网络安全元数据Expo 移动壳默认包配置显式禁用 Android 明文流量 `usesCleartextTraffic=false`iOS ATS 禁用任意加载 `NSAllowsArbitraryLoads=false`,并设置 `ITSAppUsesNonExemptEncryption=false` 作为当前未接入自定义加密能力的出口合规声明;本地 Vite 联调只通过 development build 显式环境变量进入,不把任意明文流量开关带进默认包配置。 - 2026-06-18 移动壳网络安全元数据Expo 移动壳默认包配置显式禁用 Android 明文流量 `usesCleartextTraffic=false`iOS ATS 禁用任意加载 `NSAllowsArbitraryLoads=false`,并设置 `ITSAppUsesNonExemptEncryption=false` 作为当前未接入自定义加密能力的出口合规声明;本地 Vite 联调只通过 development build 显式环境变量进入,不把任意明文流量开关带进默认包配置。
- 2026-06-18 移动壳麦克风权限禁用Expo 移动壳的 `expo-image-picker` 插件必须保持 `microphonePermission=false`Android 包配置必须通过 `android.blockedPermissions` 显式移除 `android.permission.RECORD_AUDIO`,且不得在 `android.permissions` 中重新声明;移动壳现阶段没有录音、后台音频采集或远程语音 SDK音频导入只走系统文档选择器。配置检查会拒绝麦克风权限拦截缺失或被反向加入。 - 2026-06-18 移动壳麦克风权限禁用Expo 移动壳的 `expo-image-picker` 插件必须保持 `microphonePermission=false`Android 包配置必须通过 `android.blockedPermissions` 显式移除 `android.permission.RECORD_AUDIO`,且不得在 `android.permissions` 中重新声明;移动壳现阶段没有录音、后台音频采集或远程语音 SDK音频导入只走系统文档选择器。配置检查会拒绝麦克风权限拦截缺失或被反向加入。
- 2026-06-18 移动壳 Android 自动备份关闭Expo 移动壳必须保持 `android.allowBackup=false`,避免 WebView cookie、localStorage、缓存文件和宿主文件导入导出中间态进入 Google Drive 自动备份 / 恢复链路;正式业务事实仍以后端账号、作品、钱包和草稿状态为准。配置检查会拒绝恢复 Android 默认允许备份的包配置。 - 2026-06-18 移动壳 Android 自动备份关闭Expo 移动壳必须保持 `android.allowBackup=false`,避免 WebView cookie、localStorage、缓存文件和宿主文件导入导出中间态进入 Google Drive 自动备份 / 恢复链路;正式业务事实仍以后端账号、作品、钱包和草稿状态为准。配置检查会拒绝恢复 Android 默认允许备份的包配置。
- 2026-06-18 移动壳 WebView 安全开关Expo 移动壳 WebView 必须显式禁用 JS 自动开窗、多窗口、文件访问、file URL 跨源访问、HTTPS 混合内容、第三方 Cookie、共享 Cookie 和 WebView 远程调试;同源主站页面才能留在带 HostBridge 的 WebView 内,外链只通过受控协议离开容器交给系统。配置检查和移动壳导航测试会拒绝这些边界被放宽。
- 影响范围:`src/services/host-bridge/`、未来 `apps/mobile-shell/`、未来 `apps/desktop-shell/`、移动端支付 / 分享 / 深链 / 推送、桌面端系统能力、AI H5 sandbox 的 GameBridge 边界。 - 影响范围:`src/services/host-bridge/`、未来 `apps/mobile-shell/`、未来 `apps/desktop-shell/`、移动端支付 / 分享 / 深链 / 推送、桌面端系统能力、AI H5 sandbox 的 GameBridge 边界。
- 验证方式普通浏览器、小程序、Expo 壳、Tauri 壳都能返回正确 `getHostRuntime()`;未支持能力能回退 H5固定玩法在各宿主中读取同一作品数据和运行态 snapshotAI sandbox 无法直接调用 HostBridgeTauri release 不允许任意远端页面调用桌面命令。 - 验证方式普通浏览器、小程序、Expo 壳、Tauri 壳都能返回正确 `getHostRuntime()`;未支持能力能回退 H5固定玩法在各宿主中读取同一作品数据和运行态 snapshotAI sandbox 无法直接调用 HostBridgeTauri release 不允许任意远端页面调用桌面命令。
- 关联文档:`docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md``docs/【前端架构】宿主壳能力统一协议-2026-06-17.md` - 关联文档:`docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md``docs/【前端架构】宿主壳能力统一协议-2026-06-17.md`

View File

@@ -321,6 +321,8 @@ GameBridge 禁止:
2026-06-18 追加:移动壳 Android 自动备份显式关闭。Expo `android.allowBackup=false`,避免 WebView cookie、localStorage、缓存文件、系统剪贴板导入中间文件等本地宿主状态进入 Google Drive 自动备份 / 恢复链路;正式业务事实仍以后端账号、作品、钱包和草稿状态为准,不依赖设备备份恢复。`apps/mobile-shell/scripts/check-config.mjs` 会拒绝恢复默认允许备份的 Android 包配置。 2026-06-18 追加:移动壳 Android 自动备份显式关闭。Expo `android.allowBackup=false`,避免 WebView cookie、localStorage、缓存文件、系统剪贴板导入中间文件等本地宿主状态进入 Google Drive 自动备份 / 恢复链路;正式业务事实仍以后端账号、作品、钱包和草稿状态为准,不依赖设备备份恢复。`apps/mobile-shell/scripts/check-config.mjs` 会拒绝恢复默认允许备份的 Android 包配置。
2026-06-18 追加:移动壳 WebView 原生安全开关显式收紧。`react-native-webview` 只加载同源主站入口,保留 JS 和 DOM storage 以运行现有 H5但禁用 JS 自动开窗、多窗口、文件访问、file URL 跨源访问、HTTPS 页面加载 HTTP 混合内容、第三方 Cookie、共享 Cookie 和 WebView 远程调试;外链继续只允许 `http:``https:``mailto:``tel:` 离开 WebView 交给系统。`apps/mobile-shell/scripts/check-config.mjs``mobileShellNavigation.test.ts` 会覆盖这些壳边界,避免后续为单个页面调试把完整 HostBridge 暴露给外域页面。
### Phase 4宿主能力扩展 ### Phase 4宿主能力扩展
- 移动端接入系统分享、推送、原生登录和渠道支付。 - 移动端接入系统分享、推送、原生登录和渠道支付。