Public app - security risks?

We want to develop a public app that will use the same SQL tables as a private staff app. This app will only have the form and links to info with no ability to search through records. Meeting with IT security next week but are there any concerns we need to be aware of or are there safeguards in appsheet that might alleviate some of their concerns??

Solved Solved
2 35 3,304
1 ACCEPTED SOLUTION

Sorryh I hadnโ€™t seen this thread earlier. Seems like I missed a lot :]

As background, Tammiโ€™s already using their (cloud-based) SQL database for their secure apps. This has already been blessed by her IT team. So AppSheet connecting to their database is not by itself an issue.

The question here is: thereโ€™s going to be a second AppSheet app connecting to the database and the app itself isnโ€™t secure (it is public). So what bad stuff could happen?

  1. The app creator (Tammi) could make a mistake and allow the users to update/delete data.

  2. The app might expose information to the end-users that should not be exposed

  3. A large number of users might use the app at the same time and overload the SQL database

For #1 and #2, the mitigation is pretty simple. The SQL database admin should create a SQL user with very limited permissions in the SQL database. Just give that SQL user the ability read the minimal tables needed and write the minimal tables needed. Then use that SQL user to set up a data source in the AppSheet account. This ensures that no matter what the app allows, the database will only show and allow updates to specific data in specific tables.

It would be a good idea to have different tables in the database for the public app and the private app. If you need every update done via the public app to also update the data for the private app, it is easy to do with a SQL trigger. Your IT folks can set that up easily enough.

I think Leventโ€™s suggestion of using the AppSheet REST API is to achieve the same outcome, but do it via an AppSheet workflow rule (our version of a โ€œtriggerโ€) instead. To be honest, it is better to do it in the database โ€” much more efficient that way when there is the mechanism. If you were using a Google Sheet or something, then the AppSheet workflow solution is better.

For #3, it is a more complex response. In theory, a large number of users could all sync at the same time and overwhelm your SQL database. In practice though, AppSheet is starting to throttle the number of concurrent users per app. So I suspect this will not be an issue for your SQL database. However, make sure to provision the database to have enough capacity for your planned peak load (sometimes you can get a cloud-hosted SQL databse but it is on a shared machine and with a very low resource allocation โ€” so very cheap but also doesnโ€™t handle a lot of scale).

Hope this helps. Tammi, please feel free to engage us when you have your conversation with IT. I donโ€™t think this is a freak-out worry situationl. More like a situation that needs some planning and it will be fine.

View solution in original post

35 REPLIES 35

@tcanelli
Will any of your tables include PII data anyhow? With the public app, itโ€™s quite easy to reveal the table data (if you are aware of AppSheetโ€™s structure of course, but itโ€™s not so hard to learn) even though you donโ€™t show that table in the app. I might strongly recommend not using private appโ€™s SQL back-end in a public app. Provided you donโ€™t have any cross references and complex expressions looking up data from other tables, rows etc. you can set the Security Filter to FALSE for that table, but lately AppSheet revoked use of Security Filters from the Publisher Pro plan, so @praveenโ€™s insight and reply could be more strategic at this point.

Hmmm. The public app is a pre registration form that the staff using the private app would access when they arrive at a shelter. If we dont use the same table Iโ€™m not sure how that plan would work. Only collecting very basic info, name, county, how many people with them and how many petsโ€ฆ

@tcanelli
You can create a webhook workflow which will invoke AppSheet API and record the same record directly in your private appโ€™s table. Hence there is no need to carry all the private appโ€™s data totally on the public app where you even canโ€™t use a security filter to reduce the number of fetched rows or even set it to FALSE. Just create an empty database. It does not need to be in identical structure as you can post the data to any column you want to the main table within the JSON payload.

Would that be similar to running stored procedures in SQL to copy the data? Pros cons of both methods? Not sure IT will be thrilled with api solution , but I could be wrong.

@tcanelli
Can you elaborate your query about "Would that be simillar to running stored procedures in SQL to copy the data?"
There is nothing for the IT guys to do for the API actually. Just enable API from your AppSheet editor via Manage >> Integrations >> IN: from cloud services to your app and set a ADDS_ONLY webhook workflow in your public app. Quite easy to accomplish really.
You can refer to this page for further info:
https://help.appsheet.com/integrations/api/adding-records-to-a-table

Provided you are not so familiar with API integration, just drop me a line at levent@able3ventures.com and Iโ€™ll be pleased to help.

Steve
Platinum 4
Platinum 4

Iโ€™d be interested to know what concerns IT has.

Youโ€™ve indicated the two appsโ€“the public and private appsโ€“would both access the same SQL tables. That right there is your biggest security risk: an internet-facing SQL server. Youโ€™ll want to make sure that server is secured against unauthorized and undesirable access. IT will want to know what IP addresses AppSheet will use connecting to your SQL server. If theyโ€™re generally unfamiliar with AppSheet, they might also want an IT-focused overview of the platform.

When designing your public app, youโ€™ll want to pay close attention to access controls for app tables. Make sure only those tables that must be modified by the app have only those access modes strictly needed (add, modify, and (possibly not) delete); use read-only access wherever possible.

Consider using slices to hide columns that are needed for the app but that the public user should never see. Base your views on these slices to reduce the possibility of accidentally exposing sensitive columns. Slices can also be used to limit the userโ€™s access to tables by limiting the access modes (add, modify, delete) and hiding rows that the apps needs but that the user shouldnโ€™t see (using a filter condition).

Security filters are the best way to prevent sensitive data from ever reaching the userโ€™s device.

Itโ€™s perfectly okay for the public and private apps to share tables, but could be a problem if the shared table also contains data that should never be exposed to the public. Best to make a shared table suited to the needs of the public app then give the private app access to it, rather than giving the public app access to a private table.

@tcanelli
Provided you are using an on-premises SQL server, generally most SQL servers are designed to receive inbound IP traffic, therefore take an internal IP address from the router i.e. 192.168.x.x and for security reasons never exposed to an external IP. If thatโ€™s the case, then the IT should be defining and opening a port for AppSheet on the firewall for the incoming and outgoing TCP traffic.

Sometimes, when exposing the SQL server to an external IP is necessary, than generally the IT sets up a VPN or hides the SQL server behind a VM. On this case, it might be a bit problematic but there are a couple of solutions too. Depending on what kinda VPN mainframe they are using (could be either an external VPN service or they might have set-up their own VPN server) than either you or an IT guy should consult to AppSheet to provide the IPv6 addresses of the incoming traffic.

The help pages that @Steve has provided might be a good point to start with.

We arent using on prem SQL but I know this is something IT would like to move to just dont think we can make this happen before this hurricane season. We are using Azure sql.

I will need to review all the info - this part is really over my head. Hopefully the guys in IT will be willing to help find a solution instead of just road blocking us.

@tcanelli
IT guys have 2 words in their vocabularies: (1) No and (2) Not possible without even knowing or eager about what will be or is being asked. And they have a huge paranoia that every tiny hacker in the world is waiting to attack their system LOL. So may God save your soul with them

Lol so very true!

The way I set up the app was simply to have a form with the finish view hitting a home page that has links to various websites for info. But now you guys have scared me off using the same table as the private app. Whatโ€™s the best solution to have a form for the public that collects the data and then copies or moves that data to another table that staff can access? Will that be the webhook?

@tcanelli
You can only have a simple ADDS_ONLY form in your public app and the recorded data can be easily pushed to your ADMIN app via AppSheet API. Quite easy, no worries.

@tcanelli When you are dealing with the public app, please remember one thing. Every table you have in that public app, are open for everyone. Slices or hiding columns doesnโ€™t help that situation. When itโ€™s public, it really means everything is public. For exampleโ€ฆ if you use public app for registering, everyone will have the possibility to see what your users have filled. Thatโ€™s one reason why we should have a way to filter that data but Iโ€™m afraid thatโ€™s not possible at this moment.

@Aleksi Even if I dont provide any view other than a data entry form?

@tcanelli When the data is in userโ€™s device, itโ€™s not secured.

@Aleksi if we do what @LeventK suggested would there be any data on the users device other than their own data they just entered?

@tcanelli
After the data of the public app is transferred to your admin app, we can delete the data from the public app, if thatโ€™s a concern.

@tcanelli
itโ€™s very easy to test. Just open your public app on a full preview mode. As per your design it shall open with your form or any other view you have chosen to show. Now edit the URL, and change it like this:

https://www.appsheet.com/start/AppId#appName=AppName-AccountID&table=TableNameThatYouDontShow

Hello, is anyone aware if Appsheet has done anything to prevent this happening to public apps (ie table data being available using the link path below?) - https://www.appsheet.com/start/AppId#appName=AppName-AccountID&table=TableNameThatYouDontShow 

 

Nope. That's why the app is called "public".

@tcanelli When the user saves the form, the app will sync and read the data from the backend and then that device is updatedโ€ฆ so it wonโ€™t help.

Sorryh I hadnโ€™t seen this thread earlier. Seems like I missed a lot :]

As background, Tammiโ€™s already using their (cloud-based) SQL database for their secure apps. This has already been blessed by her IT team. So AppSheet connecting to their database is not by itself an issue.

The question here is: thereโ€™s going to be a second AppSheet app connecting to the database and the app itself isnโ€™t secure (it is public). So what bad stuff could happen?

  1. The app creator (Tammi) could make a mistake and allow the users to update/delete data.

  2. The app might expose information to the end-users that should not be exposed

  3. A large number of users might use the app at the same time and overload the SQL database

For #1 and #2, the mitigation is pretty simple. The SQL database admin should create a SQL user with very limited permissions in the SQL database. Just give that SQL user the ability read the minimal tables needed and write the minimal tables needed. Then use that SQL user to set up a data source in the AppSheet account. This ensures that no matter what the app allows, the database will only show and allow updates to specific data in specific tables.

It would be a good idea to have different tables in the database for the public app and the private app. If you need every update done via the public app to also update the data for the private app, it is easy to do with a SQL trigger. Your IT folks can set that up easily enough.

I think Leventโ€™s suggestion of using the AppSheet REST API is to achieve the same outcome, but do it via an AppSheet workflow rule (our version of a โ€œtriggerโ€) instead. To be honest, it is better to do it in the database โ€” much more efficient that way when there is the mechanism. If you were using a Google Sheet or something, then the AppSheet workflow solution is better.

For #3, it is a more complex response. In theory, a large number of users could all sync at the same time and overwhelm your SQL database. In practice though, AppSheet is starting to throttle the number of concurrent users per app. So I suspect this will not be an issue for your SQL database. However, make sure to provision the database to have enough capacity for your planned peak load (sometimes you can get a cloud-hosted SQL databse but it is on a shared machine and with a very low resource allocation โ€” so very cheap but also doesnโ€™t handle a lot of scale).

Hope this helps. Tammi, please feel free to engage us when you have your conversation with IT. I donโ€™t think this is a freak-out worry situationl. More like a situation that needs some planning and it will be fine.

@praveen
This is an awesome response! Thanks on my behalf!

Meeting with IT went well! I was asked to inquire about SQL injection (?) and what, if anything, does Appsheet do to mitigate this. @praveen, @LeventK

Any info I can provide to them would be appreciated. Thanks

Hello @tcanelli
SQL Injection (SQLi) is a type of an injection attack that makes it possible to execute malicious SQL statements. These statements control a database server behind a web application. Attackers can use SQL Injection vulnerabilities to bypass application security measures. They can go around authentication and authorization of a web page or web application and retrieve the content of the entire SQL database. They can also use SQL Injection to add, modify, and delete records in the database. So I believe your IT team wants to learn how AppSheet mitigate risks.

Though @praveen will reply this better than me, but thatโ€™s one of the main reasons why AppSheet donโ€™t want to deal with the user authentication and hence uses cloud providersโ€™ authentication mechanism.

@LeventK - they were asking me if there is a way to prevent special characters frequently used in sql commands from being entered/saved on the forms. Plus anything else that could mitigate these types of attacks. Is there?

@tcanelli
You can restrict using special characters simply setting an expression in Valid_if i.e.:

NOT(CONTAINS([_THIS],{"@" , "-" , "." , "," , "+" , "=" , "*"}))

But actually, you shouldnโ€™t need to mitigate SQL injection that way. Any SQL queries are constructed by AppSheet code. And they are constructed as parameterized queries rather than as textual queries. If any user inputs are passed as parameters, it prevents SQL injection attacks.

-praveen

To support @praveen, I want to detail a bit what parameterized query means:

A easier-to-understand, and a more general answer goes like this:

Imagine a dynamic SQL query:

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND Pass=' + password

A simple SQL injection would be just to put the Username in as ' OR 1=1--

This would effectively make the SQL query:

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS=' + password

This says select all customers where their username is blank ( '' ) or 1=1 , which is a boolean, equating to TRUE. It then uses -- to comment out the rest of the query. So this will print out the entire customer table, or enable you to do whatever you want with it.

Now parameterized queries do it differently, with code like:

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?' parameters.add("User", username) parameters.add("Pass", password)

where username and password are variables pointing to the associated & entered username and password. Now at this point, you may think, this doesnโ€™t change anything at all. Surely you could still just put into the username field something like Nobody OR 1=1'--, effectively making the query:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND Pass=?'

And this would seem like a valid argument. But, you would be wrong. The way parameterized queries work, is that the SQL query is sent as a query, and the database knows exactly what this query will do, and only then will it insert the username and passwords merely as values. This means they cannot affect the query, because the database already knows what the query will do. So in this case it would look for a username of Nobody OR 1=1'-- and a blank password, which should come up false.

For further info, you can refer to this page > How To: Protect From SQL Injection in ASP.NET

We have issue with a public app that is built to capture data via form only - it has 2 sensitive data tables linked to the app - one database to be used for valid if dropdowns, the other to be used for email notifications. both the tables contain sensitive data in other columns and confidential - we cannot have a security filter on the public app as the app does not allow it, we need another solution if anyone has any ideas please?

Are you able to use this option?
3X_a_6_a6c13e8d89838e9af0933b154e0f4b0638892eca.png

Hello, yes we can for the data collection table, but it is the other 2 tables that contain sensitive data that we need to use for a dropdown in the form, we just need to use 2 or 3 columns from that table as the valid if dropdown in the form. But all the other information is sensitive

Can you just pull those 2 or 3 columns into a new Google Sheet with IMPORTRANGE() ?

Thanks that could be possible, although we are currently using Smartsheet

Canโ€™t you just create a slice which only includes those fields you require in the dropdown and then point the drop down to the slice?

No. Slices donโ€™t remove the sensitive data from the device. On a Public app, there is no way to limit the data being loaded onto the device, unless that data simply doesnโ€™t exist in the loaded Tables.

Top Labels in this Space