Output encoding can be utilized to protect against these cross-site scripting attacks. Output encoding functions by converting all untrusted input into a safe form where the untrusted input can be displayed as data to the end-user, but not be executed as code. One technique that can be utilized in implementing output encoding is HTML encoding. Malicious scripts can be stored in a database and not be executed until they are retrieved by the end-user. This kind of incubated attack can sit dormant for extended periods of time until the end-user views a web page that the malicious script was injected into. When this occurs, the incubating script will activate and then execute. Such scripts, that take advantage of HTML security vulnerabilities, can be prevented from ever executing by implementing HTML encoding. HTML encoding functions by taking the variable output and encoding them, by replacing certain special characters, such as < and >, with a set of pre-defined alternative representations called entities, such as < and %gt;. After end user’s web browser encounters these entities, it will convert the encoded variable output back into the original HTML and print it on the end user’s screen, however, the script will not be run.
Create a new Android Studio project and name it “OutputEncoding” and click Next.
File->New-> New Project->Select Basic Activity->Click Next
Create a new Android Studio project and name it “OutputEncoding” with the company domain of "com.example" and click on Next
Copy and paste the following code into “MainActivity.java” and "Other Pages"
//Copy and paste the following code into “MainActivity.java”.
//MainActivity.java
package com.ksu.outputencoding;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.TextView;
import android.text.TextUtils;
public class MainActivity extends AppCompatActivity {
TextView textView;
TextView encoded;
Button unsecure;
Button secure;
Button encodedResult;
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
encoded = (TextView) findViewById(R.id.textView2);
unsecure = (Button) findViewById(R.id.button);
secure = (Button) findViewById(R.id.button2);
encodedResult = (Button) findViewById(R.id.button3);
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
String script = "Demostrating the consequences of the script:\n<script>alert(\"You have been attacked!\")</script>";
String html = "<html><body>" + script + "</body></html>";
textView.setText(script);
unsecure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
webView.setWebChromeClient(new WebChromeClient());
webView.setVisibility(View.VISIBLE);
webView.loadUrl("file:///android_asset/unsecure.html");
encoded.setText("");
}
});
secure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String secureHTML = "<html><head><title>Secure</title></head><body><h1> Hello "+TextUtils.htmlEncode("<script>alert(\"You have been attacked!\")</script>")+"!</h1></body></html>";
webView.setWebChromeClient(new WebChromeClient());
webView.setVisibility(View.VISIBLE);
webView.loadDataWithBaseURL(null, secureHTML, "text/html", "utf-8", null);
encoded.setText("");
}
});
encodedResult.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
encoded.setText(TextUtils.htmlEncode("<script>alert(\"You have been attacked!\")</script>"));
webView.setVisibility(View.GONE);
webView.loadData("","text/html", null);
}
});
}
}
//Next Copy the following code into “AndroidManifest.xml”.
//AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ksu.outputencoding">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.OutputEncoding">
<activity android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
//Copy the following code into “activity_main.xml”.
//activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.ksu.outputencoding.MainActivity">
<TextView
android:text="Demostrating the consequences of the script:"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="@+id/textView" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/textView"
android:id="@+id/linearLayout">
<Button
android:text="Unsecure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button"
android:layout_below="@+id/linearLayout"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:text="Encode!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/linearLayout"
android:layout_toRightOf="@+id/button"
android:layout_toEndOf="@+id/button"
android:id="@+id/button2" />
<Button
android:text="Encoded Result!"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/linearLayout"
android:layout_toRightOf="@+id/button2"
android:layout_toEndOf="@+id/button2"
android:id="@+id/button3" />
</LinearLayout>
<WebView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/linearLayout"
android:id="@+id/webView"
>
</WebView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/webView"
android:id="@+id/textView2" />
</RelativeLayout>
Note: When you run "Analyze Scope Files" sometimes the following Error would be initiated so you need to eliminate this error to get result in FindBugs Security issue in this project.