-
Notifications
You must be signed in to change notification settings - Fork 760
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
StrandHogg detection #4498
StrandHogg detection #4498
Conversation
00bed50
to
a3b4c31
Compare
vector/src/main/AndroidManifest.xml
Outdated
<activity android:name=".features.home.HomeActivity" /> | ||
<activity | ||
android:name=".features.home.HomeActivity" | ||
android:launchMode="singleTask" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried adding singleTask
to this activity for a deeplink issue and it caused a bunch of odd behaviours (skipping deeplinks, activity not fully loading), have you noticed anything strange after the change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't see any problem on HomeActivity after this change but I didn't stress it. I would prefer to make more tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, clicking on a link like https://app.element.io/#/room/%23element-web-announcements:matrix.org
creates 2 tasks if Element was already running, so we can see in the task switcher:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this a blocker for the fix? maybe singleTop
could provide similar protection without allowing multiple instances
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No more needed to change launchMode since we generate a random task affinity on each build.
@@ -42,5 +58,81 @@ class VectorActivityLifecycleCallbacks constructor(private val popupAlertManager | |||
} | |||
|
|||
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) { | |||
// restart the app if the task contains an unknown activity | |||
if (isTaskCorrupted(activity)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be interesting to know if there's a performance impact for this, might be worth making the check async to avoid slowing down the activity start flow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -520,7 +521,16 @@ class HomeActivity : | |||
if (views.drawerLayout.isDrawerOpen(GravityCompat.START)) { | |||
views.drawerLayout.closeDrawer(GravityCompat.START) | |||
} else { | |||
super.onBackPressed() | |||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R && supportFragmentManager.backStackEntryCount == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like we could extract this logic to reduce the duplication, either extension or base class function
something like
if (views.drawerLayout.isDrawerOpen(GravityCompat.START)) {
views.drawerLayout.closeDrawer(GravityCompat.START)
} else {
validateBackPressed { super.onBackPressed() }
}
...
fun Activity.validateBackPressed(onBackPressed: () -> Unit) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R && supportFragmentManager.backStackEntryCount == 0) {
if (isTaskRoot) {
onBackPressed()
} else {
Timber.e("Application is potentially corrupted by an unknown activity")
finishAffinity()
}
} else {
onBackPressed()
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://github.com/vector-im/element-android/pull/4498/files#r754454956
It's worth noting that the app seems robust to the StrandHogg vulnerability with the fix. I have the error log when I try the attack.
a3b4c31
to
e454fab
Compare
Matrix SDKIntegration Tests Results:
|
a08946e
to
11c5769
Compare
11c5769
to
647e22c
Compare
vector/src/main/java/im/vector/app/features/lifecycle/VectorActivityLifecycleCallbacks.kt
Outdated
Show resolved
Hide resolved
@@ -114,6 +116,19 @@ fun AppCompatActivity.hideKeyboard() { | |||
currentFocus?.hideKeyboard() | |||
} | |||
|
|||
fun AppCompatActivity.validateBackPressed(onBackPressed: () -> Unit) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add documentation to explain that this should be only used for top-level activities. A developer which is not aware of this could think that it's a good practice to use it for all activities.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Funny: I had the same mental path "A developer which is not aware of this could think that it's a good practice to use it for all activities". And now I see this comment in GitHub, and the comment in the code :)
d29f58d
to
885a861
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add the suffix to the taskAffinity of VectorCallActivity
?
vector/build.gradle
Outdated
|
||
return alphaCharset[rnd.nextInt(alphaCharset.length())] + | ||
rnd.with { | ||
(1..7).collect { alphaNumCharset[nextInt(alphaNumCharset.length())] }.join() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe using 8 chars in [a-z] is enough :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
vector/build.gradle
Outdated
@@ -91,6 +91,17 @@ static def getFdroidVersionSuffix() { | |||
} | |||
} | |||
|
|||
static def getTaskAffinitySuffix() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rename to generateTaskAffinitySuffix
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
vector/build.gradle
Outdated
@@ -131,6 +136,9 @@ android { | |||
// Required for sonar analysis | |||
versionName "${versionMajor}.${versionMinor}.${versionPatch}-sonar" | |||
|
|||
// Generate a random app task affinity | |||
manifestPlaceholders = [appTaskAffinitySuffix:"${generateTaskAffinitySuffix()}"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a blocker since we're not using the build cache, wanted to highlight generating new values on each build/gradle configuration cycle may cause some of the android gradle tasks to become non cachable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, something else I did not think about.
We want to have stable builds, i.e. the same code generates the same binary (related: #842, and context in element-hq/riot-android#3131). It's important for F-Droid.
With this change it will not be the case anymore.
I have not idea how to handle that now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we use the short git hash for the suffix? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should propably compute the task affinity suffix from tags or commit hash ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could we use the short git hash for the suffix? 🤔
We can't use it as is. taskAffinity has same format as namespace :
- It must have at least two segments (one or more dots).
- Each segment must start with a letter.
- All characters must be alphanumeric or an underscore [a-zA-Z0-9_].
https://developer.android.com/studio/build/configure-app-module#set-application-id
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we could use the git hash as a seed for the random()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea to compute a suffix using git hash and just remove forbidden chars (but is there any?).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So many having a appTaskAffinitySuffix
like a${git_hash_8_digits}
with a a
prefix to ensure it's always starting with a letter would fit all our needs. WDYT @yostyle ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already have gitRevision
. I'm going to reuse it.
feab80d
to
a12f9b7
Compare
a12f9b7
to
e9814ee
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update. As per my test, it's working well.
I will squash commits to clean up the history of this branch.
* develop: (392 commits) Missing import of at-Ignore annotation. FTUE - Choose a display picture (#5323) Ignore ThreadMessagingTest as it seems to cause other integration tests to fail. Maybe the file is here? I give up for the weekend Frustration at artifact handling vs what's in docs. Update the top bar in a room (#5213) Tweak upload/download of codecov xml file Address review points from adam Remove unneeded code, retaining a comment for how to exclude certain projects Merge pull request #5405 from vector-im/cgizard/ISSUE-5402 Remove the printing of file name to the log as it's doubling up information. Remove exclusions (for now). Fix typo in name of action giving avatar/display name error dialogs human readable error messages - reuses the ErrorDialog logic which translates exceptions to human readable strings Run codecoverage and pass to sonarqube upload for processing. Better codecov based on ouchadam's suggestion Correct name of environment variable Use environment variable that is tied to project property Merge pull request #4498 from vector-im/yostyle/fix_strandhogg ... # Conflicts: # vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt
No description provided.