Skip to content

SettingsServerAboutFragment passes null baseUrl to loadDataWithBaseURL while rendering server-controlled HTML with JS enabled #1093

@jim-daf

Description

@jim-daf

SettingsServerAboutFragment renders the server's extended description in a WebView with setJavaScriptEnabled(true):

webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new WebViewClient(){
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url){
        Uri uri=Uri.parse(url);
        if(uri.getScheme().equals("http") || uri.getScheme().equals("https")){
            UiUtils.launchWebBrowser(getActivity(), url);
        }else{
            Intent intent=new Intent(Intent.ACTION_VIEW, uri);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            try{
                startActivity(intent);
            }catch(ActivityNotFoundException x){
                ...
            }
        }
        return true;
    }
});

The HTML is built from the server's extended_description (see GetInstanceExtendedDescription.Response#content) and rendered with:

webView.loadDataWithBaseURL(null, html, "text/html; charset=utf-8", null, null);

The extended_description field is text the server admin writes, so it is effectively first-party content from the server, but it is content the user did not author. With null as the baseUrl the rendered page has an opaque about:blank origin. Any link or window.open call inside that HTML inherits the same origin and reaches the shouldOverrideUrlLoading handler, which routes non-http schemes (intent:, market:, mailto:, sms:, etc.) to Intent.ACTION_VIEW without an explicit allow-list.

The closest CWE mapping is CWE-79 on the bridge-less surface: a server admin who wants to be hostile can ship HTML that triggers external intents without the user seeing any URL bar.

Suggested fix

Pass the account's instance domain as an https baseUrl:

final String baseUrl="https://"+AccountSessionManager.get(accountID).domain+"/";
webView.loadDataWithBaseURL(baseUrl, html, "text/html; charset=utf-8", null, null);

This gives the rendered page a deterministic origin tied to the server that produced the HTML. The description renders the same way it did before. A subsequent change can add an explicit scheme allow-list inside shouldOverrideUrlLoading, but the baseUrl swap alone is the minimum step from C01 of the WebView posture notes.

A PR is open at #1094.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions