Dear all,
I've recently stumbled upon (too) many cases where some apps has been customized with object-based api calls on the front-end (ergo: with Javascript).
I've noticed it in a couple of cases where I had access to the code by the app owner, and then I've decided to run a research. (not really) Surprisingly, in a 10 minute effort of serching on the internet, I've managed to collect 10 API-KEY/APPID valid pairs because the developers left those information directly in the code.
Now, considering that:
- Only with the appID you can get the WHOLE app structure (which is something I don't completely understand);
- That even if you embed a knack blank page in a website you can still access the WHOLE custom Javascript and CSS code;
- That if you have the pair AppID+API-KEY you can make some real damage;
- That is easy as (almost) searching on google to find websites that embeds knack apps;
I think many apps are actually under a very high security risk and should be fixed asap.
We should all put as much effort as possible to discourage the use of object-based requests through Javascript (and other front-end languages) and put some more effort in publishing, when we are doing so, only view-based examples so that the less experienced users that are more keen to copy/paste will copy/paste legit code.
Of course object-based request are a lot more fun and easy to implement, but with a clever use of display rules you can make very complicated and nested custom operations without exposing your api key (and when you want to GET information, without even making an API call at all).
To the knack staff, I'll request as a feature, a big red message to show up in the builder in those app that has the api-key exposed. This is already a deterrent for developers to take this very wrong path.
P.S. Even if it might look silly or I might look paranoid I can assure that someone with the right motivation and not even much skills, could easily take advantage (or maybe is already!!) of such a security breach. I've seen this before.
Think about how many knack apps are used to treat highly sensitive data (health, education, children,..) and you'll agree with me that we have to take an effort also as a community, to mitigate such risk of data leak or manipulation.
Davide
Craig, I do agree that whatever you do through Javascript is volatile and can be modified at runtime by a not-even-so-skilled script kiddie, but what I meant with the "clever use of display rules" was strictly related to API calls.
What I usually do, is to create views that are used only for API calls (sometime within the same scene I'm calling the API from, sometimes when I have many, I create a proper page structure just related to API calls). Through page rules, I then hide all those views with a always true condition (ex: if logged in user is any or whatever) so that the view is actually hidden before the scene being rendered (and therefore not visible in the source code). So I have my tables (for GET & DELETE) and my forms (for POSTs and PUTs) which I can call through ajax without using the API key and without having a malicious user to interact with those.
For other cases where I need to get information for something custom and I want to avoid API calls in general (for a matter of API limits and general delays), I usually create tables where I hide, through a rule, the value of specific columns and then I check the "hide empty columns". So, when the view is rendered I can still access all the payload, but it won't be visible to the end user. This is the way I am programming knack lately, reducing to the minimum the GET calls (since I can get this information in the above way) and having hidden views for DELETEs, PUTS, and POSTs.
Do you have any further suggestion to share?
The problem with "but with a clever use of display rules you can make very complicated and nested custom operations without exposing your api key" (quote from earlier post in this thread) is that a talented (or determined) user can make these same operations and completely invalidate your data while it is written to the database.
Let's say I write some client-site JS to hide a few options in a choice box - because I don't want the user to see or select them. Then a 'malicious' user comes along, hits F12, stops the code, changes the values, and then lets the program continue with the invalid values. Now the values which I didn't want written can be written to the database, and no audit trail or validation exists.
Additional server-side validation would stop this monkeying around before the database is mucked up.
It really is unfortunate that developers read these docs and still don't realize that the key is public if it's placed in the 'javascript' part. (and don't understand that this is really a skeleton key ... it opens up everything)
That said, it would be super-nice if Knack provided a server-side javascript editor so that we can safely include javascript object-based manipulation in our code without having to hoist our own server-side functions. Many folks use IFTTT or Integromat or maybe Microsoft's Power Automate (Flow), but it would be fantastic if we could build our server-side event handlers or logic right in the Knack interface for additional validation or manipulation.
Thanks Davide,
My thoughts on this are similar in that view requests have been around for a few years now and as a community we should be supporting their use over object based code. I do think it's a quirk of history that object based requests for Knack existed well before view requests and therefore some of the examples written back then have been promulgated to recent times - the table checkbox is a good example of that: https://support.knack.com/hc/en-us/community/posts/115002418991-Checkboxes-in-Table-Update-Knack-Send-to-Webmerge
While not being alarmist a major breach from this route might cast the Knack platform in a negative light - when it is the user of the tool exposing AppID/key pairs at fault. That's something I'm sure none of us want to see ever happening.
It must be noted that the documentation for API has been updated around this issue, and it's made very clear when to use object requests: https://www.knack.com/developer-documentation/#object-based-requests
I do like your idea of a warning when object requests are used in the Knack Javascript sandbox.
Brad