Android phonegap Source Analysis-white list

Source: Internet
Author: User

For a standalone web app, the URL that is loaded does not guarantee its security. So how to deal with the problem of URL security?

Let's take a look at how PhoneGap is doing.

PhoneGap takes the form of a whitelist, thinking that URLs in the whitelist are considered safe, and URLs that are not whitelisted are unsafe. For secure Url,phonegap, the Web app opens directly and opens in a browser for unsafe URLs.

So how do you add white lists? PhoneGap is required to be set in configuration file Res/xml/config.xml, as follows:

 <cordova>-<!--access Elements control the Android whitelist. Domains is assumed blocked unless set otherwise-<access origin= "Http://127.0.0.1*"/>-<!--all   OW local pages-<!--<access origin= "https://example.com"/> Allow any secure requests to example.com --<!--<access origin= "https://example.com" subdomains= "true"/> such as above, but including subdomain s, such as www--and <access origin= ". *"/> <log level= "DEBUG"/> <preference name= "usebrowserhist Ory "value=" false "/> <preference name=" Exit-on-suspend "value=" false "/>-<plugins> <plugin name=" A PP "value=" org.apache.cordova.App "/> <plugin name=" geolocation "value=" Org.apache.cordova.GeoBroker "/> &lt ;p lugin name= "Device" value= "Org.apache.cordova.Device"/> <plugin name= "Accelerometer" value= " Org.apache.cordova.AccelListener "/> <plugin name=" Compass "value=" Org.apache.Cordova.  Compasslistener "/> <plugin name=" Media "value=" Org.apache.cordova.AudioHandler "/> <plugin name=" Camera " Value= "Org.apache.cordova.CameraLauncher"/> <plugin name= "Contacts" value= " Org.apache.cordova.ContactManager "/> <plugin name=" File "value=" Org.apache.cordova.FileUtils "/> < Plugin name= "NetworkStatus" value= "Org.apache.cordova.NetworkManager"/> <plugin name= "Notification" value= " Org.apache.cordova.Notification "/> <plugin name=" Storage "value=" Org.apache.cordova.Storage "/> <plugin Name= "Temperature" value= "Org.apache.cordova.TempListener"/> <plugin name= "Filetransfer" value= " Org.apache.cordova.FileTransfer "/> <plugin name=" Capture "value=" Org.apache.cordova.Capture "/> <plugin Name= "Battery" value= "Org.apache.cordova.BatteryListener"/> <plugin name= "SplashScreen" value= "   Org.apache.cordova.SplashScreen "/> <plugin name=" Echo "value=" Org.apache.cordova.Echo "/><plugin name= "Globalization" value= "Org.apache.cordova.Globalization"/> </plugins> </cordova> 

Among them, <access origin= "Http://127.0.0.1*"/> is added white list, we only need to add the URL after the *, on the format added to the configuration file.

So how does phonegap make the white list? Let's take a look at the source code: Cordovawebview.java. Cordovawebview is the base class for the displayed WebView. It will load configuration entries for the configuration file at initialization, with the following source code:

    /** * Load Cordova configuration from Res/xml/cordova.xml. * Approved list of URLs that can is loaded into Droidgap * <access origin= "http://server regexp" subdomains= "t Rue "/> * Log level:error, WARN, INFO, DEBUG, VERBOSE (default=error) * <log level=" DEBUG "/> * /private void Loadconfiguration () {int id = getresources (). Getidentifier ("config", "xml", This.cordova.getActi        Vity (). Getpackagename ()); if (id = = 0) {id = getresources (). Getidentifier ("Cordova", "xml", This.cordova.getActivity (). Getpackagen               Ame ());        LOG.I ("Cordovalog", "config. Missing, reverting to Cordova.xml"); } if (id = = 0) {log.i ("Cordovalog", "Cordova.xml missing").            Ignoring ... ");        Return        } xmlresourceparser XML = Getresources (). GETXML (ID);        int eventtype =-1; while (eventtype! = xmlresourceparser.end_document) {if (EventType = = XmlresourceparseR.start_tag) {String Strnode = Xml.getname ();                    if (Strnode.equals ("Access")) {String origin = Xml.getattributevalue (null, "origin");                    String subdomains = Xml.getattributevalue (null, "subdomains"); If (origin = null) {This.addwhitelistentry (Origin, (subdomains! = null) && (subdomains.co                    Mparetoignorecase ("true") = = 0)); }} else if (Strnode.equals ("log")) {String level = Xml.getattributevalu                    E (NULL, "level");                    LOG.I ("Cordovalog", "Found log level%s", level);                    if (level! = null) {Log.setloglevel (level); }} else if (Strnode.equals ("preference")) {String name = Xml.getattribu                    Tevalue (NULL, "name");          String value = Xml.getattributevalue (null, "value");          LOG.I ("Cordovalog", "Found preference for%s=%s", name, value);                    LOG.D ("Cordovalog", "Found preference for" + name + "=" + value);                Save preferences in Intent this.cordova.getActivity (). Getintent (). PutExtra (name, value);            }} try {EventType = Xml.next ();            } catch (Xmlpullparserexception e) {e.printstacktrace ();            } catch (IOException e) {e.printstacktrace ();            }}//Init Preferences if ("true". Equals (This.getproperty ("Usebrowserhistory", "false"))) {        This.usebrowserhistory = true;        } else {this.usebrowserhistory = false; } if ("true". Equals (This.getproperty ("fullscreen", "false"))) {this.cordova.getActivity (). GetWindow (). c            Learflags (WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); This.cordova.getActivity (). GETwindow (). SetFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); }    }

When parsing an XML file, the contents of the origin tag are added to the whitelist, and the Addwhitelistentry method is called. Let's take a look at the source code of the Addwhitelistentry method:

    public void Addwhitelistentry (String origin, Boolean subdomains) {try {//Unlimited access to NETW Ork Resources if (Origin.compareto ("*") = = 0) {log.d (TAG, "Unlimited access to network resource                S ");            This.whiteList.add (Pattern.compile (". *"));  } else {//specific access//check if subdomains should is included//todo:we should not Add more domains if * have already been added if (subdomains) {//XXX making it stupid                        Friendly for people-forget to include Protocol/ssl if (Origin.startswith ("http")) { This.whiteList.add (Pattern.compile (Origin.replacefirst ("https?:/ /"," ^https?:/ /(.*\\.)?")));                    } else {This.whiteList.add (Pattern.compile ("^https?:/ /(.*\\.)?"                    + origin)); } log.d (TAG, "origin to allow with subdomains:%s", origin);                    } else {//XXX making it stupid friendly for people. Forget to include Protocol/ssl if (Origin.startswith ("http")) {This.whiteList.add ("Pattern.compile" ("https") ("Origin.replacefirst" ://"," ^https?:/                    /"))); } else {This.whiteList.add (Pattern.compile ("^https?:/                    /"+ origin)";                } log.d (TAG, "Origin to allow:%s", origin);        }}} catch (Exception e) {log.d (TAG, "Failed to add Origin%s", origin); }    }

As we can see, it is parsed with a regular expression to add the URL of the whitelist to the whitelist attribute, and whitelist is a ArrayList type property.

So how does the PhoneGap Web app use the whitelist when it comes to displaying Web pages? Let's continue to look at the following source code, which is the method that will be called when the page is loaded:

    /** * Load The specified URL in the Cordova WebView or a new browser instance.     * * Note:if openexternal is false, only URLs listed in whitelist can be loaded.     * * @param url the URL to load.     * @param openexternal Load URL in browser instead of Cordova WebView. * @param clearhistory Clear The history stack, so new page becomes top of history * @param params droidgap par Ameters for new app */public void showwebpage (String url, Boolean openexternal, Boolean clearhistory, Hashmap<s        Tring, object> params) {log.d (TAG, "Showwebpage (%s,%b,%b, HashMap", url, openexternal, clearhistory);        If clearing history if (clearhistory) {this.clearhistory ();            }//If loading into we webview if (!openexternal) {//Make sure URL are in whitelist if (Url.startswith ("file://") | | | url.indexof (this.baseurl) = = 0 | | isurlwhitelisted (URL)) {//Todo:wHat about params?                    Clear out current URLs from the history, since it'll be replacing it if (clearhistory) {                This.urls.clear ();            }//Load new URL this.loadurl (URL); }//load in the default viewer if not else {LOG.W (TAG, "Showwebpage:cannot load URL in  To WebView since it isn't in white list. Loading into browser instead.                (url= "+ URL +") ");                    try {Intent Intent = new Intent (Intent.action_view);                    Intent.setdata (uri.parse (URL));                Cordova.getactivity (). StartActivity (Intent);                } catch (Android.content.ActivityNotFoundException e) {log.e (TAG, "Error loading url" + URL, e); }}}//Load in default view intent else {try {in          Tent Intent = new Intent (Intent.action_view);      Intent.setdata (uri.parse (URL));            Cordova.getactivity (). StartActivity (Intent);            } catch (Android.content.ActivityNotFoundException e) {log.e (TAG, "Error loading url" + URL, e); }        }    }

We can see that in the inside will use isurlwhitelisted and other methods to determine whether the URL is in the whitelist, or whether it is safe, and then the secure URL directly through the Loadurl to load into the Web app, URLs that PhoneGap consider unsafe are opened by intent to the browser to load the Web page.

The following is a isurlwhitelisted method of the source code:

/** * Determine if URL is in approved list of URLs to load. * * @param URL * @return */public boolean isurlwhitelisted (String URL) {//Check to see if we hav        E matched URL previously if (this.whiteListCache.get (URL)! = null) {return true;        }//Look for match in the white list iterator<pattern> pit = This.whiteList.iterator ();            while (Pit.hasnext ()) {Pattern p = pit.next ();            Matcher m = p.matcher (URL); If match found, then caches it to speed up subsequent comparisons if (M.find ()) {This.whiteli                Stcache.put (URL, true);            return true;    }} return false; }
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.