diff --git a/.jules/sentinel.md b/.jules/sentinel.md new file mode 100644 index 0000000..39bab3e --- /dev/null +++ b/.jules/sentinel.md @@ -0,0 +1,4 @@ +## 2024-04-20 - XSS in WebView injectJavaScript +**Vulnerability:** XSS vulnerability through string interpolation in WebView `injectJavaScript`. +**Learning:** Avoid using `injectJavaScript` with string interpolation for data transfer. It can lead to script injection attacks if the data is not properly sanitized. +**Prevention:** Use `webViewRef.current.postMessage(data)` and set up corresponding `message` event listeners in the WebView's JavaScript context for both `window` and `document` (`window.addEventListener('message', ...)` and `document.addEventListener('message', ...)`) to ensure cross-platform compatibility between iOS and Android. diff --git a/src/screens/HomeScreen.tsx b/src/screens/HomeScreen.tsx index 8475bcb..c2ebd54 100644 --- a/src/screens/HomeScreen.tsx +++ b/src/screens/HomeScreen.tsx @@ -42,7 +42,12 @@ const weatherMap: Record = { const engineHtml = ` `; function PinnedFlightCardComponent({ item, colors }: { item: any; colors: any }) { @@ -288,14 +295,7 @@ export default function HomeScreen() { const base64List = result.assets.map(a => `data:image/jpeg;base64,${a.base64}`); const base64Json = JSON.stringify(base64List); // Use postMessage pattern to avoid script-injection risks with injectJavaScript - webViewRef.current?.injectJavaScript(` - if(window.runTesseract){ - window.runTesseract(${JSON.stringify(base64Json)}); - } else { - window.ReactNativeWebView.postMessage(JSON.stringify({success:false,error:'OCR non pronto'})); - } - true; - `); + webViewRef.current?.postMessage(base64Json); } } catch (e) { if (__DEV__) console.error('[imagePicker]', e); setProcessing(false); } }; diff --git a/src/screens/ShiftScreen.tsx b/src/screens/ShiftScreen.tsx index e04f2fb..fba8736 100644 --- a/src/screens/ShiftScreen.tsx +++ b/src/screens/ShiftScreen.tsx @@ -31,17 +31,9 @@ export default function ShiftScreen() { setOcrText(''); const base64List = result.assets.map(a => `data:image/jpeg;base64,${a.base64}`); - const base64Json = JSON.stringify(base64List).replace(/'/g, "\\'"); + const base64Json = JSON.stringify(base64List); - const jsCode = ` - if (window.runTesseract) { - window.runTesseract('${base64Json}'); - } else { - window.ReactNativeWebView.postMessage(JSON.stringify({ success: false, error: "Motore OCR non pronto." })); - } - true; - `; - webViewRef.current?.injectJavaScript(jsCode); + webViewRef.current?.postMessage(base64Json); } } catch (e) { Alert.alert("Errore OCR", "Impossibile elaborare l'immagine."); @@ -216,7 +208,12 @@ export default function ShiftScreen() {