رده OWASP: MASVS-STORAGE: ذخیرهسازی
نمای کلی
این سند چندین مسئله مربوط به گنجاندن فایل را پوشش میدهد که راهکارهای کاهش مشابهی دارند. این مسائل بر آسیبپذیریهای ناشی از دسترسی به فایلها در WebViews متمرکز هستند و از WebSettings خطرناک که اجازه دسترسی به فایل یا فعال کردن جاوا اسکریپت را میدهد تا یک روش WebKit که درخواست انتخاب فایل ایجاد میکند، متغیر هستند. اگر به دنبال راهنمایی در مورد رفع مشکلات درون WebView ناشی از استفاده از طرح file:// ، دسترسی نامحدود به فایلهای محلی و اسکریپتنویسی بین سایتی هستید، این سند باید مفید باشد.
به طور دقیقتر، این سند موضوعات زیر را پوشش میدهد:
-
WebSettingsکلاسی است که شامل متدهایی است که حالتهای تنظیمات WebViewها را مدیریت میکنند. این متدها میتوانند WebViewها را در معرض حملات مختلفی قرار دهند که بعداً به آنها اشاره خواهد شد. در این سند، به متدهایی که مربوط به نحوه دسترسی به فایلها و تنظیماتی هستند که امکان اجرای جاوا اسکریپت را فراهم میکنند، خواهیم پرداخت: - متدهای
setAllowFileAccess،setAllowFileAccessFromFileURLsوsetAllowUniversalAccessFromFileURLsمیتوانند برای اعطای دسترسی به فایلهای محلی، با استفاده از یک آدرس فایل (file://) استفاده شوند. با این حال، اسکریپتهای مخرب میتوانند از آنها برای دسترسی به فایلهای محلی دلخواه که برنامه به آنها دسترسی دارد، مانند پوشه/data/خود، سوءاستفاده کنند. به همین دلیل، این متدها به عنوان ناامن علامتگذاری شده و در API 30 به نفع جایگزینهای امنتر، مانندWebViewAssetLoader، منسوخ شدهاند. - متد
setJavascriptEnabledمیتواند برای فعال کردن اجرای جاوا اسکریپت در WebViewها استفاده شود. این امر برنامهها را در برابر XSS مبتنی بر فایل آسیبپذیر میکند. به خصوص هنگامی که پیکربندی شده باشد تا امکان بارگذاری فایلهای محلی یا محتوای وب غیرقابل اعتماد که ممکن است حاوی کد اجرایی باشند را فراهم کند، پیکربندی شده باشد تا امکان دسترسی به فایلهایی را فراهم کند که میتوانند توسط منابع خارجی ایجاد یا تغییر داده شوند، یا به WebViewها اجازه اجرای جاوا اسکریپت را بدهد، کاربران و دادههای آنها در معرض خطر قرار میگیرند. -
WebChromeClient.onShowFileChooserمتدی متعلق به پکیجandroid.webkitاست که ابزارهای مرور وب را ارائه میدهد. این متد میتواند برای اجازه دادن به کاربران جهت انتخاب فایلها درون یک WebView مورد استفاده قرار گیرد. با این حال، این ویژگی میتواند مورد سوءاستفاده قرار گیرد زیرا WebViewها محدودیتهایی را در مورد اینکه کدام فایل انتخاب شود اعمال نمیکنند.
تأثیر
تأثیر گنجاندن فایل میتواند به تنظیمات وب (WebSettings) پیکربندی شده در WebView بستگی داشته باشد. مجوزهای فایل بیش از حد گسترده میتواند به مهاجمان اجازه دهد به فایلهای محلی دسترسی پیدا کنند و دادههای حساس، PII (اطلاعات شخصی قابل شناسایی) یا دادههای برنامه خصوصی را سرقت کنند. فعال کردن اجرای جاوا اسکریپت میتواند به مهاجمان اجازه دهد جاوا اسکریپت را در یک WebView یا روی دستگاه کاربر اجرا کنند. فایلهای انتخاب شده با استفاده از روش onShowFileChooser میتوانند امنیت کاربر را به خطر بیندازند زیرا هیچ راهی برای روش یا WebView وجود ندارد که از قابل اعتماد بودن منبع فایل اطمینان حاصل کند.
Risk: Risky Access to Files through file://
فعال کردن setAllowFileAccess ، setAllowFileAccessFromFileURLs و setAllowUniversalAccessFromFileURLs میتواند به بدافزارها و درخواستهای WebView با زمینه file:// اجازه دسترسی به فایلهای محلی دلخواه، از جمله کوکیهای WebView و دادههای خصوصی برنامه را بدهد. علاوه بر این، استفاده از متد onShowFileChooser میتواند به کاربران اجازه دهد فایلها را از منابع غیرقابل اعتماد انتخاب و دانلود کنند.
بسته به پیکربندی برنامه، این روشها میتوانند منجر به استخراج اطلاعات شخصی، اطلاعات ورود یا سایر دادههای حساس شوند.
کاهشها
اعتبارسنجی آدرسهای اینترنتی فایلها
اگر برنامه شما نیاز به دسترسی به فایلها از طریق آدرسهای اینترنتی file:// دارد، مهم است که فقط آدرسهای اینترنتی خاصی را که معتبر شناخته شدهاند، در فهرست قرار دهید تا از اشتباهات رایج جلوگیری شود.
استفاده از WebViewAssetLoader
به جای روشهای ذکر شده، از WebViewAssetLoader استفاده کنید. این روش از طرح http(s)//: به جای طرح file:// برای دسترسی به داراییهای سیستم فایل محلی استفاده میکند و در برابر حملهی شرح داده شده آسیبپذیر نیست.
کاتلین
val assetLoader: WebViewAssetLoader = Builder()
.addPathHandler("/assets/", AssetsPathHandler(this))
.build()
webView.setWebViewClient(object : WebViewClientCompat() {
@RequiresApi(21)
override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest): WebResourceResponse {
return assetLoader.shouldInterceptRequest(request.url)
}
@Suppress("deprecation") // for API < 21
override fun shouldInterceptRequest(view: WebView?, url: String?): WebResourceResponse {
return assetLoader.shouldInterceptRequest(Uri.parse(url))
}
})
val webViewSettings: WebSettings = webView.getSettings()
// Setting this off for security. Off by default for SDK versions >= 16.
webViewSettings.allowFileAccessFromFileURLs = false
// Off by default, deprecated for SDK versions >= 30.
webViewSettings.allowUniversalAccessFromFileURLs = false
// Keeping these off is less critical but still a good idea, especially if your app is not
// using file:// or content:// URLs.
webViewSettings.allowFileAccess = false
webViewSettings.allowContentAccess = false
// Assets are hosted under http(s)://appassets.androidplatform.net/assets/... .
// If the application's assets are in the "main/assets" folder this will read the file
// from "main/assets/www/index.html" and load it as if it were hosted on:
// https://appassets.androidplatform.net/assets/www/index.html
webView.loadUrl("https://appassets.androidplatform.net/assets/www/index.html")
جاوا
final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder()
.addPathHandler("/assets/", new AssetsPathHandler(this))
.build();
webView.setWebViewClient(new WebViewClientCompat() {
@Override
@RequiresApi(21)
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
return assetLoader.shouldInterceptRequest(request.getUrl());
}
@Override
@SuppressWarnings("deprecation") // for API < 21
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
return assetLoader.shouldInterceptRequest(Uri.parse(url));
}
});
WebSettings webViewSettings = webView.getSettings();
// Setting this off for security. Off by default for SDK versions >= 16.
webViewSettings.setAllowFileAccessFromFileURLs(false);
// Off by default, deprecated for SDK versions >= 30.
webViewSettings.setAllowUniversalAccessFromFileURLs(false);
// Keeping these off is less critical but still a good idea, especially if your app is not
// using file:// or content:// URLs.
webViewSettings.setAllowFileAccess(false);
webViewSettings.setAllowContentAccess(false);
// Assets are hosted under http(s)://appassets.androidplatform.net/assets/... .
// If the application's assets are in the "main/assets" folder this will read the file
// from "main/assets/www/index.html" and load it as if it were hosted on:
// https://appassets.androidplatform.net/assets/www/index.html
webview.loadUrl("https://appassets.androidplatform.net/assets/www/index.html");
Disable dangerous WebSettings methods
مقادیر متدهای setAllowFileAccess() ، setAllowFileAccessFromFileURLs() و setAllowUniversalAccessFromFileURLs() به طور پیشفرض در سطح API 29 و پایینتر روی TRUE و در سطح API 30 و بالاتر FALSE تنظیم شدهاند.
اگر نیاز به پیکربندی سایر WebSettings باشد، بهتر است این روشها را به طور صریح غیرفعال کنید، به خصوص برای برنامههایی که سطوح API کمتر یا مساوی ۲۹ را هدف قرار میدهند.
Risk: File-Based XSS
تنظیم متد setJavacriptEnabled روی TRUE به جاوا اسکریپت اجازه میدهد تا درون یک WebView اجرا شود و در ترکیب با دسترسی به فایل که همانطور که قبلاً توضیح داده شد فعال است، XSS مبتنی بر فایل از طریق اجرای کد درون فایلهای دلخواه یا وبسایتهای مخرب باز شده در WebView امکانپذیر است.
کاهشها
جلوگیری از بارگذاری فایلهای محلی توسط WebViews
همانند ریسک قبلی، در صورتی که setAllowFileAccess() ، setAllowFileAccessFromFileURLs() و setAllowUniversalAccessFromFileURLs() روی FALSE تنظیم شوند، میتوان از XSS مبتنی بر فایل جلوگیری کرد.
Prevent WebViews executing JavaScript
متد setJavascriptEnabled روی FALSE تنظیم کنید تا جاوا اسکریپت نتواند درون WebViewها اجرا شود.
مطمئن شوید که WebViewها محتوای غیرقابل اعتماد را بارگذاری نمیکنند
گاهی اوقات فعال کردن این تنظیمات در WebViews ضروری است. در این حالت، مهم است که مطمئن شوید فقط محتوای قابل اعتماد بارگذاری میشود. محدود کردن اجرای جاوا اسکریپت فقط به مواردی که کنترل میکنید و عدم اجازه به جاوا اسکریپتهای دلخواه، یک راه خوب برای اطمینان از قابل اعتماد بودن محتوا است. در غیر این صورت، جلوگیری از بارگذاری ترافیک cleartext تضمین میکند که WebViews با تنظیمات خطرناک حداقل قادر به بارگذاری URL های HTTP نیستند. این کار را میتوان از طریق manifest، تنظیم android:usesCleartextTraffic روی False یا با تنظیم Network Security Config که ترافیک HTTP را غیرفعال میکند، انجام داد.
منابع
- صفحه مرجع API مربوط به setAllowUniversalAccessFromFileURLs
- صفحه مرجع API مربوط به setAllowFileAccessFromFileURLs
- WebViewAssetLoader API reference page
- CodeQL documentation
- Oversecured blog
- صفحه مرجع onShowFileChooser