An embedded WebView used for OAuth credential entry violates Apple's guideline 5.1.1 and the OAuth 2.0 security model: the app can read the WebView's DOM content, giving it access to the user's credentials on the OAuth provider's login page. CWE-522 (insufficiently protected credentials) applies directly. Google, Apple, and GitHub explicitly prohibit embedded WebView OAuth because it enables phishing — an app can silently capture the username and password typed into what appears to be Google's login form. The correct implementations (SFSafariViewController, AuthenticationSession, Chrome Custom Tabs) operate in a separate process the app cannot read.
Low because the pattern requires an OAuth flow to be present and is not an immediate binary rejection in all cases, but Apple has started rejecting it more consistently under guideline 5.1.1.
Replace any WebView OAuth flow with expo-auth-session, which uses SFSafariViewController on iOS and Chrome Custom Tabs on Android.
// src/screens/LoginScreen.tsx
import * as Google from 'expo-auth-session/providers/google';
export default function LoginScreen() {
const [request, response, promptAsync] = Google.useAuthRequest({
clientId: process.env.EXPO_PUBLIC_GOOGLE_CLIENT_ID,
});
useEffect(() => {
if (response?.type === 'success') {
const { authentication } = response;
// exchange authentication.accessToken for your session
}
}, [response]);
return <Button title="Sign in with Google" onPress={() => promptAsync()} />;
}
For Apple Sign In (required when offering any third-party sign-in on iOS), use expo-apple-authentication. Never use a <WebView source={{ uri: 'https://accounts.google.com/...' }} /> for credential entry.
app-store-review-blockers.technical-requirements.webview-oauth-securelowWebView components used for authentication (check props like source={{ uri: 'https://accounts.google.com/...' }} or similar OAuth provider URLs in WebView). The correct pattern is: expo-auth-session (Expo), react-native-app-auth (React Native), SFSafariViewController (iOS native), Chrome Custom Tabs (Android). Look for WebView imports in authentication-related files: src/screens/auth/, src/components/auth/, login flows. Check if the WebView has access to the user's session cookies (which would allow the app to read OAuth tokens from the page content).SFSafariViewController / AuthenticationSession on iOS, Chrome Custom Tabs on Android) or well-established auth libraries (expo-auth-session, react-native-app-auth). At least 1 implementation must be verified. No embedded WebView is used for OAuth credential entry.WebView component that loads an OAuth provider's login page (Google, Apple, Facebook, GitHub, etc.) — this allows the app to read the WebView's content, which is a security violation."Google OAuth is implemented with an embedded WebView loading accounts.google.com — use expo-auth-session or react-native-app-auth instead"expo-auth-session:
import * as Google from 'expo-auth-session/providers/google';
const [request, response, promptAsync] = Google.useAuthRequest({ ... });
react-native-app-auth for non-Expo projectsexpo-apple-authentication or the AuthenticationServices framework directly — this is required for any app offering third-party sign-in on iOS