Merge "Sanitize VPN label to prevent HTML injection" into rvc-dev
This commit is contained in:
@@ -89,4 +89,32 @@
|
|||||||
without any consequences. [CHAR LIMIT=20] -->
|
without any consequences. [CHAR LIMIT=20] -->
|
||||||
<string name="dismiss">Dismiss</string>
|
<string name="dismiss">Dismiss</string>
|
||||||
|
|
||||||
|
<!-- Malicious VPN apps may provide very long labels or cunning HTML to trick the system dialogs
|
||||||
|
into displaying what they want. The system will attempt to sanitize the label, and if the
|
||||||
|
label is deemed dangerous, then this string is used instead. The first argument is the
|
||||||
|
first 30 characters of the label, and the second argument is the package name of the app.
|
||||||
|
Example : Normally a VPN app may be called "My VPN app" in which case the dialog will read
|
||||||
|
"My VPN app wants to set up a VPN connection...". If the label is very long, then, this
|
||||||
|
will be used to show "VerylongVPNlabel… (com.my.vpn.app) wants to set up a VPN
|
||||||
|
connection...". For this case, the code will refer to sanitized_vpn_label_with_ellipsis.
|
||||||
|
-->
|
||||||
|
<string name="sanitized_vpn_label_with_ellipsis">
|
||||||
|
<xliff:g id="sanitized_vpn_label_with_ellipsis" example="My VPN app">%1$s</xliff:g>… (
|
||||||
|
<xliff:g id="sanitized_vpn_label_with_ellipsis" example="com.my.vpn.app">%2$s</xliff:g>)
|
||||||
|
</string>
|
||||||
|
|
||||||
|
<!-- Malicious VPN apps may provide very long labels or cunning HTML to trick the system dialogs
|
||||||
|
into displaying what they want. The system will attempt to sanitize the label, and if the
|
||||||
|
label is deemed dangerous, then this string is used instead. The first argument is the
|
||||||
|
label, and the second argument is the package name of the app.
|
||||||
|
Example : Normally a VPN app may be called "My VPN app" in which case the dialog will read
|
||||||
|
"My VPN app wants to set up a VPN connection...". If the VPN label contains HTML tag but
|
||||||
|
the length is not very long, the dialog will show "VpnLabelWith<br>HtmlTag
|
||||||
|
(com.my.vpn.app) wants to set up a VPN connection...". For this case, the code will refer
|
||||||
|
to sanitized_vpn_label.
|
||||||
|
-->
|
||||||
|
<string name="sanitized_vpn_label">
|
||||||
|
<xliff:g id="sanitized_vpn_label" example="My VPN app">%1$s</xliff:g> (
|
||||||
|
<xliff:g id="sanitized_vpn_label" example="com.my.vpn.app">%2$s</xliff:g>)
|
||||||
|
</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -44,12 +44,18 @@ public class ConfirmDialog extends AlertActivity
|
|||||||
implements DialogInterface.OnClickListener, ImageGetter {
|
implements DialogInterface.OnClickListener, ImageGetter {
|
||||||
private static final String TAG = "VpnConfirm";
|
private static final String TAG = "VpnConfirm";
|
||||||
|
|
||||||
|
// Usually the label represents the app name, 150 code points might be enough to display the app
|
||||||
|
// name, and 150 code points won't cover the warning message from VpnDialog.
|
||||||
|
static final int MAX_VPN_LABEL_LENGTH = 150;
|
||||||
|
|
||||||
@VpnManager.VpnType private final int mVpnType;
|
@VpnManager.VpnType private final int mVpnType;
|
||||||
|
|
||||||
private String mPackage;
|
private String mPackage;
|
||||||
|
|
||||||
private IConnectivityManager mService;
|
private IConnectivityManager mService;
|
||||||
|
|
||||||
|
private View mView;
|
||||||
|
|
||||||
public ConfirmDialog() {
|
public ConfirmDialog() {
|
||||||
this(VpnManager.TYPE_VPN_SERVICE);
|
this(VpnManager.TYPE_VPN_SERVICE);
|
||||||
}
|
}
|
||||||
@@ -58,6 +64,42 @@ public class ConfirmDialog extends AlertActivity
|
|||||||
mVpnType = vpnType;
|
mVpnType = vpnType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will use the string resource to combine the VPN label and the package name.
|
||||||
|
*
|
||||||
|
* If the VPN label violates the length restriction, the first 30 code points of VPN label and
|
||||||
|
* the package name will be returned. Or return the VPN label and the package name directly if
|
||||||
|
* the VPN label doesn't violate the length restriction.
|
||||||
|
*
|
||||||
|
* The result will be something like,
|
||||||
|
* - ThisIsAVeryLongVpnAppNameWhich... (com.vpn.app)
|
||||||
|
* if the VPN label violates the length restriction.
|
||||||
|
* or
|
||||||
|
* - VpnLabelWith<br>HtmlTag (com.vpn.app)
|
||||||
|
* if the VPN label doesn't violate the length restriction.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private String getSimplifiedLabel(String vpnLabel, String packageName) {
|
||||||
|
if (vpnLabel.codePointCount(0, vpnLabel.length()) > 30) {
|
||||||
|
return getString(R.string.sanitized_vpn_label_with_ellipsis,
|
||||||
|
vpnLabel.substring(0, vpnLabel.offsetByCodePoints(0, 30)),
|
||||||
|
packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return getString(R.string.sanitized_vpn_label, vpnLabel, packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getSanitizedVpnLabel(String vpnLabel, String packageName) {
|
||||||
|
final String sanitizedVpnLabel = Html.escapeHtml(vpnLabel);
|
||||||
|
final boolean exceedMaxVpnLabelLength = sanitizedVpnLabel.codePointCount(0,
|
||||||
|
sanitizedVpnLabel.length()) > MAX_VPN_LABEL_LENGTH;
|
||||||
|
if (exceedMaxVpnLabelLength || !vpnLabel.equals(sanitizedVpnLabel)) {
|
||||||
|
return getSimplifiedLabel(sanitizedVpnLabel, packageName);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sanitizedVpnLabel;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
@@ -80,15 +122,16 @@ public class ConfirmDialog extends AlertActivity
|
|||||||
finish();
|
finish();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
View view = View.inflate(this, R.layout.confirm, null);
|
mView = View.inflate(this, R.layout.confirm, null);
|
||||||
((TextView) view.findViewById(R.id.warning)).setText(
|
((TextView) mView.findViewById(R.id.warning)).setText(
|
||||||
Html.fromHtml(getString(R.string.warning, getVpnLabel()),
|
Html.fromHtml(getString(R.string.warning, getSanitizedVpnLabel(
|
||||||
this, null /* tagHandler */));
|
getVpnLabel().toString(), mPackage)),
|
||||||
|
this /* imageGetter */, null /* tagHandler */));
|
||||||
mAlertParams.mTitle = getText(R.string.prompt);
|
mAlertParams.mTitle = getText(R.string.prompt);
|
||||||
mAlertParams.mPositiveButtonText = getText(android.R.string.ok);
|
mAlertParams.mPositiveButtonText = getText(android.R.string.ok);
|
||||||
mAlertParams.mPositiveButtonListener = this;
|
mAlertParams.mPositiveButtonListener = this;
|
||||||
mAlertParams.mNegativeButtonText = getText(android.R.string.cancel);
|
mAlertParams.mNegativeButtonText = getText(android.R.string.cancel);
|
||||||
mAlertParams.mView = view;
|
mAlertParams.mView = mView;
|
||||||
setupAlert();
|
setupAlert();
|
||||||
|
|
||||||
getWindow().setCloseOnTouchOutside(false);
|
getWindow().setCloseOnTouchOutside(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user