titanium-sdk icon indicating copy to clipboard operation
titanium-sdk copied to clipboard

feat: android Ti.UI.WebView support allowFileAccess

Open markive opened this issue 3 years ago • 12 comments

This is needed so that local files can be loaded into a WebView.

In SDK 9.X.X this was allowed by default, in 10.X.X this is not the case. The Android documentation recommends that this is set to false by default so I have added this as a new Ti.UI.WebView property setAllowFileAccess() as per previous PR feedback

Fixes #13188

markive avatar Jan 04 '22 09:01 markive

Fails
:no_entry_sign: Test reports missing for MacOS. This indicates that a build failed or the test app crashed
:no_entry_sign:

:microscope: There are library changes, but no changes to the unit tests. That's OK as long as you're refactoring existing code, but will require an admin to merge this PR. Please see README.md#unit-tests for docs on unit testing.

Warnings
:warning: Tests have failed, see below for more information.
:warning: There is no linked JIRA ticket in the PR body. Please include the URL of the relevant JIRA ticket. If you need to, you may file a ticket on JIRA
Messages
:book: :fist: The commits in this PR match our conventions! Feel free to Rebase and Merge this PR when ready.
:book: :x: 1 tests have failed There are 1 tests failing and 902 skipped out of 17426 total tests.
:book:

:confetti_ball: Welcome to the Titanium SDK community, markive! Thank you so much for your PR, you're helping us make Titanium better. :gift:

Tests:

ClassnameNameTimeError
android.emulator.main.Titanium.Geolocation.methods#forwardGeocoder() works via callback argument (12)5.043
Error: expected false to be true
at Assertion.fail (/node_modules/should/cjs/should.js:275:13)
      at Assertion.value (/node_modules/should/cjs/should.js:356:9)
      at Geolocation.<anonymous> (/ti.geolocation.test.js:585:32)

Generated by :no_entry_sign: dangerJS against 1b90b9511bdb0e8a265c20c47e4f5e37e120999b

build avatar Jan 04 '22 10:01 build

I feel like there was a reason for it to be removed. Kindly tagging @jquick-axway who most likely knows more here.

hansemannn avatar Mar 21 '22 18:03 hansemannn

This "feature" allows the website to use "file://" URLs to access local files. Apple and Google considers this to be a security issue. And it violates the "same origin" policy for URLs and exposes a cross-app/site scripting vulnerability. If the Android device is rooted, then it might expose the entire Android file system to the web view too. https://developer.android.com/reference/android/webkit/WebSettings#setAllowFileAccess(boolean)

I'm pretty sure Google Play's security scanner will flag the app with a warning if it sees this API in the code. I'd be worried about all apps getting wrongly flagged. https://stackoverflow.com/questions/50791306/google-play-warning-your-app-contains-a-file-based-xss-issue-javascript-enable https://stackoverflow.com/questions/53095398/google-play-warning-your-app-contains-a-cross-app-scripting-vulnerability

On iOS, you have to use the assetsDirectory property and assign it the local directory or single file you want to expose to the WebView. https://titaniumsdk.com/api/titanium/ui/webview.html#assetsdirectory

Maybe something similar can be implemented via the WebViewAssetLoader? This class' shouldInterceptRequest() method can intercept any URL (such as a file:// URL) and return the file content the website is looking for... but only if the file "should" be exposed. Probably more work than what you guys want to implement. https://developer.android.com/reference/android/webkit/WebResourceResponse.html

jquick-axway avatar Mar 21 '22 22:03 jquick-axway

Thanks @jquick-axway for your detailed explanation!

@hansemannn Only setAllowFileAccessFromFileURLs() and setAllowUniversalAccessFromFileURLs() are deprecated in API level 30, but setAllowFileAccess() is still available. In this PR it is set to false by default as recommended, so why not give the option to explicitly changing it (regardless of the fact that an implementation via WebViewAssetLoader is indeed needed) ? A note could be added to the Titanium API reference like in the Android developer reference.

In this way one can explicitly allow file:// access in e.g. an inhouse app outside Google Play.

hbugdoll avatar May 25 '22 15:05 hbugdoll

There is an example for WebViewAssetLoader in https://developer.android.com/reference/androidx/webkit/WebViewAssetLoader

But it looks like we can use this PR too: https://github.com/tidev/titanium_mobile/issues/13188#issuecomment-1177675842 and it's not being flagged by Google.

m1ga avatar Jul 07 '22 14:07 m1ga

Can we merge it?

Xlinx64 avatar Jul 27 '22 12:07 Xlinx64

We need @markive as a listed contributor to merge this

caspahouzer avatar Jul 28 '22 05:07 caspahouzer

@Xlinx64 @caspahouzer, sorry i'm not very Github experienced.. I think we are all good to merge, I've updated branch to merge latest changes.. Anything else I'm needed to do?

markive avatar Aug 30 '22 03:08 markive

@markive you have to sign the contributor cla as described. After you've been added to the contributors list we can merge your changes.

caspahouzer avatar Aug 30 '22 06:08 caspahouzer

@caspahouzer ok I've reached out to Josh, thanks!

markive avatar Aug 30 '22 06:08 markive

@caspahouzer please note I have signed the CLA, so as soon as I appear on the contributor list this can be merged. Thanks!

markive avatar Sep 09 '22 02:09 markive

@caspahouzer @m1ga I am now on the contributor list so I think all is in place, thanks! https://github.com/tidev/organization-docs/blob/main/AUTHORIZED_CONTRIBUTORS.md

markive avatar Sep 20 '22 00:09 markive

Will this be part of the next release? What is keeping us back to approve and merge this?

Xlinx64 avatar Sep 26 '22 12:09 Xlinx64

Is there anything else I need to do? This is my first submission..

markive avatar Sep 27 '22 01:09 markive

@markive can you add it to the docs too. Have a look at https://github.com/tidev/titanium_mobile/blob/master/apidoc/Titanium/UI/WebView.yml#L727-L735 for an example.

Also tried to test it but I wasn't successful. I've tried:

const win = Ti.UI.createWindow({});
const webview = Ti.UI.createWebView({
	allowFileAccess: true,
});
win.add(webview);

win.addEventListener("open", function() {
	var permissions = [ 'android.permission.READ_EXTERNAL_STORAGE' ];
	Ti.Android.requestPermissions(permissions, function(e) {
		if (e.success) {
			webview.url = "file:////storage/emulated/0/test.html";
		}
	});
})
win.open();

but still get err_access_denied

m1ga avatar Sep 27 '22 10:09 m1ga

@m1ga I've retested it and it does work for me like this:

image image
const win = Ti.UI.createWindow({});
const webview = Ti.UI.createWebView({
	allowFileAccess: true,
});
win.add(webview);

win.addEventListener("open", function() {

            var assetFile = Ti.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory, '/images/[email protected]');
            var destFile = Ti.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, '[email protected]')

            if (!destFile.exists()) {
                assetFile.copy(destFile.nativePath);
            }

			webview.url = "test.html";
})
win.open();`
`<!doctype html>
<html>
	<head>
		<title>View Plan</title>
		<meta name="viewport" content="width=device-width, maximum-scale=4, minimum-scale=0.1, user-scalable=yes">
		<meta name="format-detection" content="telephone=no"/>
		
		<style type="text/css">
			/* Prevent the default selection behaviour */
			html, body {
				-webkit-user-select: none;
				-webkit-touch-callout: none;
			}
		
			html, body, #plan-image { 
				margin: 0; padding: 0; 
			}
			
			#plan-image {
				position: relative;
				height: 1000px;
				width: 1000px;
				z-index: 1;		
			}
			
			.defect, .newDefect, .location, .drilldown, .mp { 				
				position: absolute; 
				cursor: pointer;
				z-index: 2;
				
				background-repeat: no-repeat;
				background-color: transparent;
				
				-webkit-background-size: 100% 100%;
          		background-size: 100% 100%;
			}
				
			.defect {
				width: 50px; 
				height: 50px;
				background-image: url(file:///android_asset/Resources/images/[email protected]);
			}

			.blueDefect {
				padding-left:10px;
				width: 50px; 
				height: 50px;
				background-image: url(file:///data/user/0/uk.co.marktestdelete/app_appdata/[email protected]);
			}
			
		</style>
	</head>
	<body>
		<div id="plan-image">
			<div class="defect" >&nbsp;</div>
			<div class="blueDefect" style="margin-left:10px">&nbsp;</div>
			<h1>hello!</h1>
		</div>
		
		
	</body>
</html>`

First test is with allowFileAccess: false, second is true.

markive avatar Oct 11 '22 03:10 markive

Thanks for the example @markive :+1: That helped and it's working fine. Testing it with Liveview wasn't a good idea since that cached the images in the webview even when you switch it off.

m1ga avatar Oct 11 '22 08:10 m1ga

@m1ga & @markive

Thanks for helps. It's working fine.

git

akinsoftyazilim42 avatar Oct 11 '22 11:10 akinsoftyazilim42

~~PR can be closed in my opinion.~~ Why it is still not merged into tidev:master and was not released with Ti 12.0.0 ?

hbugdoll avatar Dec 07 '22 16:12 hbugdoll

@m1ga what is still needed? Tests and checks have passed, @markive is listed as a authorized contributor.

hbugdoll avatar Feb 24 '23 13:02 hbugdoll

@hbugdoll I don't merge PRs, I'm only a contributor too. I have more than one PR waiting :wink: So we'll need to be patient (or you a custom SDK with this PR merged in)

m1ga avatar Feb 24 '23 13:02 m1ga

@hbugdoll I don't merge PRs, I'm only a contributor too.

@m1ga Thank you for the clarification.

hbugdoll avatar Feb 24 '23 13:02 hbugdoll

To check if there is any automatic security scan that would flag an app I've uploaded an app with 12.1.0 (master) + this PR merge in. I didn't enable the flag so it's a "normal" app build like other users would do it too. No issues during app upload check and after the review. App is live, no warnings :+1:

m1ga avatar Mar 13 '23 21:03 m1ga

Yes I have also been using this in production across 2 different apps for over 1yr, so that is many many full reviews and approvals with no issue.

markive avatar Mar 14 '23 00:03 markive

We released an app using setAllowFileAccess(true) in Google Play without any issues last year.

hbugdoll avatar Mar 15 '23 12:03 hbugdoll