uintdev / qrserv

Transfer files with ease over a network.
https://play.google.com/store/apps/details?id=dev.uint.qrserv
MIT License
130 stars 10 forks source link

Create https server instead of http with aes 128 or 256 encryption and tls 3.0 #10

Closed Wjxfi closed 4 months ago

Wjxfi commented 1 year ago

Look at how he did it https://www.f-droid.org/packages/com.ismartcoding.plain/ https://www.f-droid.org/packages/org.localsend.localsend_app/

it may require a long password (for encryption)

uintdev commented 1 year ago

I'm guessing that for this to be practically possible, it would require the receiver to have the same app but in a state to receive.

As the main intent is for this to just work like by accessing via browser without installing a self-signed certificate, by default at least, it would not be possible. Maybe if a receive mode was implemented, that could be added as a way to help secure that connection. But there aren't currently plans lined up for that.

But honestly even so, it looks like it might be more of security theatre. For example, the private key is very present in the LocalSend app. There's some other things going on, so maybe that's at least preventing an attack in terms of MITM (provided the attacker isn't the intended receiver) to some extent -- don't quote me on that though. Either way, if I do add in support for encryption then I'd want to do that properly. I'm no cryptographer, so I don't have much of an idea of how to have something solid enough in this sort of situation.

Wjxfi commented 1 year ago

https://www.f-droid.org/packages/com.ismartcoding.plain/ this app works through the website and any apps the recipient doesn't need

uintdev commented 1 year ago

In the case of that, it prompts for the user to essentially trust the unsigned certificate in the browser.

Wjxfi commented 1 year ago

In the case of that, it prompts for the user to essentially trust the unsigned certificate in the browser.

If the site is open source, you can trust it, I guess

uintdev commented 1 year ago

Ultimately, the issue is that as long as the network is untrusted, it's possible for the attacker to use their or the app's own self-signed to try impersonating the server. Encouraging users to trust an untrusted self-signed certificate isn't wise in general, and would be an inconvenience (i.e. would have to at least let them know that it won't generally be usable outside of a web browser, user has to perform an extra step to 'trust' something that may not be trustworthy).

The best way to go about this with how things currently are is to use mobile tethering. It would have its own LAN of which you can trust. The sender can be the device tethering but it will still be on its own network. Any device that joins that network can reach the sender. Mobile data doesn't need to be on for it to operate.

There's stuff such as WiFi direct that would help (although limited between Android devices), but the big issue I keep running into is scoped storage. For some time, existing apps have to target 31 (Android 12) at least -- this is going to be increased further for new app publications and updates from 31st August 2023. The API limitations affects this app, as well as similar ones such as the ones you had linked to. They cannot perform efficiently (i.e. no direct access to selected files and so are copied to app's cache) or perform tasks that involve saving into a specific location under internal storage. Not without the functionality they depend on supporting the use of a permission that is strictly limited on Google Play (and even then, it has to meet the exceptions made).

Wjxfi commented 1 year ago
  1. The HTTPS solution is better than NOTHING.
  2. Open the Open in PC web browser -> ... -> HTTPS certificate signature, you can compare the signature value with the browser one if you really concern the security. image
  3. All data in the api request or response are encrypted. Nobody can even steal your phone data. image
  4. Every file URL is encrypted with a file token which will be recreated when app restarts. When you share the file URL with someone, he will not be able to access that file if your app restarts.
  5. Is there an existing solution which can hack the self-signed certificate solution? I would like to try to see if I can improve it.

response from the developer of the application plain

uintdev commented 1 year ago

Wasn't quite expecting for an issue to be made on the dev's own repository, but I guess to be fair, there isn't an obvious way of direct contact. I'll speak of that app specifically (as what I spoke of was more of in-general). I want to at least make the disclaimer that the 'analysis' was mostly a quick glance. So this is partly going by some assumptions.

Some things I'd at least note:

That said, I'll get into each point here.

  1. Yes, it's better than nothing. No plaintext communication of the actual responses. Although, bare in mind that certificates are about trust too. Without a (trusted) CA, it's inherently not going to be trustworthy right out the gate. The end user has to explicitly essentially make an exception to this. As the private key would have no way of being known in this case, at most, the only interception that could be done is to have the client get (injected) responses from the attacker along with its own self-signed certificate.. if trusted by the user. With point 2 in mind, there's an advantage to at least being able to rely on the certificate signature value when it comes to spoofing, but it relies on the user to put some effort into checking themselves at least -- realistically, most aren't going to do this, especially if not explicitly prompted to (even then, as long as the friction is there, the user may eventually just blindly trust it) -- this itself does kind of help solve the rest of the puzzle (manual verification), so I'll give credit where it's due, despite not being that practical What kind of bothers me is essentially encourage trusting what are deemed as untrusted certificates -- as it may normalise such behaviour elsewhere (like a public-facing website). In addition, applications or tools that involve downloading content may not offer the option to go trusting untrusted certificates. Unfortunately, not much can be done in this regard.

  2. It's good that there's at least that anti-spoofing measure, but it's going to be a little involved to leverage that (see point 1)

  3. Looking into the app a bit more and on the GraphQL side, this looks to do with general controls (as the app is essentially a toolbox of utilities) rather than the transmission of files -- which is still good (there's also a bit of WireGuard going on but looks to be more for the chat feature?) -- I'm not that familiar with what's really going on there to achieve that, so I can't comment on how that might've been implemented.

  4. Not familiar with how this is encrypted, so I cannot provide much of a comment regarding that. Although, I have a feeling this would involve a (web) client to do the decryption at least?

  5. See point 1. Looks like there's at least far more effort put into this sort of app compared to others in the HTTPS department in order to try reducing risk, so there is some degree of protection. The user has to decide if they want to risk making the connection still.

This is not intended to be a security review (far from it). If in reality it protects well enough for what it is and for the usual threat models of the users, then that's a good enough win. Of course, it doesn't mean I'm not going to have some concerns of my own (there usually will be pros and cons, as with many things) and feel different about it.

This is not to discourage use of the app at all. Absolutely not. It is indeed better than nothing from a security standpoint, if a user wants a more secure option that doesn't involve the internet. I just hope they're still a bit careful, as it's by no means perfect.


It's important to outline something here, and I have to be clear on it. The app in question is very different from mine in terms of the intended objectives. As with others in a similar category.

In the case of mine, it's about working with other devices without having to depend on having a web page or another client to just work (along with an optional full path fallback for software that need the file name in the URL in order to name the saved file appropriately) -- direct download. There won't be the luxury to dismiss warnings in some cases. Sure, HTTPS could just be optional, but users may try using it where it just won't work out and complain. A disclaimer would at least need to be included in the app just to try covering such possible cases. But even then, there are other concerns.

These sorts of apps have to make a compromise somewhere in order to achieve their objectives, even if it may reduce flexibility or convenience in places. It's tough. At the end of the day, these are tools. Use what works best. It's always good to have multiple options out there.

Believe me, I strongly want some security measures when it comes to communications. I absolutely would want HTTPS in place. However, the good has to outweigh the bad. I don't want to introduce anti-patterns. I want for it to consistently work for the sort of use cases it could be put through over an insecure connection. The app's philosophy is convenience and simplicity. So it's going to be minimal, rather than a Swiss-army knife. It shouldn't have (much) friction.

I had to compromise enough as it is when it comes to the app (one of the major issues being mentioned a few posts ago regarding cache), in ways that could've been avoided from the very beginning. Those sort of things make me not so 'happy' about it, despite genuinely being useful (to the users, and even myself in several occasions [i.e. to quickly get screenshots off a device]). I want to be proud of my creations, knowing I did the best I could to the highest quality. It was never claimed to have secure communications (as fancy as it would to do so as a 'selling point'). Just that it does what was described. Which naturally works on various platforms and software without additional dependencies (i.e. recipient needing the [web] client too). Nothing that advanced.

This is not to throw any salt at anyone. Not at all. I just want to be clear with where I stand with this sort of concept (walking through the issues it might pose if I adopt it).


I plan to use self-signed certificates in the future for an ongoing private project (not having a domain to use for reasons). Thing is, the private key will be only on the server (like how it is with the app being discussed, but static rather than dynamic) and the public key would be baked into the app client so that it knows if it can be trusted. I don't like having to do self-signed, but considering the circumstances and that there's very little compromise in that case (not having much of a technical choice), it's good enough. This is how self-signed certificates are usually done in a safer context outside of a browser.

Wjxfi commented 1 year ago

Thank you for such a comprehensive and detailed response. I think the advantages cover the disadvantages (I need privacy). I will wait for the fulfillment.

There won't be the luxury to dismiss warnings in some cases. Sure, HTTPS could just be optional, but users may try using it where it just won't work out and complain. A disclaimer would at least need to be included in the app just to try covering such possible cases. But even then, there are other concerns.

uintdev commented 1 year ago

The response was lengthly, so for clarity, it boils down to these points:

If I were to add this, I'd do what I mentioned with a strong disclaimer regarding the potential issues, while discouraging casual trusting of untrusted certificates and not making it the default option. Then hope that's enough of a heads-up.

I'll consider the possibility of implementing such functionality in the future. Would at least need to figure out certificate generation.

uintdev commented 4 months ago

Closing as part of clean up.

I gave this one some thought. I still stand by my concerns, and I don't really wish to overcomplicate the app from a technical perspective, never mind the user-facing. If there's enough demand then maybe I'll dig even further to try finding the best approach for having such a thing implemented and go ahead if there's an approach that sounds solid enough to go by. Ideally, I don't want a half-baked solution. Especially if it's to do with security.

I'll be real: not sure if it'll happen, if ever. So, I'd advise only using the app on trusted networks, while tethering (phone or tablet becomes its own router with LAN), or on a VPN (if downloading via one). At least then, there can be more confidence in communications not being intercepted by a random person.