Backendless security practices

Hi All,

I’ve only just started with Backendless, currently in the process of migrating the backend of my app away from bubble.io (due to impending dramatic cost increases) - but I’m having a lot of reservations about some of the security practices in play in backendless.

A few points on my background experience.

  • I work in IT and cybersecurity and have been in this space for ~25 years. I specialise in IT & security architecture, cyber incident response and identity security - so my concerns are from practical exposure in these domains.
  • I can write and understand code, but prefer to avoid writing it to save time - codeless is preferred
  • I have read the documentation and forums countless times for answers, to no avail

My goal is very simple - I am trying to have bubble.io call my API to perform the heavy-lifting functions in my app (my app is very data heavy, with lots of many-many queries involved in the DB). In essence, the problem with bubble is that the upcoming pricing changes make performing any work in the app extremely costly, to the point where it makes the entire app unviable. I therefore aim to move the core heavy-lifting functions from bubble.io into backendless. As such, this will be a machine-to-machine integration, with bubble.io being the client and backendless being the server.

My concerns:

  1. No MFA on the main interface. Yes, I could go down the SAML path - but MFA is an essential feature these days, and users often like to reuse passwords in more than one place. A large account gets breached, a vulnerability gets found in the platform or the infrastructure goes down during the incident or response - I’m left high and dry without a backend to my platform (yes, this is a risk with any SaaS platform - but I digress…).
  2. Confusing permissions model - it is very convoluted, and even today I’m mystified how it actually works, as I am finding documentation and support posts often conflict and don’t even come close to explaining it in a way that even I can understand (Identity Security is one of my areas of expertise, FWIW!). Why not simply use the tried-and-true group-user-object permissions model? It’s well-known, simple and very secure when done right. At the very least, the current model needs to have a “RSoP” (Resultant Set of Policies) capability, to help people understand the final result of their configuration in the current model. The “NonAuthenticatedUser” is the most glaring confusion I’ve encountered, where the permissions of it seem to override my custom role, which doesn’t align with what I’ve read in the forums or the documentation. Documentation and training is also very unclear on how multiple roles interact with eachother.
  3. No simple means of validating user input in APIs being passed to the DB. It’s great to have full control over the data coming in and out of the database, but at the very least - always assume the user is malicious and trying to inject bad data. There should be an easy way to automatically escape any invalid data (e.g. with a checkbox in codeless) that could avoid any possibly of an attacker trying to extract or infiltrate the system. Not to mention the frustration of a single character (e.g. an apostrophe) breaking the query, THEN revealing the where clause used by the internal query (yes, I can override this behaviour, but not everyone will even know this risk…)! Any queries I send to a DB I always parameterise to ensure they are clean, but this doesn’t seem to be possible in backendless, where I’m instead forced to use raw SQL in the where clauses - to the point of adding quotes? Nobody should ever send a query direct, especially from user-generated input, for the exact points aforementioned.
  4. Security Logging - where is it and why isn’t it available to everyone? This is a mandatory feature for any system, and should be easily accessible irrespective of tier. How else can one determine if they are under attack or identify how an attacker got in, or what data was exposed? This is a serious concern, especially in GDPR or similar regimes.
  5. Permissions “Open by Default”. This just leads to bad code in the first instance. Yes, it is a hurdle for a non-coder to get their head around securing an app (especially with the confusing permissions model in backendless…), but honestly - if someone is writing an app for the first time, at the very least they should be forced to learn the basics of how to be secure on the Internet. There are enough serious data breaches these days, we don’t need more places for data to be stored insecurely and the lives of people being impacted by poor opsec practices.
  6. API key in the URL. This is just bad practice. Yes, it is easier to scale and automate with a WAF/LB - but it means your API key is not protected in any way during transit. It really needs to be in the header, at the very least.

Don’t get me wrong, I love the promise of backendless and the breadth of capability it offers - but there are some really glaring security concerns that I routinely see lead to compromise on a daily basis in my job. I really don’t need to be kept awake at night, particularly when I’m in the near future going to be dealing with GDPR concerns also. I need to feel confident I have done everything I can feasibly to secure my app, and right now - I’m not feeling the platform is going to allow me to do this due to these limitations. I’m open to being challenged on any of my points, some of which may be controversial, but even for my own sanity - I hope to be proven wrong!

Hi @aemondis,

Thank you for your post and for sharing your concerns. Let me address them below:

In addition to the basic email/password, we support login with Google, which can be configured to support Two-step verification

The Backendless security model is based on Principal-Subject-Action tuples. A principal is always the user which may have its own user-centric permissions which come into play with ObjectACL for example. Since Backendless security is multi-layered, user roles are at the core of the decision-making process. I recognize this can easily turn into an academic discussion about Security, but from the pragmatic standpoint, I would be happy to demonstrate how security would work in a specific use-case if you have one in mind for your specific schema.

Please clarify how you configured the permissions, what result you got, and what result you expected. The docs outline a system consisting of 8 layers. Permissions assigned to NonAuthenticatedUser come into play at layers 6 and 8.

Any additional validation of the user input can be performed in the API event handlers in Cloud Code. The event handlers are also available with Codeless. You can add any kind of logic for any of our API calls to perform data validation or modification.

All logs go into the /logging directory. This will include both the logs created by using the Logging API, as well as system logging. You can control the logging in Backendless Console (Manage > Logging)

I disagree with you on this one. When you start developing an app and if the system is entirely closed, the development experience of building something becomes completely substandard. This reminds me of using Internet Explorer back in the days when the browser out of the box was restricted to do anything - you literally had to add each site you want to visit to the white list - a complete turn off from the UX perspective.

Forcing people to do something pushes them away. This must not negate the importance of security, but it must not be the first thing a developer does (IMHO).

It is not when you use API key for analytics purposes only. An API Key in Backendless is not a security mechanism. We use it to track the type of device you access the backend system with. An API key is associated with a security role and there are plenty of ways to set the role permissions for various backend resources. If you do not like seeing API keys in the URLs, there are other ways to access the backend, all of them are documented.

I should mention that Backendless is used in some applications with some of the most stringent security requirements (banking sector, last-mile delivery, and telecom). We have passed multiple security audits otherwise, the customers would not be allowed to run their businesses on top of our platform.

Regards,
Mark

Please allow me to add my view on the “open by default” topic.
I agree with both of you. I think a solution is to not constrain developers when working on a development version of their app. However, when going productive, there must be “security by default”. For instance, the published version of my app should be secure in this respect. Also, developers should be able to switch on/off this behavior for testing purposes.

I remember well when you more or less silently introduced the new upsert permission, which consequently appeared as “open by default”. This had set my app in an unsecure state until I recognized that this new permission setting exists.

Regards,