Analyzing Security Flaws in the Java Note-Taking Apps

Table of Contents

Program 01

Analyzing
  1. There is no possibility for a user to change the password without going to the code and change app password manually
  2. The password is stored in the NotepadActivity.new_password  and it is not encapsulated. Meaning, every programmer may view, edit, access the password within any part of the project.

3. The password is stored locally, in the cache

How it hinders the security
  1. It doesn’t follow the CIA model
    1. Confidential — authorized people have the access
      Anyone who has the access to the project has the access to the password of a user. For instance, a project may be an Open Source and hosted on GitHub. Unless the GitHub sensitive data feature get triggered and remove the very same data, this password would be place in GitHub for everyone’s view

    2. Integrity — users aren’t capable of unintentional editing of data.
      In this project a programmer may unintentional editing of data.

    3. Availability — it is about available of information

How to improve the security
  1. Use a database to permanently store the passwords
  2. Use hashing to store the password in the database. Then, the database will consist of only hashed passwords, and unauthorized people accessing the database won’t see the passwords right away
  3. Use encapsulation to improve the integrity. For example instead of coding like this public static String new_password = "1234"; maybe it will be a good idea to code like this privatestatic String new_password = "1234";
  4. Make the password not static, but dynamic. In this project user has to go to the code to alter the password. However, making the password dynamic, will allow user to edit the code in the program. There are many ways to implement this in Java. We may use a constructor or setters

				
					public class MainActivity extends AppCompatActivity {

    EditText password;
    private Button button;
    public static String correct_password;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        password = findViewById(R.id.password);
        button = (Button) findViewById(R.id.login);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                correct_password = NotepadActivity.new_password;

                //validate password
                if (TextUtils.isEmpty(password.getText().toString())) {
                    Toast.makeText(MainActivity.this, "Empty input", Toast.LENGTH_LONG).show();
                }
                else if (password.getText().toString().equals(correct_password)) {
                    Toast.makeText(MainActivity.this, "Correct password", Toast.LENGTH_LONG).show();
                    openNotepad();
                }
                else
                    Toast.makeText(MainActivity.this, "Invalid password", Toast.LENGTH_LONG).show();
            }
        });
    }
    public void openNotepad() {
        Intent intent = new Intent(this, NotepadActivity.class);
        startActivity(intent);
    }
}
				
			
				
					public class NotepadActivity extends AppCompatActivity {
    private TextView textView;
    private EditText editText;
    private Button saveButton;
    private Button changeButton;

    public static final String TEXT = "message";
    public static final String SHARED_PREFS = "sharedPrefs";

    public static String text;
    public static String new_password = "1234";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notepad);

        textView = (TextView) findViewById(R.id.text_view);
        editText = (EditText) findViewById(R.id.edit_text);
        saveButton = (Button) findViewById(R.id.save_button);
        changeButton = (Button) findViewById(R.id.change_password);

        saveButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText(editText.getText().toString());
                saveData();
            }
        });

        changeButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new_password = editText.getText().toString();
                savePassword();
            }
        });

        loadData();
        updateView();
    }

    public void saveData() {
        SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        editor.putString(TEXT, textView.getText().toString());
        editor.apply();

        Toast.makeText(this,"Data saved", Toast.LENGTH_SHORT).show();
    }

    public void savePassword() {
        Toast.makeText(this,"Password changed to: "+ new_password, Toast.LENGTH_SHORT).show();
    }

    public void loadData() {
        SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
        text = sharedPreferences.getString(TEXT, "");
    }

    public void updateView() {
        textView.setText(text);
    }
}
				
			

Program 02

Analyzing
  1. Library that gives PatternLockView from jCenter repository ****is deprecated.
  2. Moreover, since the jCenter is itself depricated:

jCenter is no longer be available for non-Artifactory clients. This means by the end of March 2021, publishing new packages to Bintray will no longer be allowed

https://testfairy.com/blog/jcenter-and-bintray-is-shutting-down-what-to-do/​
  1. Since in the **public class** MainActivity **extends** AppCompatActivity in the run() method we have the same code in the both if-else scenarios
  2. The password is stored locally, in the cache sharedPreferences.getString
  3. There is no possibility for an app user to change the password without going to the code and change app password manually
How it hinders the security
  1. Since jCenter was removed, there is no longer a possibility to use the library PatternLockView. Moreover, the creators do not intend to transfer the library to Maven repository. The last changes to the library were in 2017 https://github.com/aritraroy/PatternLockView
  2. The MainActivity has the same if-else code, thus, a user or unauthorized person has the access to the program despite entering the wrong password
  3. It is hard for an app user to change the password
How to improve the security
  1. Use the libraries and repositories that are not deprecated. It will make sure that a programmer is up to date with the last patches
  2. Code a different else scenario if a user enters the wrong password
  3. Make it easy for a user to change a password
				
					import com.andrognito.patternlockview.PatternLockView;
import com.andrognito.patternlockview.listener.PatternLockViewListener;
import com.andrognito.patternlockview.utils.PatternLockUtils;

import java.util.List;

public class CreatePasswordActivity extends AppCompatActivity
				
			
				
					public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                // loading is given
                SharedPreferences sharedPreferences = getSharedPreferences("PREFS", 0);
                String password = sharedPreferences.getString("password", "0");
                if (password.equals("0")) {
                    // Intent to navigate to Create Password Screen
                    Intent intent = new Intent(getApplicationContext(), CreatePasswordActivity.class);
                    startActivity(intent);
                    finish();
                } else {
                    // Intent to navigate to Input Password Screen
                    Intent intent = new Intent(getApplicationContext(), InputPasswordActivity.class);
                    startActivity(intent);
                    finish();
                }
            }
        }, 2000);
    }
}
				
			

Program 03

Analyzing
  1. MainActivity has two methods:
    1. one that creates a new password
    2. another that modifies a note
  2. In method changepassword.setOnClickListener we can set any password we want

How it hinders the security
  1. The app is not protected by the password. There is a possibility to change a password, however security with the password is not implemented
  2. New password can be any length and any password. This opens the possibility to bruteforce. For example, if a user sets a common password “qwerty”, or “123” it could be broken under a second
How to improve the security
  1. Implement the security with a password
  2. Set the password length and forbid the common password: “Michelle”, “password”, “123”…
				
					public class MainActivity extends AppCompatActivity {

    Button changepassword;
    Button notechange;
    TextView thenote;
    String notee;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        SharedPreferences settings = getSharedPreferences("PREFS", 0);
        notee = settings.getString("note", "");

        changepassword = (Button) findViewById(R.id.changepassword);
        notechange = (Button) findViewById(R.id.notechange);
        thenote = (TextView) findViewById(R.id.thenote);

        thenote.setText(notee);

        //ability to cahnge the password on the main screen
        changepassword.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getApplicationContext(), NewPasswordActivity.class);
                startActivity(intent);
                finish();
            }
        });

        notechange.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                Intent intent2 = new Intent(getApplicationContext(), MessageChangeActivity.class);
                startActivity(intent2);
                finish();
            }
        });

    }


}
				
			
				
					public class NewPasswordActivity extends AppCompatActivity {

    EditText passwordcreating;
    Button confirm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_password);

        passwordcreating = (EditText) findViewById(R.id.passwordcreating);
        confirm = (Button) findViewById(R.id.confirm);

        confirm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String text = passwordcreating.getText().toString();

                if(text.equals("")){
                    Toast.makeText(NewPasswordActivity.this, "No Password Entered", Toast.LENGTH_SHORT).show();
                }
                else{
                    SharedPreferences settings = getSharedPreferences("PREFS", 0);
                    SharedPreferences.Editor editor = settings.edit();
                    editor.putString("password", text);
                    editor.apply();

                    //small string input
                    Toast.makeText(NewPasswordActivity.this, "New Password Set", Toast.LENGTH_LONG).show();

                    Intent intent = new Intent(getApplicationContext(), MainActivity.class);
                    startActivity(intent);
                    finish();
                }
            }
        });
    }
}
				
			

Download ZIP File With The Programs

Share the article​

Share on facebook
Share on linkedin
Share on twitter

Author

Max D.

Max D.

"Thank you for finishing reading the article! I'm open to new opportunities, collaborations, partnerships! Contact me"