12

Okay, so I'm completely new to the server stuff, but I have a VPS running with MySql.

I want to create a mobile app with Python, but I need access to a database that's available for everyone.

So now I was thinking to open port 3006 on my VPS so we can access the database from the python app. But this feels like it's not a good practice.

Any advice?

6
  • 13
    Not a good idea at all.
    – Orphans
    Aug 19 at 9:08
  • You can, iff you know how to lock down your database properly. But you're still open to DoS attacks that make a lot of connections, or execute specifically crafted long-running queries.
    – Bergi
    Aug 19 at 22:09
  • 1
    "a database that's available for everyone" - do you mean a static, public dataset, or really a database where everyone can edit whatever they want?
    – Bergi
    Aug 20 at 2:59
  • @Bergi I want my Python app to be connected to this external database.
    – Refilon
    Aug 21 at 16:14
  • 1
    @Refilon Yes, but what does it do with the database? Is it a readonly database? What does your app do, who are its users? Do you need to limit each user's permissions on what they can do with (their part of) the data? Would you allow your users to run arbitrary SQL commands on the database?
    – Bergi
    Aug 21 at 16:54

5 Answers 5

30

Do not make your database publicly accessible. One bug in the database or weak passwords and someone deletes / steals / changes everything.

Your mobile app shouldn't access the database directly, it should access an API that in your case is probably written in Python sitting behind Nginx. Your API calls need to be authenticated to avoid abuse, and ideally rate limited to avoid DDOS attacks.

8
  • 1
    "One bug in the code or weak passwords" could also be said about the API. But sure it's simpler to implement arbitrary authentication methods or rate limiting in a python HTTP server than in a database.
    – Bergi
    Aug 19 at 22:11
  • 10
    If you open your database port, people can extract the database username/password from the mobile app, then use those to do whatever they want on the database - update users set password='123456' where name='admin'. Getting the API to do this, if it doesn't allow SQL injection, and doesn't have a update users statement anywhere, is much harder. Aug 19 at 22:37
  • 2
    @GuntramBlohm You could give every user their own database account. And/or you only give SELECT privileges to the db user (a read-only account). Databases have a lot of this stuff built-in, you just need to know how to use it…
    – Bergi
    Aug 19 at 23:24
  • 5
    Here's a great recent example of someone that exposed their database directly for end user consumption, and illustrates why it's such a bad idea: kernal.eu/posts/linuxfx
    – 4oo4
    Aug 20 at 0:47
  • 1
    @Bergi still a bad idea even then. Apart from the hideous configuration you’d have to do and all the aforementioned other reasons, it also won’t allow fine-grained access on individual rows, e.g. ‘you cannot set this ‘active’ boolean to true when field x is lower than 10’. Aug 20 at 2:01
11

Is it a good idea to open up a database port for everyone?
... this feels like it's not a good practice.

No it isn't.

Access control and security are of course big issues there.

From an application design perspective: most things database related die a horrible death when there is significant latency between the database and application.

That is one of the reasons why most phone applications are designed to connect to API's instead.

5

Very bad idea. It's quite easy to decompile an app. Then anyone have credentials for your db. Lets say the app uses the same login for every install then you have a massive data leak. Even if you use different logins for each user of your app you have one hell of a task settings up correct privileges on your tables on row level which I don't think is even possible.

Much easier and more correct to build an api through which all communication is done

3

You need to set up a zero trust interface that establishes the user's identity and gives them access to only their own data.

Possibly this can be done by using different database roles for each user account, but I don't think that approach scales well. The usual approach is to set up an API on an encrypted channel (eg: HTTPS), and have the API perform permission checks on every request.

1

Recently there have been exploits for authentication bypass on MySQL, letting attackers access and modify/delete all data. I would therefore highly advise against publicly exposing a database server!

If it's only for maintenance use a SSH tunnel, like ssh -L 3306:127.0.0.1:3306 myuser@myserver.example.com

If you absolutely need to access it from across the internet, limit access to the IP of the server you are accessing from (and enable SSL in the database server configuration).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.