Generate Key-Value Pairs using Form Data

This concerns a quality-of-life improvement, but also potentially a security concern.

With large forms, one is tempted to simply use an Object and refer tot the form, as follows:

Form.data

While this is convenient from a DX perspective, it does introduce some potential vulnerabilities in regards to mass assignment. Any value in the form will be considered to be valid and although I haven't tested this out, I assume there is no safeguard or validation in place to check against any unintended values (?)

In any case, one way is mitigate this, is to be very intentional/strict on what columns and values to allow to be inserted in the database. The way to do so is using key-value pairs. But this quickly becomes a pain when you're dealing with countless columns. Making a mistake or missing something is overlooked quite easily.

Therefore I would advocate in favor of using a "Generate" button to have the form's keys automatically be set. That way, you're confident you're using all of the right columns and not potentially allowing users to add anything either.

This "Generate" button (a lightning bolt, perhaps?) would be included at the end of these buttons:

example

Anyway, I hope you'll take this into consideration.

Thanks :wave:

1 Like

Hey @emozio,

Definitely agree that the "Generate" button would really improve quality of life.

With regards to which values are added to form.data, you just simply need to leave "Form data key" empty within the component that doesn't need to be included in form.data:

But I'm guessing this may not be exactly what you're after in terms of security.

1 Like

My main concern when it comes to the security aspect is that when one simply accepts an object of values (rather than being specific on which key-values are used), then you assume that the user is providing this object using the interface.

However, since this is essentially just a bunch of JavaScript, I could imagine that this might introduce a potential vulnerability: after all, this object could be anything, so why not inject some variable like is_admin or something similar.

Coming from a Laravel background, there is this common pattern known as fillable on each model that allows you to keep certain columns outside of the scope of editing. This is essentially a simple form of validation - which is missing in the Retool interface.

Anyway, I really think someone with a security background should look into this and make sure that I am proven wrong here. :wink:

Thanks :wave: !

P.s. Responding with "user responsibility" seems naive, since users would need to add database-level security which is not always easy - and can differ per situation, after all.

1 Like

Hello @emozio!

I can definitely make a feature request to add in form validation!

In terms of building a form with a lightning bolt symbol as you were theorizing, we have a product called Retool Forms that does this!

This is a stand alone product that was built with the purpose of the tool being a form that is separate from the 'in app form' with a limited scope if just being submittable by end users to create and push data to the database table it is connected to.

It has a sharable link and I believe since it is built off the DB schema it does enforce typing restrictions on the inputs users can enter in. Let me know your thoughts on how the Retool Form can fit into your use case and I will get on adding in something that mimics the Laravel fillable pattern for the in app form components! :saluting_face:

Hello @Jack_T ,

Another apology for the late response.

I wasn't quite referring to the process of building out a form, but rather using those form values to fill out a query instead, As you can read, most users will probably resort to using {{ Form.data }} to automatically collect any form variables (why? it's efficient, for sure). However, I think this could have security ramifications, since there is no check which values may actually be collected.

A concrete and practical example is a user profile form. If my database table, called "users", contains a column named "is_admin", I do not want regular users to fill this field in, correct? Well, if I update a user using the {{ Form.data }}, then I have no way of knowing if users may have included the is_admin column from their developer tools, i.e. by resending the XHR request and modifying data,

This is an very common issue and I was primarily wondering if this should be a concern for this usecase. Would you be able to forward this suggestion/question to the people who are involved in security?

Thanks. :wave:

1 Like

No worries, thank you for the example this makes a lot more sense now :sweat_smile:

Can definitely forward this concern to the security and forms team. As I agree, the tools are built around the ease of use of doing {{ Form.data }} but we need to make sure that security concerns are addressed to keep users from altering data that they shouldn't be since they are effectively exposing the entire ORM/schema.

Any news on this? Just ran a few tests myself and seems like this is a pretty significant security issue if you're relying on Form.data alone. :fearful:

If there is a bug bounty involved, I would have to share it with my colleague who mentioned the sensitivity of variable front-end input in the first place. :wink:

1 Like

One way to mitigate this issue is by providing a UI option to "filter data by available form keys." In other words, a column is only accepted as a value if it matches a key that is available inside the form. While validation remains a separate concern, this at least ensures that the user cannot tamper with the keys (columns).

However, since we have been using dynamic (i.e. using variables) form keys (and for good reason, I assure you), whitelisting columns could prove to be technically challenging. I suppose the same option to "filter data by available form keys" could also be toggled to provide a manual list of column names. I suppose? That would allow the form keys to stay dynamic.

Finally, I think another tab called Security (next to "Advanced") would be a nice way to group these sort of things. I could also imagine this area supporting (back-end) validation, like checking certain values, if a user is allowed to run a certain query, etc. Just a thought.

:wave: Hope this helps.

@Jack_T

1 Like

Hi @emozio,

I agree that the use of Form.data can open up a query to having additional data sent to the database. Which could be malicious, based on how the data being sent in is mapped to the columns of the DB.

I can definitely elevate this with our security team.

A "devil's advocate" counterpoint would be that for internal teams and their tools, the permissions and permission grouping for the resource and query, as well as edit privileges of the app should be the front line for only giving access to trusted users within an org.

Given that to alter a form to have extra 'unintended' fields would require app edit privileges, and at that point someone could do a lot more.

With external apps I would image that users of the app should not be able to edit a form and can only fill in the input fields given to them.

I really like the idea of "filter data by available form keys" and an added "Security" tab! Will bubble this up internally as well :saluting_face:

1 Like

Hello @Jack_T ,

I'm glad you're taking this seriously and have communicated this towards the devs at security.

You mentioned "extra fields", but that is not the place a hacker or any other person with wrong intent would take their swing. They would simply resend the XHR request while adjusting the body (JSON). That way, they can simply add columns, edit values, etc. I managed to do so yesterdsy, i.e. providing a value to a column that I had never specified, neither as a field or a value in the query.

While people inside the org normally don't do these things, you never know for certain. At the bare mininum, I think your users should be aware of the risks that come with accepting the Form.data (via a warning of some sort), and a mitigation would be an added bonus, in my opinion.

:wave: Hope this helps specify the issue further.

1 Like

Ahhhh I see what you are saying. Thank you so much for elaborating on the resending of the XHR request with an altered JSON payload!

Will ensure that the engineers understand this and the risks to get it fixed ASAP.

2 Likes