diff options
author | Allan Wang <me@allanwang.ca> | 2019-08-15 22:08:57 -0700 |
---|---|---|
committer | Allan Wang <me@allanwang.ca> | 2019-08-15 22:08:57 -0700 |
commit | 39d07d946b753f197d200fa07792670e37435a95 (patch) | |
tree | 56444cfe379a491e14db26608dd7c4572aedad55 | |
parent | f12762c4175e37a6f887ca17a07ddb4fc7508849 (diff) | |
parent | e47d5d47c0997b9a696f4f8881f4a057e2a5f934 (diff) | |
download | frost-39d07d946b753f197d200fa07792670e37435a95.tar.gz frost-39d07d946b753f197d200fa07792670e37435a95.tar.bz2 frost-39d07d946b753f197d200fa07792670e37435a95.zip |
Merge obfuscator
7 files changed, 87 insertions, 14 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 40e3827c..3416c420 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 } @@ -107,3 +109,34 @@ 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)) + } + } +} 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 5ca0bd74..6142f595 100644 --- a/app/src/main/res/xml/frost_changelog.xml +++ b/app/src/main/res/xml/frost_changelog.xml @@ -15,6 +15,7 @@ <item text="Allow hiding main fab (see settings > newsfeed)" /> <item text="Add some experimental options to debug login problems (settings > experimental)" /> <item text="Enforce desktop user agent for now" /> + <item text="Obfuscate js tags" /> <version title="v2.3.1" /> <item text="Hide all story panels if enabled" /> 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..e7145e39 --- /dev/null +++ b/app/src/test/kotlin/com/pitchedapps/frost/injectors/TagObfuscatorTest.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2019 Allan Wang + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +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") + } +} |