Security
Dynamic Selects fetch (using ajax) and display data in the dropdowns based on the ID of the item selected in the trigger dropdown. For frontend use, this is a potential security issue. However, the visibility of the ID itself does not present any security issue. ProcessWire itself references page IDs when returning assets such as files and images. In addition, the IDs of various core ProcessWire pages (admin, setup, trash pages, etc) are public knowledge. Of concern to us is the potential manipulation of markup (e.g. using a browser's dev tools) generated by Dynamic Selects by a malicious user in an attempt to trick the module to fetch and return data (pages, users, fields or templates) that that user is not authorised to view. To guard against such manipulation, Dynamic Selects ships with a number of security features. These are noted below as well as best-practices which you need to follow when setting up the module for frontend use.
In-built Security Features
- Dynamic Selects does not fetch nor display ProcessWire admin pages.
- Dynamic Selects skips, hence does not display, data from password, roles and permissions fields.
- Dynamic Selects does not display data about system templates and superusers.
- Dynamic Selects does not fetch nor display unpublished or hidden pages.
- Dynamic Selects does not fetch nor display data of pages whose templates have access controls in place in cases where the current user has no access.
- By default, each Dynamic Selects in the frontend is only displayed to Logged-in users. Alternatively, these can be set up to be viewable only to users with the permission 'dynamic-selects-front-view'.
- For frontend use, Dynamic Selects always caches the valid server-side data to be displayed in the first/initial select/column.
Best-practices: Using Dynamic Selects in the Frontend
- If possible, ONLY allow users with the permission 'dynamic-selects-front-view' to view frontend Dynamic Selects or at least Logged-in users. Please refer to this section on how to set this up.
- Make extensive use of include/exclude templates/pages/fields to filter-out/in data that will be displayed in your Dynamic Selects. For instance, you can use a range of IDs to block out pages that should not be shown in the selects. Remember though, as noted above, unpublished, hidden and template-access-controlled pages data will never be returned (whether as a trigger or a dependent column) in Dynamic Selects.
- If 'Users' has been selected as the data in the first/initial dropdown, it is highly recommended that you add ProcessWire's Title field to the 'user' template and use that to input your users' titles. Dynamic Selects will first attempt to use a title and if one is not found, will use the user's name as data for that dropdown. Since users names are used for logging in, this is not desirable. Ideally, you should avoid setting up a 'Users' Dynamic Selects in the frontend.
- Give any fields that will be listed in Dynamic Selects columns/dropdowns of relationship Field or User: Property labels. Otherwise, the field names will be displayed instead.
- Always test your Dynamic Selects before deploying them. This is also applicable to backend Dynamic Selects. Testing ensures that the Dynamic Selects return the data you expect them to.
- Related to the above, when testing frontend Dynamic Selects, make use of the debugging feature to easily see the returned results and their IDs.
Please note that the above (security features and best-practices) apply to the columns/selects in a Dynamic Selects whether it is a trigger or dependent select or both. This means that the module cannot be tricked into accepting an invalid trigger in order to return its data (so-called trigger select manipulation). It also means that for valid triggers, it will also only return data that the user is allowed to view (so-called dependent select fidelity).
In summary, given the above in-built security features, when it comes to pages and templates, frontend users (including guests) will only ever see pages that they are authorised to view. Since unpublished, hidden and template-access-controlled pages are never returned, any other pages you may not want them to see will be because of convenience and not security. Beyond these though, you have the powerful include/exclude settings at your disposal. For selects that return fields, it is imperative that you limit the fields to be displayed (if necessary) by using include/exclude fields settings.