We've been trying to work through exactly what is the proper way to hide Disco elements. I've come up with a list of different scenarios of why you might want to hide an element, and outlined the best practices for each scenario.
|Remove an element – it's not needed, shouldn't be visible to and doesn't need to be accessed.||$disco->remove_element() is the proper way to go for this, though using the cloaked type is probably acceptable from a security standpoint, as it doesn't leak data to the user.|
|Make an element invisible, but available as data on server-side via disco->get_value().||Use the cloaked type. If you don't mind the person viewing page to be able to see data via view_source, an unalterable hidden field would also be acceptable. (See notes below)|
|Make an element invisible even when viewing source/checking DOM, but still available via disco->get_value().||Use the cloaked type.|
|Make an element invisible, but available as data on the client side (js access to value).||An unalterable hidden field would work for this. See the notes below regarding hidden fields.|
|Pass along data available at start of process but later unavailable, or to "fix" something that changes over subsequent page loads (like the date/time the first form was called up, for example).||An alterable hidden field is an acceptable type for this. (See the notes below regarding hidden fields.) If it it important that the user not be able to fiddle with this data, however, it would probably be better to store it somewhere other than disco, like in a session.|
|A place where js can place or change data to be passed back to server on submission.||An alterable hidden field is the proper type for this. See the notes below regarding hidden fields.|
Notes on hidden fields
At the moment, hidden fields are alterable – they can change their value in userland, or pass their value across multiple submits of a form even if different values are set in php. However, because fields have often been hidden in an attempt to prevent users from changing them, this can present a security issue if a developer hides a field but does not realize that the value can still be changed by a crafty user.
Because of this situation, and because the vast majority of hidden fields in Disco forms appear to be intended to prevent users from editing the fields (in addition, of course, to preventing the fields from being seen) the alterability of hidden fields in Disco has been deprecated since Aug. 2008.
The question at this point is whether to:
- As originally planned, to create a new hidden_alterable plasmature type to support those fields data does need to come in from userland, add a parameter to the hidden type that allows it to accept said data, or
- to reverse direction and leave the standard hidden type as the alterable one and add a new hidden_unalterable type (or add an an unalterable parameter to the hidden type), or
- to deprecate the hidden type entirely, and force devs to update their code to use either hidden_unalterable or hidden_alterable.
The advantage of #1 is that it makes the hidden field behave in roughly the way people seem to generally expect, and in the more secure way. It forces developers to actively choose the less secure method, at which point the presumably realize that the value can be changed in userland. It also is likely to mean less work for developers, as they only have to change those few cases where they want the hidden value to be updated from userland. The disadvantage of #1 is that is changes existing behavior, and could potentially break existing code in subtle and surprising ways. Sensible error handling around attempts to change values in userland could help make these failures less subtle, however.
The advantage of #2 is that code continues to behave the way it always has, and therefore nothing is likely to break. However, it puts the onus on developers to remember to use the new, less memorably named plasmature type in the majority of cases, and there are no security benefits unless developers update their code to use the new type.
The advantage of #3 is that it forces developers to acknowledge the issue when the change occurs and to consciously select one or the other type of hidden field going forward – there can be no false assumptions about the (ambiguous) behavior of the hidden field. The disadvantage of #3 is that developers would have to do the work to update all the code that specifies hidden fields, and would have to change their habits regarding the specification of hidden fields.
So... the question is, what should we do with the hidden field API? are there other scenarios you think should be added to the scenario table above? You can leave comments here, or send an email to email@example.com.