Android being a client-side platform, developers deal with many different APIs on a daily basis. Some of these APIs are great, some of them not really, but we can work with anything that a backend sends us.
A while ago, we had an atypical request from our backend developers. They asked us to unescape every string in the app.
This meant that the strings from the backend would contain special characters which we needed to replace. For example, & sign would be &, apostrophe would be ' and so on. It was atypical because it’s not often that developers handle such a case in mobile apps. We make an API call and show the string which came from the backend as is.
Why unescape special characters?
Although strange at first, the backend guys had a good reason for this. They were developing a platform which can be used by anyone, not only the Android application.
Other frontend clients could add items to the platform and they didn’t have control over how they would do it. In order to minimize cross-site scripting (XSS) vulnerability, they sanitized strings saved to the backend and they wanted to be sure they don’t send back anything exploitable.
Another reason why you would want to do this is to save the formatting of a string backend sends. If you want to show a multiline string, then you would format the string so it’s shown as expected.
Unescaping special characters for every string
If your backend escapes every string it returns, you need a method to unescape them all in one place. In Android, if you use Moshi, you can do it by defining an application-wide serializer for the String class.
class StringSerializer() : JsonAdapter<String>() {
override fun fromJson(reader: JsonReader): String? {
// Unescape characters
}
@Throws(IOException::class)
override fun toJson(writer: JsonWriter, value: String?) {
// Escape characters or do nothing
}
}
Then add the serializer when defining Moshi.
Moshi.Builder().add(String::class.java, StringSerializer())
If you initialize Moshi in one place and use the same instance across the app all your strings will be unescaped and your work is done.
Unescaping special characters for certain strings
Sometimes, you might need to unescape special characters only for certain strings in the app. If this is your case, you can do this by defining an annotation which will be used only on those strings.
@Retention(AnnotationRetention.RUNTIME)
@JsonQualifier
annotation class Escaped
Then, create a serializer and annotate the fromJson method and toJson parameter.
class EscapedStringSerializer() {
@FromJson
@Escaped
fun fromJson(reader: JsonReader): String {
// Unescape special characters
}
@ToJson
@Throws(IOException::class)
fun toJson(@Escaped value: String?) : String {
// Escape special characters or do nothing
}
}
After defining the annotation and serializer you can annotate any escaped string in your models.
class MyClass (@Escaped @Json(name = "description") val description: String)
Is unescaping for me?
Unless you load strings in a WebView, you probably don’t have a problem with XSS in your Android app.
In most cases, mobile apps get a string from an API and show it in a TextView. However, if you really need to escape strings, it’s good to know you can use one of these two approaches.