Repository: flutter
Issue: Hidden text field messages not sanitized, and are visible in memory dump.
Labels: c: new feature,engine,has reproducible steps,P3,found in release: 2.2,found in release: 2.3,team-engine,triaged-engine

<!-- Thank you for using Flutter!

     If you are looking for support, please check out our documentation
     or consider asking a question on Stack Overflow:
      * https://flutter.dev/
      * https://api.flutter.dev/
      * https://stackoverflow.com/questions/tagged/flutter?sort=frequent

     If you have found a performance problem, then fill out the template below.
     Please read our guide to filing a bug first: https://flutter.dev/docs/resources/bug-reports
-->

## Details
I have created a Linux application having login form on which clicking the login button the dio netowrk request is made and the current page is route to another page with pushReplacement. But when I take memory dump of the process there I can see the entered password is visible in the dump file.



**Target Platform:** Ubuntu 18.04.1
**Target Kernel version:**  5.4.0-42-generic

## Basic application code

<details> 
<summary>code snippet</summary> 

```dart
@override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        if (Navigator.of(context).userGestureInProgress) {
          return false;
        } else {
          return true;
        }
      },
      child: Scaffold(
        appBar: AppBar(
          backgroundColor: Colors.white,
          elevation: 1,
          centerTitle: true,
          title: Text(
            "Login",
            style: TextStyle(color: Colors.black),
          ),
          leading: Icon(
            Icons.arrow_back,
            color: Colors.transparent,
          ),
        ),
        body: Center(
          child: Card(
            elevation: 8.0,
            child: Container(
              width: 600,
              height: 600,
              child: SingleChildScrollView(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.center,
                  children: <Widget>[
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        Container(
                          width: 140,
                          child: Text(
                            "Username : ",
                            style: TextStyle(color: Colors.grey),
                          ),
                        ),
                        SizedBox(
                          width: 16.0,
                        ),
                        Container(
                          decoration: BoxDecoration(
                            border: Border(
                                bottom: BorderSide(
                              color: Colors.grey,
                            )),
                          ),
                          width: 260,
                          key: usernameKey,
                          padding: EdgeInsets.all(8),
                          child: TextField(
                            controller: usernameController,
                            keyboardType: TextInputType.text,
                            style:TextStyle(fontSize: 16.0, color: Colors.black),
                            decoration: InputDecoration(
                                border: InputBorder.none,
                                hintText: "Enter username",
                                hintStyle: TextStyle(fontSize: 18.0)),
                            
                            onSubmitted: (text) {
                              fetchUpdateDetails();         
                            },
                          ),
                        ),
                        SizedBox(
                          width: 16.0,
                        ),
                        SizedBox(
                          width: 32,
                        ),
                      ],
                    ),
                    SizedBox(
                      height: 16,
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        Container(
                          width: 140,
                          child: Text(
                            "Password : ",
                            style: TextStyle(color: Colors.grey),
                          ),
                        ),
                        SizedBox(
                          width: 16.0,
                        ),
                        Stack(
                          children: [
                            Container(
                              decoration: BoxDecoration(
                                border: Border(
                                  bottom: BorderSide(
                                    color: Colors.grey,
                                  ),
                                ),
                              ),
                              width: 260,
                              key: passwordKey,
                              padding: EdgeInsets.all(8),
                              child: TextField(
                                obscureText: true,
                                onChanged: (String new_val) {
                                  String newPass = "";
                                  for (int i = 0; i < new_val.length; i++) {
                                    newPass += "\u2022";
                                  }
                                  setState(() {
                                    this.passwordToShow = newPass;
                                    this.actualPassword = new_val;
                                  });
                                },
                                controller: passwordController,
                                keyboardType: TextInputType.text,
                                
                                textAlign: TextAlign.left,
                                onSubmitted: (String text) {
                                  fetchUpdateDetails();
                                },
                                style: TextStyle(
                                    fontSize: 16.0, color: Colors.transparent),
                                decoration: InputDecoration(
                                  border: InputBorder.none,
                                  hintText: "Enter password",
                                  hintStyle: TextStyle(fontSize: 18.0),
                                ),
                              ),
                            ),
                            Positioned(
                              top: 24,
                              left: 8,
                              child: Text(
                                "${passwordToShow}",
                                style: TextStyle(fontSize: 16),
                              ),
                            )
                          ],
                        ),
                        SizedBox(
                          width: 16.0,
                        ),
                      ],
                    ),
                    SizedBox(
                      height: 16,
                    ),
                    Row(
                      mainAxisAlignment: MainAxisAlignment.center,
                      crossAxisAlignment: CrossAxisAlignment.center,
                      children: <Widget>[
                        RaisedButton(
                          child: Text("LOGIN"),
                          onPressed: () {
                            loginUser();
                          },
                        ),
                      ],
                    ),
                    SizedBox(
                      height: 16,
                    ),
                  ],
                ),
              ),
            ),
          ),
        ),
      ),
    );
    
  }
```

</details>

Here loginUser() will make a dio network request and on response it will route to next page using pushReplacement. And before routing to next page i have made all the string(string which stored password or username) to null.

And i have disposed all TextEditingController.

## Script used to take memory dump
```console
#!/bin/bash

grep rw-p /proc/$1/maps \
| sed -n 's/^\([0-9a-f]*\)-\([0-9a-f]*\) .*$/\1 \2/p' \
| while read start stop; do \
    gdb --batch --pid $1 -ex \
        "dump memory $1-$start-$stop.dump 0x$start 0x$stop"; \
done
```
Run scipt by ./shript.sh [pid of application]



## Flutter doctor -v

<details> 
<summary>flutter doctor -v</summary> 
	
```console
[✓] Flutter (Channel unknown, 2.0.3, on Linux, locale en_IN)
    • Flutter version 2.0.3 at /home/shivam/flut/flutter
    • Framework revision 4d7946a68d (3 months ago), 2021-03-18 17:24:33 -0700
    • Engine revision 3459eb2436
    • Dart version 2.12.2

[!] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    • Android SDK at /usr/lib/android-sdk
    ✗ Flutter requires Android SDK 29 and the Android BuildTools 28.0.3
      To update the Android SDK visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions.
    ! Some Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses

[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
    • clang version 6.0.0-1ubuntu2 (tags/RELEASE_600/final)
    • cmake version 3.10.2
    • ninja version 1.8.2
    • pkg-config version 0.29.1

[!] Android Studio (not installed)
    • Android Studio not found; download from https://developer.android.com/studio/index.html
      (or visit https://flutter.dev/docs/get-started/install/linux#android-setup for detailed instructions).

[✓] VS Code (version 1.47.1)
    • VS Code at /usr/share/code
    • Flutter extension version 3.14.1

[✓] Connected device (2 available)
    • Linux (desktop) • linux  • linux-x64      • Linux
    • Chrome (web)    • chrome • web-javascript • Google Chrome 89.0.4389.90
```

</details>