aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2019-08-13 23:57:52 -0700
committerGitHub <noreply@github.com>2019-08-13 23:57:52 -0700
commite47d5d47c0997b9a696f4f8881f4a057e2a5f934 (patch)
treeac985d192580735c34e31fa0583e60ecaf54a147
parentb47900cbf82cdb216f7e3bd7961d29b7f6e1e507 (diff)
parentda3f1bb99df7f75e6adc62aa8aae15716033789b (diff)
downloadfrost-e47d5d47c0997b9a696f4f8881f4a057e2a5f934.tar.gz
frost-e47d5d47c0997b9a696f4f8881f4a057e2a5f934.tar.bz2
frost-e47d5d47c0997b9a696f4f8881f4a057e2a5f934.zip
Merge pull request #1514 from AllanWang/theopensourceguy-native-toggle
Tag obfuscation
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt37
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt7
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt7
-rw-r--r--app/src/main/res/values/strings_pref_behaviour.xml5
-rw-r--r--app/src/main/res/values/strings_pref_experimental.xml6
-rw-r--r--app/src/main/res/xml/frost_changelog.xml2
-rw-r--r--app/src/test/kotlin/com/pitchedapps/frost/injectors/TagObfuscatorTest.kt22
7 files changed, 71 insertions, 15 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
index 13032479..eed2f819 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsInjector.kt
@@ -17,9 +17,11 @@
package com.pitchedapps.frost.injectors
import android.webkit.WebView
+import androidx.annotation.VisibleForTesting
+import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.web.FrostWebViewClient
import org.apache.commons.text.StringEscapeUtils
-import java.util.Locale
+import kotlin.random.Random
class JsBuilder {
private val css = StringBuilder()
@@ -38,7 +40,7 @@ class JsBuilder {
}
fun single(tag: String): JsBuilder {
- this.tag = "_frost_${tag.toLowerCase(Locale.CANADA)}"
+ this.tag = TagObfuscator.obfuscateTag(tag)
return this
}
@@ -106,4 +108,35 @@ fun FrostWebViewClient.jsInject(vararg injectors: InjectorContract) = web.jsInje
class JsInjector(val function: String) : InjectorContract {
override fun inject(webView: WebView) =
webView.evaluateJavascript(function, null)
+}
+
+/**
+ * Helper object to obfuscate window tags for JS injection.
+ */
+@VisibleForTesting
+internal object TagObfuscator {
+
+ fun obfuscateTag(tag: String): String {
+ val rnd = Random(tag.hashCode() + salt)
+ val obfuscated = buildString {
+ append(prefix)
+ append('_')
+ appendRandomChars(rnd, 16)
+ }
+ L.v { "TagObfuscator: Obfuscating tag '$tag' to '$obfuscated'" }
+ return obfuscated
+ }
+
+ private val salt: Long = System.currentTimeMillis()
+
+ private val prefix: String by lazy {
+ val rnd = Random(System.currentTimeMillis())
+ buildString { appendRandomChars(rnd, 8) }
+ }
+
+ private fun Appendable.appendRandomChars(random: Random, count: Int) {
+ for (i in 1..count) {
+ append('a' + random.nextInt(26))
+ }
+ }
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt
index 1ab53a56..ba5b839b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Behaviour.kt
@@ -83,13 +83,6 @@ fun SettingsActivity.getBehaviourPrefs(): KPrefAdapterBuilder.() -> Unit = {
descRes = R.string.exit_confirmation_desc
}
- checkbox(R.string.web_only, Prefs::webOnly, {
- Prefs.webOnly = it
- shouldRestartMain()
- }) {
- descRes = R.string.web_only_desc
- }
-
checkbox(R.string.analytics, Prefs::analytics, { Prefs.analytics = it }) {
descRes = R.string.analytics_desc
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
index 7aac7526..d0963665 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/settings/Experimental.kt
@@ -43,6 +43,13 @@ fun SettingsActivity.getExperimentalPrefs(): KPrefAdapterBuilder.() -> Unit = {
// Experimental content starts here ------------------
+ checkbox(R.string.web_only, Prefs::webOnly, {
+ Prefs.webOnly = it
+ shouldRestartMain()
+ }) {
+ descRes = R.string.web_only_desc
+ }
+
// Experimental content ends here --------------------
checkbox(R.string.verbose_logging, Prefs::verboseLogging, {
diff --git a/app/src/main/res/values/strings_pref_behaviour.xml b/app/src/main/res/values/strings_pref_behaviour.xml
index d7043aa7..32188698 100644
--- a/app/src/main/res/values/strings_pref_behaviour.xml
+++ b/app/src/main/res/values/strings_pref_behaviour.xml
@@ -19,11 +19,6 @@
<string name="force_message_bottom_desc">When loading a message thread, trigger a scroll to the bottom of the page rather than loading the page as is.</string>
<string name="enable_pip">Enable PIP</string>
<string name="enable_pip_desc">Enable picture in picture videos</string>
- <!-- Disable translation as this is still experimental -->
- <string name="web_only" translatable="false">Web Only</string>
- <string name="web_only_desc" translatable="false">Having troubles? Enable to use web exclusive features. All parsing and background services will be disabled.</string>
- <string name="leave_web_only_title" translatable="false">Leave web only mode</string>
- <string name="leave_web_only_desc" translatable="false">Currently in web only mode. Would you like to disable it to continue?</string>
<string name="autoplay_settings">Autoplay Settings</string>
<string name="autoplay_settings_desc">Open Facebook\'s auto play settings. Note that it must be disabled for PIP to work.</string>
<string name="exit_confirmation">Exit Confirmation</string>
diff --git a/app/src/main/res/values/strings_pref_experimental.xml b/app/src/main/res/values/strings_pref_experimental.xml
index 95d54ff2..fad29ff6 100644
--- a/app/src/main/res/values/strings_pref_experimental.xml
+++ b/app/src/main/res/values/strings_pref_experimental.xml
@@ -8,4 +8,10 @@
<string name="verbose_logging_desc">Enable verbose logging to help with crash reports. Logging will only be sent once an error is encountered, so repeat the issue to notify the dev. This will automatically be disabled if the app restarts.</string>
<string name="restart_frost">Restart Frost</string>
<string name="restart_frost_desc">Launch a cold restart for the application.</string>
+
+ <!-- Debugging phishing warnings -->
+ <string name="web_only" translatable="false">Web Only</string>
+ <string name="web_only_desc" translatable="false">Having troubles? Enable to use web exclusive features. All parsing and background services will be disabled.</string>
+ <string name="leave_web_only_title" translatable="false">Leave web only mode</string>
+ <string name="leave_web_only_desc" translatable="false">Currently in web only mode. Would you like to disable it to continue?</string>
</resources> \ No newline at end of file
diff --git a/app/src/main/res/xml/frost_changelog.xml b/app/src/main/res/xml/frost_changelog.xml
index 3c576a9e..6494fdd1 100644
--- a/app/src/main/res/xml/frost_changelog.xml
+++ b/app/src/main/res/xml/frost_changelog.xml
@@ -13,7 +13,7 @@
<item text="Disable bugsnag completely when opting out of analytics" />
<item text="Filter urls before sending to other apps" />
<item text="Allow hiding main fab (see settings > newsfeed)" />
- <item text="Add option to disable non web based behaviour (settings > behaviour)" />
+ <item text="Add some experimental options to debug login problems (settings > experimental)" />
<item text="" />
<version title="v2.3.1" />
diff --git a/app/src/test/kotlin/com/pitchedapps/frost/injectors/TagObfuscatorTest.kt b/app/src/test/kotlin/com/pitchedapps/frost/injectors/TagObfuscatorTest.kt
new file mode 100644
index 00000000..5c316a4a
--- /dev/null
+++ b/app/src/test/kotlin/com/pitchedapps/frost/injectors/TagObfuscatorTest.kt
@@ -0,0 +1,22 @@
+package com.pitchedapps.frost.injectors
+
+import java.util.UUID
+import kotlin.test.Test
+import kotlin.test.assertEquals
+
+class TagObfuscatorTest {
+
+ /**
+ * The same key should result in the same tag per session
+ */
+ @Test
+ fun consistentTags() {
+ val keys = generateSequence { UUID.randomUUID().toString() }.take(10).toSet()
+ val tags = keys.map {
+ val tag = generateSequence { TagObfuscator.obfuscateTag(it) }.take(10).toSet()
+ assertEquals(1, tag.size, "Key $it produced multiple tags: $tag")
+ tag.first()
+ }
+ assertEquals(keys.size, tags.size, "Key set and tag set have different sizes")
+ }
+}