Kunzisoft / KeePassDX

Lightweight vault and password manager for Android, KeePassDX allows editing encrypted data in a single file in KeePass format and fill in the forms in a secure way.
https://www.keepassdx.com/
GNU General Public License v3.0
4.78k stars 276 forks source link

Why not use the internal file storage? #1157

Open kraoli opened 3 years ago

kraoli commented 3 years ago

Currently KeePassDX saves the keepass file in the public storage of Android. When I understand it right, every application with permissions to read storage could access this (encrypted) file. I use as few as as possible apps, but still I have to use some important apps that need access to the storage.

That means theoretically a bad app could leak my keepass file via network to a third party, which could try to brute force it. I'm careful, but that can also happen by a bad update, there were incidents like that in the past.

Idea: I know, it's unlikely, but anyhow, my idea would be this. I would prefer it to save really important keepass files in the app storage that can't be accessed by other apps. Since I only sync my keepass file from time to time or even never, a simple import/export would be enough for me.

I imagine it as a option were you can say where to save the specific keypass file.

This would also solve my tidy up issue. The keepass file is always in my public files (looks messy :-P) and I can't save it at a different place (afaik).

Best regards, k.

Ps: I guess the KeePassDX does never save anything unencrypted in the public storage of android, even not a short moment, right? So other apps can really only get the encrypted keepass file and not intercept it in any way. For example when opening the keepass file or saving it.

J-Jamet commented 3 years ago

Currently KeePassDX saves the keepass file in the public storage of Android.

Not necessarily. KeePassDX simply saves the file in the storage space associated with the URI provided by the file provider. It can be public or private or remote, it is the file manager that defines it.

When I understand it right, every application with permissions to read storage could access this (encrypted) file. I use as few as as possible apps, but still I have to use some important apps that need access to the storage. That means theoretically a bad app could leak my keepass file via network to a third party, which could try to brute force it. I'm careful, but that can also happen by a bad update, there were incidents like that in the past.

This only happens if the location of the file pointed to by the URI is in a public storage space.

I know, it's unlikely, but anyhow, my idea would be this. I would prefer it to save really important keepass files in the app storage that can't be accessed by other apps. Since I only sync my keepass file from time to time or even never, a simple import/export would be enough for me.

I want to keep the keepass file storage system separate from the file editing. KeePassDX is an application that only does editing. What you propose should be done from a separate file manager application that will contain the file in its private area.

Ps: I guess the KeePassDX does never save anything unencrypted in the public storage of android, even not a short moment, right? So other apps can really only get the encrypted keepass file and not intercept it in any way. For example when opening the keepass file or saving it.

When opening and decrypting the file, the data is stored in RAM and is deleted when the database is locked. If a data file is too large, it is decrypted and re-encrypted on the fly in the application's private storage space with a temp key to be easily accessible for edition.

kraoli commented 2 years ago

@J-Jamet Late follow-up question.

Where would you put the keepass file in Android to keep it private - means that only KeepassDX (and I guess the file provider, I assume that it can't be excluded) can access it? Private file provider is certainly clear for a Android developer, but I'm not one and I only found this https://developer.android.com/training/data-storage overview and that https://github.com/Kunzisoft/KeePassDX/wiki/File-Manager-and-Sync, which still doesn't make it clear to me.

  1. As I understand it, I could use a cloud storage client as a file provider. So I would create the keepass file in this app and access it from KeepassDX. In this case only the cloud storage app can access the file, no other Android app, correct?
  2. How can I verify that the cloud storage is compatible? You have list in your wiki, but my app of choice isn't listed and it would be good to know how to check it anyhow (list can be outdated).
  3. Isn't it dangerous to use a cloud storage as a file provider? An update could make it not compatible any more, thus give a chance to corrupt the keepass file?
  4. Where can I put the keepass file when not using a cloud storage app? It would be marvellous if you could give a brief example of how to do this in practice.

I guess for most non tech savvy people this might be too complicated to use. Maybe it's an idea to integrate a small own file provider as a default to make sure that users don't expose the keepass file without knowing. I guess most people will just save the keepass file somewhere in the public file system i.e in Documents or Download.

J-Jamet commented 2 years ago

Where would you put the keepass file in Android to keep it private - means that only KeepassDX (and I guess the file provider, I assume that it can't be excluded) can access it?

KeePassDX cannot store KeePass files. This may seem counter-intuitive, but you have to think of it as an editor. For an analogy, it works more like notepad but more complex.

The links you gave explain how file managers behave with KeePassDX. On computer, you have only one integrated in the system (which allows to navigate in files and folders). In Android, it's more complicated because the programs are partitioned and can't share data easily. So KeePassDX can't have access to a file tree directly and goes through a content provider. The file manager is in charge of storing the file and providing the data of this file to KeePassDX.

  1. It depends on how the cloud application you are using is made, if it shares the file with other applications, they will have access to it. But in general it will be up to you to define it.

  2. Just test, you see if it is possible to have access to your application by pressing the button "open" and "create database" of KeePassDX. And you see if a file opened from the application remains accessible if you do external operations.

3.It is dangerous if you don't trust the service offered by the file manager application. If you chose this service, it means that you trusted it in the first place. It is quite possible that the cloud application used corrupts the file. If it was poorly designed and a synchronization is not properly performed, or a cache is not properly used, the file gets half-written and becomes unusable. So you have to trust the company when the code is closed or do an audit when the code is open.

  1. Wherever you want. It's not my job to tell you how to manage your files. As I told you before, KeePassDX is an editor (a kind of Notepad that encrypts and decrypts files), do you ask your text editor creator where you should save your sensitive files?

I guess for most non tech savvy people this might be too complicated to use. Maybe it's an idea to integrate a small own file provider as a default to make sure that users don't expose the keepass file without knowing. I guess most people will just save the keepass file somewhere in the public file system i.e in Documents or Download.

The FileSync project will be there for that, but again, it will leave the choice of storage method to the user. Personally, I don't see any problem with a file being in "Download" or "Documents" if there are only trusted applications accessing those folders. If a user allows malicious applications to access these folders, that's another problem.

There are tons of ways to store and provide a file ; it is possible to put a file on a USB stick and use it in OTG, or locally or remotely. It is the user who chooses how to store his data. If he does not want this behavior and wants to delegate the management of his passwords to an external entity, he can simply use another tool, there are many, but in this case he must fully trust this entity. (Spoiler: I prefer to manage my sensitive data personally.)

kraoli commented 2 years ago

Thanks for answering.

Personally, I don't see any problem with a file being in "Download" or "Documents" if there are only trusted applications accessing those folders. If a user allows malicious applications to access these folders, that's another problem.

That's what I basically want to archive, avoiding using "Download" or "Documents" and I'm wondering how. Usually apps save their data in their app storage, as I understand. Other apps can't access this storage area and I think it's a good concept.

II see your point to use only trusted apps. And I do. But there can always be bad updates and it's almost impossible be sure that you can trust all apps. That's the great thing of mobile OS, the separation by app and not just by admin and user and I trying to find a way to do that with Keepass DX too.

J-Jamet commented 2 years ago

Your need is related to this kind of application: https://github.com/2bllw8/anemo In this case, the files are stored internally in the file manager and are made visible only if authorized.

kraoli commented 2 years ago

I will have a look. Thank you.

I now your seperation idea of the storage provider, but would be great when this was build in as an option to prevent any other apps being accessing the keepass file.

J-Jamet commented 2 years ago

I now your seperation idea of the storage provider, but would be great when this was build in as an option to prevent any other apps being accessing the keepass file.

I get it and that's what the Anemo application does.

kraoli commented 2 years ago

After thinking a while. I'm not sure if I want to use Anemo. It seem to be a small project with just 4 people involved. I have no idea how trustworthy or reliable this solution is. I'm not a Android dev. No deep knowledge. But with most apps it's a standard feature that data is/can be saved just in the app scope. I would always prefer to use the native implementation compared to a 3rd party workaround.

Don't understand in a bad way. :-) But app scope storage is one of the best things in the mobile world compared to usual operating systems in terms of security. Trusting all your applications 100% is quite hard. And there is always a possibility of a bad update/hack of a project.

No need to continue this conversation if you have a clear vision. But I can't resist pointing it out once again. :-) Looking forward to the FileSync project!

J-Jamet commented 2 years ago

But with most apps it's a standard feature that data is/can be saved just in the app scope.

This is not an argument. Just because everyone else does it doesn't mean it's appropriate here. The goal of KeePassDX is to remain an editing application, not a file storage application. Each app is made for one purpose and keeps things separate. I think you are confused because it requires using 2 applications but apart from having two icons, if you trust the storage application, I don't see what the problem is.

The fact that KeePassDX does not store data from a KeePass database once the database is locked is a strong argument. It means that if the storage medium is external, a hacker won't even be able to recover the file to try to extract the data from KeePassDX. If I start internalizing the storage, I completely change the scope of the application.

I would always prefer to use the native implementation compared to a 3rd party workaround.

Why do you think it's a workaround? On the contrary, in my mind it's a more flexible and completely legitimate way of handling things.

app scope storage is one of the best things in the mobile world compared to usual operating systems in terms of security.

I agree, and that's what Anemo does.

Trusting all your applications 100% is quite hard. And there is always a possibility of a bad update/hack of a project.

Again I completely agree, that's why aggregating everything in one application is also a bad idea, if there is a flaw, all the concepts in the same application are compromised. If things are well separated, a flaw in one place can limit the propagation to a module.

No need to continue this conversation if you have a clear vision. But I can't resist pointing it out once again. :-)

I understand and I am always ready to discuss but I don't see any technical argument to do an internal storage directly in KeePassDX.

withdrawn-auditor-craftier commented 1 year ago

As an application developer for Android, I don't understand @J-Jamet 's reasoning.

While it is true that in theory you should absolutely trust any app which has external storage access, that isn't true in practice. And while the database is encrypted and therefore should be secure, even with offline access, why risk it? Why not account for the users which may not be using 30-80 character passwords.

Android provides implicit and built-in security by means of sandboxing. So why not use it? In terms of implementation, it is easier to use app-specific storage than it is to interact with the Storage Access Framework.

@J-Jamet, you state:

The goal of KeePassDX is to remain an editing application, not a file storage application

@kraoli wasn't asking for KeePassDX to become a file storage application. They were asking why the application does

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(...)
intent.setType(...)

startActivityForResult(intent)

instead of,

File file = new File(context.getFilesDir(), filename)

Keeping the database stored within the application is more secure (in that it is protected by android sandboxing) and simpler. So why not use it?

I would like to note that KeePassDX does not request the internet permission! This is a solid guarantee that your information won't be leaked to the internet by some bug. But this is completely ruined by the fact that the database is stored in a publicly accessible area. You now have to rely that all apps which have external read permissions don't have any bugs in them.

So far, I really like KeePassDX and all of the features it provides. The only reason why I am not using KeePassDX is because it stores the database in a publicly accessible storage, as opposed to the securer and private built-in storage.

J-Jamet commented 1 year ago

While it is true that in theory you should absolutely trust any app which has external storage access, that isn't true in practice. And while the database is encrypted and therefore should be secure, even with offline access, why risk it? Why not account for the users which may not be using 30-80 character passwords.

I am not asking to trust any application through external storage access. On the contrary, I just split the chain of responsibility, which means that the user has the choice to use the application he wants to trust to store his file. It is not the purpose of KeePassDX to be the storage environment for this file because it would become the only focus attack area for a malicious person.

Android provides implicit and built-in security by means of sandboxing. So why not use it? In terms of implementation, it is easier to use app-specific storage than it is to interact with the Storage Access Framework.

The goal is that the storage and file provider application uses this technique. You can use Anemo which works perfectly in this sense and fit your need. The logic is that it would be possible to provide only one data stream that represents a file per content provider, which means that KeePassDX never stores the file. The huge advantage is that it is possible to put a database on a USB stick, there will never be a copy to recover in the phone if it is cracked.

File file = new File(context.getFilesDir(), filename) Keeping the database stored within the application is more secure (in that it is protected by android sandboxing) and simpler. So why not use it?

This explicitly means that the application manipulates files and not data streams, so the chain of responsibility is broken and requires storing the file in the application and in the phone. This would remove the huge advantage of storing the file in a USB stick and not keeping a copy.

I would like to note that KeePassDX does not request the internet permission! This is a solid guarantee that your information won't be leaked to the internet by some bug. But this is completely ruined by the fact that the database is stored in a publicly accessible area. You now have to rely that all apps which have external read permissions don't have any bugs in them.

Not having internet permission guarantees that there is no network connection, it does not guarantee that someone can recover the file once the phone is stolen. I'm aware that the simple fact that the file is encrypted is enough to protect it, but that an attacker can't even recover it, isn't that better?

I just saw that I didn't add Anemo in the wiki, I'll add it when I have some time because it fits exactly your need.

J-Jamet commented 1 year ago

But this is completely ruined by the fact that the database is stored in a publicly accessible area.

I wanted to come back to this sentence. KeePassDX lets the user choose to store the file where he wants and use the file provider he wants. If you put your file in a public area, it's because you chose to do so, it's not a condition at all, quite the contrary. The only condition is that the data stream is provided in a standard way by file provider. If the file is stored in the private area of the file manager, it is not in the public area.

withdrawn-auditor-craftier commented 1 year ago

I've looked into this a bit more and now understand the tremendous benefits of abstracting files to URIs, especially when it comes to synchronization. I appreciate this abstraction and am for keeping this abstraction. However, I still don't understand why it wouldn't be possible to store the database within app internal storage. If you want to maintain the URI abstraction, you can still store the file internally and only interact with the file by its URI: Uri.fromFile(...)

Plus, there is an explicit reason to include the database within app internal storage. As far as I am aware, the only way to store the database in a non-external storage, is to use a third party application. When it comes to an application like this, I'd prefer the minimal number of third party dependencies.

Responding to a couple of things:

I am not asking to trust any application through external storage access. On the contrary, I just split the chain of responsibility, which means that the user has the choice

and

If you put your file in a public area, it's because you chose to do so

By not allowing the database to be stored in internal app storage, the user is forced to either trust a third party application or trust all apps that have external storage access. Granted, if an app has external storage access, one should trust it. But if its possible to store it within internal app storage, then why not?

The logic is that it would be possible to provide only one data stream that represents a file per content provider, which means that KeePassDX never stores the file. The huge advantage is that it is possible to put a database on a USB stick, there will never be a copy to recover in the phone if it is cracked.

From my understanding of how the application is implemented, storing the file in internal storage shouldn't break the URI abstraction. As explained above, one can obtain the URI of a file within internal storage.

withdrawn-auditor-craftier commented 1 year ago

I should mention: I am not against allowing the user to select where the database is stored via file providers. Quite the opposite. I would just also like the option to store it internally.

J-Jamet commented 1 year ago

There are several reasons why I don't want to store the database file internally, I have already answered the question several times in this thread and others : https://github.com/Kunzisoft/FileSync/issues/7#issuecomment-1211426179

It complicates the code, will need to manage an import-export file system, the current merge implementation is not made to manage an intermediate file so will need to make a content provider internally (whats the point for that, might as well create another dedicated app), and as we need to know where they are stored and keep their state for the display of the history, we need to make a dedicated database.

I'm not saying it's not possible, but that KeePassDX is not made for that and it would break the concept of separation of storage and modification of the data. I repeat, it is intended to be a file editor, not a file manager. If your need is a single app that handles internal storage and KeePass file editing, then try KeePass2Android.

By not allowing the database to be stored in internal app storage, the user is forced to either trust a third party application or trust all apps that have external storage access. Granted, if an app has external storage access, one should trust it. But if its possible to store it within internal app storage, then why not?

I don't see the problem of trusting another application, it just adds an icon, if it's open source and does a good job of file management, what's the issue. Why not use Anemo here?

If the file is integrated in the storage area of KeePassDX, concretely and roughly, I will have to copy and paste the code of this app, the problem is that there will be no specific updates of the base project and it increases the bug potential, so I see no interest.

klenium commented 1 year ago

Each app is made for one purpose and keeps things separate.

Nice, as the project owner, you choose the goal. For other people, this lowers the user experience. I'm not going to install az app that is not available from Google Play, nor I want to store the key in cloud (that's kind of the opposite of the goal of the key file). I'll try out Keepass2Android as other people told that it has option to save to internal storage. If that works well, KeePassDX will be uninstalled. As from the user's view, this feature is such basic that I'd like to have it and I don't want to choose a 2nd app. Our goal is different from yours. That's fine I think. This is the reason why people choose Apple instead of Linux.

J-Jamet commented 1 year ago

Obviously, I advise you to use the tool that fits your needs, KeePassDX was made after KeePass2Android to have a different behavior. So it would be useless to copy everything from another app.

Just use what suits you best, GNU/Linux users are makers who want to see the source code and have a sharing philosophy, like KeePassDX. If you are an Apple user, you trust a single closed non-free universe, so KeePass is basically not a tool with the same philosophy in this point.

You can even find all-in-one password management tools that are linked to your system without having to manage it yourself, but you have to trust the company that centralizes everything, it's always a matter of choice

If you don't want to install an app that doesn't come from the Play Store that's also your choice, but for me it's only a deployment channel that is dependent on a company, it doesn't reflect the app itself. After that, there is no reason why an app can't expand the deployment platforms.

Here I want KeePassDX to be as close as possible to the philosophy of openness and standardization I describe, in the spirit of sharing and security of the makers. But it's at the expense of an easy use, it's again a matter of choice.

nain-F49FF806 commented 10 months ago

I feel the current implementation is good.

It might be counterintuitive at first, but the way the app currently handles files, gives you more flexibility, not less. As @J-Jamet has said, think of this tool as a .kbdx file viewer/editor. By not handling the file storage itself, it saves you from the hassle of exporting or importing those files into the app. And allows you to choose a file provider as per your security/storage needs.

KeePassDX  --> File Provider --> [You manually select a file using file provider] --> File provider --> KeePassDX decrypts and shows file. 

Internal private storage is supported, you just have to use a file manager/provider/picker that supports that too. When you try to open a database, this app hands over control to a file picker (to let you select the file to open). So for considerations of securing the file, you should think towards your choice of file manager/provider.

This app's developer could implement one for you, a rudimentary one that manages files in its internal storage. But

  1. you could possibly get a better, more flexible one elsewhere.
  2. such development efforts, even if undertaken, are better spent on the dedicated file provider, than duplicating that functionality here.

Perhaps the reason why this feature is in demand is that the choice of trusted file providers currently looks slim. In that case, rather than giving in to feature creep and overburdening here, I think it'd be good to coordinate efforts in that direction.

Dedicated, focused, open tools are better to maintain, audit and combine/swap.

nain-F49FF806 commented 10 months ago

For anyone following this thread, it is indeed possible to save your database to private internal storage, using KeePassDX + Anemo.

Just create a separate folder in Anemo app, and when creating a database in KeePassDX choose Anemo > [Your dedicated folder] in the file picker. Other apps do not automatically gain access to Anemo's internal storage, even if they have general storage access.

It is an amazing tool IMO. I was impressed enough with the idea to create a small fork Aer that uses private external storage instead [~ex encrypted SD card] to have more room for storage.

Yes, the app can be made better in terms of providing permissioned, granular access to other apps (currently, global password lock/unlock is available). But such niche feature development is precisely why it is better done as a separate project. Where the sole focus can be to make the best, well thought private storage tool.