Skip to content

MASTG-DEMO-0079: App Exposing Access and Verification Codes in Text Input Fields

Download MASTG-DEMO-0079 APK Open MASTG-DEMO-0079 Folder Build MASTG-DEMO-0079 APK

Sample

The following sample demonstrates a pair of username and password input fields in Compose.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package org.owasp.mastestapp

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.input.TextObfuscationMode
import androidx.compose.foundation.text.input.rememberTextFieldState
import androidx.compose.material3.SecureTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

const val MASTG_TEXT_TAG = "mastgTestText"

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            MainScreen()
        }
    }
}

@Preview
@Composable
fun MainScreen() {
    BaseScreen {
        Column(modifier = Modifier.padding(vertical = 16.dp)) {
            TextField(
                state = rememberTextFieldState(),
                label = { Text("Username") },
                modifier = Modifier.padding(4.dp)
            )
            SecureTextField(
                state = rememberTextFieldState(),
                textObfuscationMode = TextObfuscationMode.Visible,
                modifier = Modifier.padding(4.dp),
                label = { Text("Visible Password Field") },
            )
        }
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package org.owasp.mastestapp;

import androidx.compose.runtime.Composer;
import androidx.compose.runtime.ComposerKt;
import androidx.compose.runtime.RecomposeScopeImplKt;
import androidx.compose.runtime.ScopeUpdateScope;
import kotlin.Metadata;
import kotlin.Unit;
import kotlin.jvm.functions.Function2;

/* compiled from: MainActivity.kt */
@Metadata(d1 = {"\u0000\u0010\n\u0000\n\u0002\u0010\u000e\n\u0000\n\u0002\u0010\u0002\n\u0002\b\u0002\u001a\r\u0010\u0002\u001a\u00020\u0003H\u0007¢\u0006\u0002\u0010\u0004\"\u000e\u0010\u0000\u001a\u00020\u0001X\u0086T¢\u0006\u0002\n\u0000¨\u0006\u0005"}, d2 = {"MASTG_TEXT_TAG", "", "MainScreen", "", "(Landroidx/compose/runtime/Composer;I)V", "app_debug"}, k = 2, mv = {2, 0, 0}, xi = 48)
/* loaded from: classes3.dex */
public final class MainActivityKt {
    public static final String MASTG_TEXT_TAG = "mastgTestText";

    /* JADX INFO: Access modifiers changed from: private */
    public static final Unit MainScreen$lambda$0(int i, Composer composer, int i2) {
        MainScreen(composer, RecomposeScopeImplKt.updateChangedFlags(i | 1));
        return Unit.INSTANCE;
    }

    public static final void MainScreen(Composer $composer, final int $changed) {
        Composer $composer2 = $composer.startRestartGroup(2010408835);
        ComposerKt.sourceInformation($composer2, "C(MainScreen)34@1094L546:MainActivity.kt#vyvp3i");
        if ($changed != 0 || !$composer2.getSkipping()) {
            BaseScreenKt.BaseScreen(null, ComposableSingletons$MainActivityKt.INSTANCE.m10514getLambda4$app_debug(), $composer2, 48, 1);
        } else {
            $composer2.skipToGroupEnd();
        }
        ScopeUpdateScope scopeUpdateScopeEndRestartGroup = $composer2.endRestartGroup();
        if (scopeUpdateScopeEndRestartGroup != null) {
            scopeUpdateScopeEndRestartGroup.updateScope(new Function2() { // from class: org.owasp.mastestapp.MainActivityKt$$ExternalSyntheticLambda0
                @Override // kotlin.jvm.functions.Function2
                public final Object invoke(Object obj, Object obj2) {
                    return MainActivityKt.MainScreen$lambda$0($changed, (Composer) obj, ((Integer) obj2).intValue());
                }
            });
        }
    }
}
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package org.owasp.mastestapp;

import androidx.compose.foundation.layout.Arrangement;
import androidx.compose.foundation.layout.ColumnKt;
import androidx.compose.foundation.layout.ColumnScopeInstance;
import androidx.compose.foundation.layout.PaddingKt;
import androidx.compose.foundation.text.input.TextFieldStateKt;
import androidx.compose.foundation.text.input.TextObfuscationMode;
import androidx.compose.material3.SecureTextFieldKt;
import androidx.compose.material3.TextFieldKt;
import androidx.compose.material3.TextFieldLabelScope;
import androidx.compose.material3.TextKt;
import androidx.compose.runtime.Applier;
import androidx.compose.runtime.ComposablesKt;
import androidx.compose.runtime.Composer;
import androidx.compose.runtime.ComposerKt;
import androidx.compose.runtime.CompositionLocalMap;
import androidx.compose.runtime.Updater;
import androidx.compose.runtime.internal.ComposableLambdaKt;
import androidx.compose.ui.Alignment;
import androidx.compose.ui.ComposedModifierKt;
import androidx.compose.ui.Modifier;
import androidx.compose.ui.layout.MeasurePolicy;
import androidx.compose.ui.node.ComposeUiNode;
import androidx.compose.ui.unit.Dp;
import kotlin.Metadata;
import kotlin.Unit;
import kotlin.jvm.functions.Function0;
import kotlin.jvm.functions.Function2;
import kotlin.jvm.functions.Function3;
import kotlin.jvm.internal.Intrinsics;

/* compiled from: MainActivity.kt */
@Metadata(k = 3, mv = {2, 0, 0}, xi = 48)
/* loaded from: classes3.dex */
public final class ComposableSingletons$MainActivityKt {
    public static final ComposableSingletons$MainActivityKt INSTANCE = new ComposableSingletons$MainActivityKt();

    /* renamed from: lambda-1, reason: not valid java name */
    public static Function2<Composer, Integer, Unit> f60lambda1 = ComposableLambdaKt.composableLambdaInstance(-1647210896, false, new Function2<Composer, Integer, Unit>() { // from class: org.owasp.mastestapp.ComposableSingletons$MainActivityKt$lambda-1$1
        @Override // kotlin.jvm.functions.Function2
        public /* bridge */ /* synthetic */ Unit invoke(Composer composer, Integer num) {
            invoke(composer, num.intValue());
            return Unit.INSTANCE;
        }

        public final void invoke(Composer $composer, int $changed) {
            ComposerKt.sourceInformation($composer, "C26@1018L12:MainActivity.kt#vyvp3i");
            if (($changed & 11) != 2 || !$composer.getSkipping()) {
                MainActivityKt.MainScreen($composer, 0);
            } else {
                $composer.skipToGroupEnd();
            }
        }
    });

    /* renamed from: lambda-2, reason: not valid java name */
    public static Function3<TextFieldLabelScope, Composer, Integer, Unit> f61lambda2 = ComposableLambdaKt.composableLambdaInstance(-1250832379, false, new Function3<TextFieldLabelScope, Composer, Integer, Unit>() { // from class: org.owasp.mastestapp.ComposableSingletons$MainActivityKt$lambda-2$1
        @Override // kotlin.jvm.functions.Function3
        public /* bridge */ /* synthetic */ Unit invoke(TextFieldLabelScope textFieldLabelScope, Composer composer, Integer num) {
            invoke(textFieldLabelScope, composer, num.intValue());
            return Unit.INSTANCE;
        }

        public final void invoke(TextFieldLabelScope TextField, Composer $composer, int $changed) {
            Intrinsics.checkNotNullParameter(TextField, "$this$TextField");
            ComposerKt.sourceInformation($composer, "C38@1270L16:MainActivity.kt#vyvp3i");
            if (($changed & 81) == 16 && $composer.getSkipping()) {
                $composer.skipToGroupEnd();
            } else {
                TextKt.m3574TextNvy7gAk("Username", null, 0L, null, 0L, null, null, null, 0L, null, null, 0L, 0, false, 0, 0, null, null, $composer, 6, 0, 262142);
            }
        }
    });

    /* renamed from: lambda-3, reason: not valid java name */
    public static Function3<TextFieldLabelScope, Composer, Integer, Unit> f62lambda3 = ComposableLambdaKt.composableLambdaInstance(-278467749, false, new Function3<TextFieldLabelScope, Composer, Integer, Unit>() { // from class: org.owasp.mastestapp.ComposableSingletons$MainActivityKt$lambda-3$1
        @Override // kotlin.jvm.functions.Function3
        public /* bridge */ /* synthetic */ Unit invoke(TextFieldLabelScope textFieldLabelScope, Composer composer, Integer num) {
            invoke(textFieldLabelScope, composer, num.intValue());
            return Unit.INSTANCE;
        }

        public final void invoke(TextFieldLabelScope SecureTextField, Composer $composer, int $changed) {
            Intrinsics.checkNotNullParameter(SecureTextField, "$this$SecureTextField");
            ComposerKt.sourceInformation($composer, "C45@1577L30:MainActivity.kt#vyvp3i");
            if (($changed & 81) == 16 && $composer.getSkipping()) {
                $composer.skipToGroupEnd();
            } else {
                TextKt.m3574TextNvy7gAk("Visible Password Field", null, 0L, null, 0L, null, null, null, 0L, null, null, 0L, 0, false, 0, 0, null, null, $composer, 6, 0, 262142);
            }
        }
    });

    /* renamed from: lambda-4, reason: not valid java name */
    public static Function2<Composer, Integer, Unit> f63lambda4 = ComposableLambdaKt.composableLambdaInstance(2027959928, false, new Function2<Composer, Integer, Unit>() { // from class: org.owasp.mastestapp.ComposableSingletons$MainActivityKt$lambda-4$1
        @Override // kotlin.jvm.functions.Function2
        public /* bridge */ /* synthetic */ Unit invoke(Composer composer, Integer num) {
            invoke(composer, num.intValue());
            return Unit.INSTANCE;
        }

        public final void invoke(Composer $composer, int $changed) {
            ComposerKt.sourceInformation($composer, "C35@1115L519:MainActivity.kt#vyvp3i");
            if (($changed & 11) != 2 || !$composer.getSkipping()) {
                Modifier modifier$iv = PaddingKt.m832paddingVpY3zN4$default(Modifier.Companion, 0.0f, Dp.m8394constructorimpl(16), 1, null);
                ComposerKt.sourceInformationMarkerStart($composer, 1341605231, "CC(Column)N(modifier,verticalArrangement,horizontalAlignment,content)87@4443L61,88@4509L134:Column.kt#2w3rfo");
                Arrangement.Vertical verticalArrangement$iv = Arrangement.INSTANCE.getTop();
                Alignment.Horizontal horizontalAlignment$iv = Alignment.Companion.getStart();
                MeasurePolicy measurePolicy$iv = ColumnKt.columnMeasurePolicy(verticalArrangement$iv, horizontalAlignment$iv, $composer, ((6 >> 3) & 14) | ((6 >> 3) & 112));
                int $changed$iv$iv = (6 << 3) & 112;
                ComposerKt.sourceInformationMarkerStart($composer, -1159599143, "CC(Layout)P(!1,2)80@3267L27,83@3433L360:Layout.kt#80mrfh");
                int compositeKeyHash$iv$iv = Long.hashCode(ComposablesKt.getCurrentCompositeKeyHashCode($composer, 0));
                CompositionLocalMap localMap$iv$iv = $composer.getCurrentCompositionLocalMap();
                Modifier materialized$iv$iv = ComposedModifierKt.materializeModifier($composer, modifier$iv);
                Function0 factory$iv$iv$iv = ComposeUiNode.Companion.getConstructor();
                int $changed$iv$iv$iv = (($changed$iv$iv << 6) & 896) | 6;
                ComposerKt.sourceInformationMarkerStart($composer, -553112988, "CC(ReusableComposeNode)N(factory,update,content)399@15590L9:Composables.kt#9igjgp");
                if (!($composer.getApplier() instanceof Applier)) {
                    ComposablesKt.invalidApplier();
                }
                $composer.startReusableNode();
                if ($composer.getInserting()) {
                    $composer.createNode(factory$iv$iv$iv);
                } else {
                    $composer.useNode();
                }
                Composer $this$Layout_u24lambda_u240$iv$iv = Updater.m4969constructorimpl($composer);
                Updater.m4976setimpl($this$Layout_u24lambda_u240$iv$iv, measurePolicy$iv, ComposeUiNode.Companion.getSetMeasurePolicy());
                Updater.m4976setimpl($this$Layout_u24lambda_u240$iv$iv, localMap$iv$iv, ComposeUiNode.Companion.getSetResolvedCompositionLocals());
                Function2 block$iv$iv$iv = ComposeUiNode.Companion.getSetCompositeKeyHash();
                if ($this$Layout_u24lambda_u240$iv$iv.getInserting() || !Intrinsics.areEqual($this$Layout_u24lambda_u240$iv$iv.rememberedValue(), Integer.valueOf(compositeKeyHash$iv$iv))) {
                    $this$Layout_u24lambda_u240$iv$iv.updateRememberedValue(Integer.valueOf(compositeKeyHash$iv$iv));
                    $this$Layout_u24lambda_u240$iv$iv.apply(Integer.valueOf(compositeKeyHash$iv$iv), block$iv$iv$iv);
                }
                Updater.m4976setimpl($this$Layout_u24lambda_u240$iv$iv, materialized$iv$iv, ComposeUiNode.Companion.getSetModifier());
                int i = ($changed$iv$iv$iv >> 6) & 14;
                ComposerKt.sourceInformationMarkerStart($composer, 2093002350, "C89@4557L9:Column.kt#2w3rfo");
                ColumnScopeInstance columnScopeInstance = ColumnScopeInstance.INSTANCE;
                int i2 = ((6 >> 6) & 112) | 6;
                ComposerKt.sourceInformationMarkerStart($composer, 1992602868, "C37@1218L24,36@1183L170,42@1407L24,41@1366L258:MainActivity.kt#vyvp3i");
                TextFieldKt.TextField(TextFieldStateKt.m1440rememberTextFieldStateLepunE(null, 0L, $composer, 0, 3), PaddingKt.m830padding3ABfNKs(Modifier.Companion, Dp.m8394constructorimpl(4)), false, false, null, null, ComposableSingletons$MainActivityKt.INSTANCE.m10512getLambda2$app_debug(), null, null, null, null, null, null, false, null, null, null, null, null, null, null, null, null, null, null, $composer, 1572912, 0, 0, 33554364);
                SecureTextFieldKt.m3241SecureTextFieldXvU6IwQ(TextFieldStateKt.m1440rememberTextFieldStateLepunE(null, 0L, $composer, 0, 3), PaddingKt.m830padding3ABfNKs(Modifier.Companion, Dp.m8394constructorimpl(4)), false, null, null, ComposableSingletons$MainActivityKt.INSTANCE.m10513getLambda3$app_debug(), null, null, null, null, null, null, false, null, TextObfuscationMode.Companion.m1459getVisiblevTwcZD0(), (char) 0, null, null, null, null, null, null, null, $composer, 196656, 0, 0, 8372188);
                ComposerKt.sourceInformationMarkerEnd($composer);
                ComposerKt.sourceInformationMarkerEnd($composer);
                $composer.endNode();
                ComposerKt.sourceInformationMarkerEnd($composer);
                ComposerKt.sourceInformationMarkerEnd($composer);
                ComposerKt.sourceInformationMarkerEnd($composer);
                return;
            }
            $composer.skipToGroupEnd();
        }
    });

    /* renamed from: getLambda-1$app_debug, reason: not valid java name */
    public final Function2<Composer, Integer, Unit> m10511getLambda1$app_debug() {
        return f60lambda1;
    }

    /* renamed from: getLambda-2$app_debug, reason: not valid java name */
    public final Function3<TextFieldLabelScope, Composer, Integer, Unit> m10512getLambda2$app_debug() {
        return f61lambda2;
    }

    /* renamed from: getLambda-3$app_debug, reason: not valid java name */
    public final Function3<TextFieldLabelScope, Composer, Integer, Unit> m10513getLambda3$app_debug() {
        return f62lambda3;
    }

    /* renamed from: getLambda-4$app_debug, reason: not valid java name */
    public final Function2<Composer, Integer, Unit> m10514getLambda4$app_debug() {
        return f63lambda4;
    }
}

Steps

Let's run our semgrep rule against the Kotlin code.

../../../../rules/mastg-android-input-field-usage.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
rules:
  - id: mastg-android-input-field-usage
    severity: WARNING
    languages:
      - java
    metadata:
      summary: This rule looks for TextFields and SecureTextField.
    message: "[MASVS-PLATFORM] Detected TextFields and SecureTextField."
    pattern-either:
      - pattern: androidx.compose.material3.TextFieldKt
      - pattern-regex: SecureTextFieldKt.m\d+SecureTextField\w+\(.+TextObfuscationMode.Companion.m\d+getVisible\w+\(\).+\);
run.sh
1
NO_COLOR=true semgrep -c ../../../../rules/mastg-android-input-field-usage.yml MainActivityKt_reversed.java ComposableSingletons\$MainActivityKt_reversed.java > output.txt

Observation

The rule detected one instance of SecureTextField and one of TextField.

output.txt
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌─────────────────┐
 2 Code Findings 
└─────────────────┘

    ComposableSingletons$MainActivityKt_reversed.java
    ❯❱ rules.mastg-android-input-field-usage
          [MASVS-PLATFORM] Detected TextFields and SecureTextField.

          142 TextFieldKt.TextField(TextFieldStateKt.m1440rememberTextFieldStateLepunE(null, 0L,        
               $composer, 0, 3), PaddingKt.m830padding3ABfNKs(Modifier.Companion,                        
               Dp.m8394constructorimpl(4)), false, false, null, null,                                    
               ComposableSingletons$MainActivityKt.INSTANCE.m10512getLambda2$app_debug(), null, null,    
               null, null, null, null, false, null, null, null, null, null, null, null, null, null, null,
               null, $composer, 1572912, 0, 0, 33554364);                                                
            ⋮┆----------------------------------------
          143 SecureTextFieldKt.m3241SecureTextFieldXvU6IwQ(TextFieldStateKt.m1440rememberTextFieldStateL
               epunE(null, 0L, $composer, 0, 3), PaddingKt.m830padding3ABfNKs(Modifier.Companion,         
               Dp.m8394constructorimpl(4)), false, null, null,                                            
               ComposableSingletons$MainActivityKt.INSTANCE.m10513getLambda3$app_debug(), null, null,     
               null, null, null, null, false, null,                                                       
               TextObfuscationMode.Companion.m1459getVisiblevTwcZD0(), (char) 0, null, null, null, null,  
               null, null, null, $composer, 196656, 0, 0, 8372188);                                       

Evaluation

After reviewing the decompiled code at the location specified in the output (file and line number), we can conclude that the test fails because the SecureTextField, found in line 143, is used with textObfuscationMode set to TextObfuscationMode.Visible (in Java this appears as SecureTextFieldKt.m3241SecureTextFieldXvU6IwQ(..., TextObfuscationMode.Companion.m1459getVisiblevTwcZD0(),...)).

We also conclude that the TextField instance (line 142) is a false positive, as it's used for a username field and not a password field. We conclude this by trailing back its label parameter, which is set to "Username": its seventh (label) parameter calls m10512getLambda2$app_debug() function, which returns f61lambda2 instance, which in turn creates the Text label composable TextKt.m3574TextNvy7gAk("Username", ....