LCS - Best Security Practices
This document is to assist developers in explaining how and when to meet the minimum security requirements by offering best practices.
The Low Code Solutions minimum security requirements can be found here. Before setting an application to Live in Production developers should complete the Pre-launch Checklist to ensure that the minimum security requirements have been met.
- Authentication
- Authorization
- Actions
- Data Models
- Data Application Programming Interface (API)
- Pages
- API (External Data Source) Usage
- Miscellaneous:
Authentication
- All application authentication will be provided via Single Sign On (SSO).
- Once authenticated, all users should be assigned a Betty Blocks (BB) role.
- UW Applications should use manifest for all role-based authorization mapping.
- See LCS - Configuration of Manifest groups for application role mapping for more details.
- Following the principle of least privilege, the default role assigned to authenticated users should not provide more than the minimum appropriate level access to the application.
- An Admin role assigned to specific users should only be used to provide more expansive access to the application. The Admin role should not be used as the default role assigned to most users.
- Do not modify the SSO Actions and Pages. Doing so will nullify your application’s extended warranty.
- Every private page should have an Authentication Profile set on it in the Page Settings panel.
- For pages that should be restricted to specific role or set of roles, follow the Low Code Solutions (LCS) page security guidance to ensure the proper controls are in place.
- See LCS - How to Secure a Page for more details.
- Authentication timeout requirements should meet UW System Authentication policy requirements.
Authorization
- Create at least one additional role in the Tools > Roles and Permissions application settings beyond the default Public and Admin roles.
- Your non-admin users should be assigned this role, even if you have no other roles necessary in your project requirements.
- The Admin role should be reserved for only administrative access, such as Backoffice pages, or be left unused for applications which do not currently require a separation of roles.
- Authorization for page access should be done via role and not with a specific user’s credentials, even if only one user will be accessing the contents of the page.
- Users can only have one role in a BB application. Be cautious with how you assign roles to users to ensure that the correct users have rights to the appropriate data, actions, API calls and pages.
- Each private page should include a role authorization data container at the top level of the page objects in the object hierarchy specifying which role or roles can access the contents of the page.
- Backoffice pages must contain a top-level role authorization data container in the page object hierarchy that restricts access to the appropriate role or roles.
- Private pages available only after a login via SSO don't need a role authorization data container unless you need to limit access to the contents of the page to a specific role that is not the default assigned to most users.
- Set data model read access in Tools>Roles and permissions to limit access to only those models that a role should be allowed to access.
- An example where a user would need limited read access to the data model would be a confirmation page that follows a data submission form. For the user to see data within the confirmation page, the role assigned to them should have read access to that data model but then filter that access to only the record created by the user in that session.
- The UW Template uses the BB Webuser role to store the user’s SSO profile and the application role that is assigned to the profile following a successful login for access to the live application. Note that this is different from the roles used inside the application to grant or deny access to the objects in BB.
- You can create additional user profile roles beyond the Webuser to fit your project requirements.
Actions
- Capture the user information from the logged-in webuser in a user_id property in your application data model for all critical actions which might create, update or delete important information to document who did what.
- Use conditional action steps to make sure critical actions only run when certain criteria are met. For example, add a conditional action step to have the action only run when the “Stage” property on your model is set to the value “Stage 2”, or a user can only delete a record that they have created.
- Use conditional action steps or update properties to prevent an action from intentionally or maliciously being run multiple times. For example, you should prevent your enthusiastic or malicious users from submitting a form multiple times in an action that creates new records.
- If your action uses static values that might change, use a settings model or configuration variable instead of hardcoded values to store those values to avoid accidental use of the old data values. For example, store a list of CC’d email addresses in a settings model to maintain a list of system administrators who need to notified when an event occurs.
- Add the allowed roles to the description field of the action, especially for action that should only be executed by a specific role or with a specific data set. This will help the next developer follow your logic.
- Note that actions can be triggered directly from a web browser (maliciously or accidentally) via API call by users who have the role that is granted execute permissions on the action. This execution is possible without going through the appropriate page in the normal workflow/validation to trigger the action.
- Make sure your demo or test options can’t be manipulated to be run for normal actions with that demo or test data. For example, use a Universally Unique Identifier (UUID) for any demo/test records that is filtered in the action.
- Instead of using a record delete action, consider flagging a record as deleted, then filtering your data model records for those not with that deleted flag. Subsequently, use a scheduled action to delete flagged items after a certain number of days/years if the data are subject to the UW’s records retention policy or your business requirements suggest this is necessary.
- Use subactions with different role permissions carefully, since they may open up your data to unintended audiences with access to the parent action.
- Create a log data model for scheduled actions to help determine the status and last runtime, and to assist with fault tracking.
Data Models
- Use the Settings model to store and propagate site settings though the sandboxes instead of hardcoding values in actions or pages.
- Ensure only the correct roles have access to read each data model. The public role should not be granted default access to any data models unless necessary.
- Specify at least one required property in a data model to prevent null records from being created accidentally or maliciously.
- Consider that a user granted access to a data model will be able to see all properties in the data model. If that user should not see a piece of data contained in a property, use a separate model to contain that sensitive data instead, then create a relationship between the data models.
- Always specify a max file size and file type in your data models used to store files to prevent unnecessarily large uploads from uninformed or malicious users.
- All file uploads should be marked as private unless a specific use case can be justified. This prevents the URL of the uploaded file from being shared between users which will grant unauthorized access to the uploaded file.
- Consider using an Update action and isDeleted checkbox property to flag deleted data in data models instead of a Delete action if your users are allowed to delete data. Then, use filters to remove those records from display. This will allow for a restoration of data in the case of a mistaken deletion, and/or compliance with the UW’s records retention policy if it applies to your application.
Data Application Programming Interface (API)
- Access to an API should be granted via a dedicated authentication profile and dedicated API user account.
- The API Users should be provisioned and assigned a dedicated role, not a personal account.
- API user accounts must adhere to UW Password security policies for service accounts. (link to policy)
- API user credentials should be securely stored in the external service calling the API and never committed to a code repository.
- Actions being called via API must be secured to the authentication profile and role of the API service account.
- When transferring files from an external service to BB it is advised to use one of the following methods
- Base64 the file in the external service and send as a field in the input.
- Use a secure storage solution and generate a short-lived secure URL for BB to retrieve the file from. Example: a pre-signed URL from an encrypted AWS S3 bucket.
- Only models containing public or internal data should be used via the Data API without review and sign-off by the Office of Cybersecurity.
Pages
- Restrict page data and content filters by role and not specific users.
- Backoffice pages should use page-level data containers that are restricted to specific application roles (such as the Admin role) to protect record access.
- Test navigating to your role-restricted pages with an unsupported role that you assign yourself. Also, try navigating to your pages while not logged in to verify the security setup is working as expected.
- Don’t rely on hidden buttons or clickable menus as a security measure – rather restrict your pages by role access in filters set on data containers and other data elements.
- Test accessing the base URLs of each of the pages in your application with each of the roles to ensure that your page and data security match the sensitivity of the data it displays.
- Take note of what content flashes before being hidden when loading your pages if you are using conditionals to hide content from certain roles.
- Consider setting the “Hide child elements,” “Only render children when data is present” and “No cache” options where available in a component to avoid inadvertent temporary display of data.
- Don’t display sensitive or restricted data on your page without testing all roles in your application that might be able access the page or view the data.
- Set max file sizes on uploads and consider restricting file upload types to prevent misuse.
- Consider that if a user/role has read access to a record coming from a data model or API, they can read all properties on that record via the Graph QL call for the page prior to hiding any part of that data from the user interface.
- Use an onClick interaction to temporarily disable a submit button in a form in order to discourage impatient users from submitting multiple records. Then, use the onActionSuccess to re-enable the button if appropriate.
- Add “Required” attributes to form fields in your data gathering applications to prevent empty records from being added to your data model inadvertently or maliciously.
- To protect against guessing or indexing through unauthorized datasets or records via input page variables, use UUIDs to uniquely identify the record instead of the model’s ID when passing them in URLs.
- See LCS - Data Model Best Practices for more details.
API (External Data Source) Usage
- API Credentials should not be shared across applications.
- API credentials should not be hard coded into an action. Instead, use an application configuration to protect them.
- Ensure that proper read access roles and permissions are set on all remote models in your application.
- Be mindful of the sensitivity of the data in the API and ensure that data exposed to application users is secured to the proper roles and permissions authorized to view it.
- Consider that with the right API call from a web browser accessing your application, unauthorized users could perform actions that they do not and should not have direct access to.
- When making a new API integration, let the LCS Team know about the integration to ensure that they are aware of that connection.
Miscellaneous:
- Carefully remove old or unused roles, pages, actions and data models from your application.
- Before adding another developer to your application, consider the data they would have access to. All application records, configurations and connected APIs will be accessible to a low-code developer on the app. Avoid adding developers to the production level of the application to better protect production data that a new developer isn’t authorized to have access to.
- Applications should not enable iframe embedding from the Applications settings > security tab without prior contact with the LCS Team to determine if that is right for your application.
- BB will allow security vulnerability testing or PenTesting from 3rd parties provided they are contacted prior to beginning the testing.
- BB can perform a security review of your application if requested, although there may be a cost associated with this audit.