diff options
| author | 2023-03-20 09:13:45 +0000 | |
|---|---|---|
| committer | 2023-03-20 09:13:45 +0000 | |
| commit | fb8a2bf711d6597c9952a246c2ca8f906d7aedcc (patch) | |
| tree | cabf1a22120a623d35f5837bac1a16b9f0fbf385 | |
| parent | cd801e3f19f4ed1455d5a293e81d79313dbc4716 (diff) | |
| parent | 1d32ff85a491ec983d03401eb752fe679b694d31 (diff) | |
Merge "Sanitize VPN label to prevent HTML injection" into rvc-dev am: 230c7ab574 am: 749b03d2e6 am: f39900d8b2 am: 92a9270571 am: 00b4d82125 am: 1d32ff85a4
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20460002
Change-Id: I59577cf69813a84579d78c97b4483ccc4e8fd665
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
| -rw-r--r-- | packages/VpnDialogs/res/values/strings.xml | 28 | ||||
| -rw-r--r-- | packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java | 53 |
2 files changed, 76 insertions, 5 deletions
diff --git a/packages/VpnDialogs/res/values/strings.xml b/packages/VpnDialogs/res/values/strings.xml index f971a0916837..a85b8e4ff553 100644 --- a/packages/VpnDialogs/res/values/strings.xml +++ b/packages/VpnDialogs/res/values/strings.xml @@ -100,4 +100,32 @@ without any consequences. [CHAR LIMIT=20] --> <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> diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java index fb2367843fc1..2b3202e0a982 100644 --- a/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java +++ b/packages/VpnDialogs/src/com/android/vpndialogs/ConfirmDialog.java @@ -40,12 +40,18 @@ public class ConfirmDialog extends AlertActivity implements DialogInterface.OnClickListener, ImageGetter { 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; private String mPackage; private VpnManager mVm; + private View mView; + public ConfirmDialog() { this(VpnManager.TYPE_VPN_SERVICE); } @@ -54,6 +60,42 @@ public class ConfirmDialog extends AlertActivity 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 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -75,15 +117,16 @@ public class ConfirmDialog extends AlertActivity finish(); return; } - View view = View.inflate(this, R.layout.confirm, null); - ((TextView) view.findViewById(R.id.warning)).setText( - Html.fromHtml(getString(R.string.warning, getVpnLabel()), - this, null /* tagHandler */)); + mView = View.inflate(this, R.layout.confirm, null); + ((TextView) mView.findViewById(R.id.warning)).setText( + Html.fromHtml(getString(R.string.warning, getSanitizedVpnLabel( + getVpnLabel().toString(), mPackage)), + this /* imageGetter */, null /* tagHandler */)); mAlertParams.mTitle = getText(R.string.prompt); mAlertParams.mPositiveButtonText = getText(android.R.string.ok); mAlertParams.mPositiveButtonListener = this; mAlertParams.mNegativeButtonText = getText(android.R.string.cancel); - mAlertParams.mView = view; + mAlertParams.mView = mView; setupAlert(); getWindow().setCloseOnTouchOutside(false); |