feat: WebView OPEN_EXTERNAL_URL 메시지 핸들러 추가#18
Conversation
개요WebView 메시지 프로토콜에 외부 URL을 열기 위한 새 메시지 타입 변경 사항웹뷰 메시지 프로토콜 확장
예상 코드 리뷰 난이도🎯 2 (Simple) | ⏱️ ~10분 관련된 가능성 있는 PR
제안된 검수자
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@hooks/use-webview-message-handler.ts`:
- Around line 49-57: WebView에서 받은 URL을 검증 없이 Linking.openURL에 전달하고
있으니(WebViewMessageTypes.OPEN_EXTERNAL_URL 케이스, message.payload.url), 허용 스킴(예:
http/https)만 통과시키고 안전하게 열도록 수정하세요: URL 문자열에서 스킴을 파싱해 허용 목록에 있는지 확인하고, 허용될 때만
Linking.canOpenURL(url)로 열 수 있는지 검사한 뒤 Linking.openURL(url)을 호출하며, 그렇지 않으면
경고/오류를 로깅해 차단하도록 구현합니다.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 9a143d25-d1de-4e5e-97e6-8503647876fb
📒 Files selected for processing (2)
hooks/use-webview-message-handler.tstypes/webview-message.types.ts
| case WebViewMessageTypes.OPEN_EXTERNAL_URL: { | ||
| const { url } = message.payload; | ||
| if (url) { | ||
| Linking.openURL(url).catch(err => | ||
| console.error('[WebViewHandler] URL 열기 실패:', err) | ||
| ); | ||
| } | ||
| break; | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
fd -t f "use-webview-message-handler.ts" --type fRepository: Moadong/moadong-react-native
Length of output: 109
🏁 Script executed:
cat -n hooks/use-webview-message-handler.tsRepository: Moadong/moadong-react-native
Length of output: 2695
🏁 Script executed:
head -80 hooks/use-webview-message-handler.ts | cat -nRepository: Moadong/moadong-react-native
Length of output: 2695
🏁 Script executed:
rg -t ts "WebViewMessageTypes" --max-count 5 -A 3Repository: Moadong/moadong-react-native
Length of output: 1846
🏁 Script executed:
find . -type f -name "*webview*" | grep -E "\.(ts|tsx)$"Repository: Moadong/moadong-react-native
Length of output: 358
🏁 Script executed:
cat -n types/webview-message.types.tsRepository: Moadong/moadong-react-native
Length of output: 1041
🏁 Script executed:
cat -n ui/home/home-webview-screen.tsx | head -100Repository: Moadong/moadong-react-native
Length of output: 4522
🏁 Script executed:
rg "useWebViewMessageHandler" --type ts --type tsxRepository: Moadong/moadong-react-native
Length of output: 100
🏁 Script executed:
rg "Linking.openURL" --type ts --type tsx -B 3 -A 3Repository: Moadong/moadong-react-native
Length of output: 100
🏁 Script executed:
rg "useWebViewMessageHandler" -A 5 -B 5Repository: Moadong/moadong-react-native
Length of output: 4194
🏁 Script executed:
rg "Linking.openURL" -A 3 -B 3Repository: Moadong/moadong-react-native
Length of output: 1372
WebView에서 전달된 URL을 스킴 검증 없이 바로 여는 것은 보안 위험입니다.
49~56줄에서 WebView payload의 URL을 검증 없이 Linking.openURL()에 전달하고 있어, 의도치 않은 커스텀 스킴(예: tel:, mailto: 등) 실행 위험이 있습니다. 허용 스킴 제한(예: https/http)과 Linking.canOpenURL() 확인 후 열도록 수정해주세요.
수정 예시
case WebViewMessageTypes.OPEN_EXTERNAL_URL: {
- const { url } = message.payload;
- if (url) {
- Linking.openURL(url).catch(err =>
- console.error('[WebViewHandler] URL 열기 실패:', err)
- );
- }
+ const url = message.payload?.url;
+ if (!url) break;
+
+ try {
+ const parsed = new URL(url);
+ const allowedProtocols = new Set(['https:', 'http:']);
+ if (!allowedProtocols.has(parsed.protocol)) {
+ console.warn('[WebViewHandler] 허용되지 않은 URL 스킴:', parsed.protocol);
+ break;
+ }
+
+ Linking.canOpenURL(parsed.toString())
+ .then(canOpen => {
+ if (!canOpen) {
+ console.warn('[WebViewHandler] 열 수 없는 URL:', parsed.toString());
+ return;
+ }
+ return Linking.openURL(parsed.toString());
+ })
+ .catch(err => console.error('[WebViewHandler] URL 열기 실패:', err));
+ } catch {
+ console.warn('[WebViewHandler] 유효하지 않은 URL:', url);
+ }
break;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| case WebViewMessageTypes.OPEN_EXTERNAL_URL: { | |
| const { url } = message.payload; | |
| if (url) { | |
| Linking.openURL(url).catch(err => | |
| console.error('[WebViewHandler] URL 열기 실패:', err) | |
| ); | |
| } | |
| break; | |
| } | |
| case WebViewMessageTypes.OPEN_EXTERNAL_URL: { | |
| const url = message.payload?.url; | |
| if (!url) break; | |
| try { | |
| const parsed = new URL(url); | |
| const allowedProtocols = new Set(['https:', 'http:']); | |
| if (!allowedProtocols.has(parsed.protocol)) { | |
| console.warn('[WebViewHandler] 허용되지 않은 URL 스킴:', parsed.protocol); | |
| break; | |
| } | |
| Linking.canOpenURL(parsed.toString()) | |
| .then(canOpen => { | |
| if (!canOpen) { | |
| console.warn('[WebViewHandler] 열 수 없는 URL:', parsed.toString()); | |
| return; | |
| } | |
| return Linking.openURL(parsed.toString()); | |
| }) | |
| .catch(err => console.error('[WebViewHandler] URL 열기 실패:', err)); | |
| } catch { | |
| console.warn('[WebViewHandler] 유효하지 않은 URL:', url); | |
| } | |
| break; | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@hooks/use-webview-message-handler.ts` around lines 49 - 57, WebView에서 받은 URL을
검증 없이 Linking.openURL에 전달하고 있으니(WebViewMessageTypes.OPEN_EXTERNAL_URL 케이스,
message.payload.url), 허용 스킴(예: http/https)만 통과시키고 안전하게 열도록 수정하세요: URL 문자열에서 스킴을
파싱해 허용 목록에 있는지 확인하고, 허용될 때만 Linking.canOpenURL(url)로 열 수 있는지 검사한 뒤
Linking.openURL(url)을 호출하며, 그렇지 않으면 경고/오류를 로깅해 차단하도록 구현합니다.
WebView OPEN_EXTERNAL_URL 메시지 핸들러 누락 트러블슈팅
Summary by CodeRabbit
새로운 기능