To prove that a dynamic SOQL query is safe from injection because its variables are derived from secure sources, follow these steps:
1. **Use Bind Variables**: Incorporate user-supplied input securely into the query using bind variables. This ensures the input remains within its quoted context.
2. **Sanitize Input**: If bind variables aren't an option, sanitize input with methods like `String.escapeSingleQuotes()`. This is suitable for simple string comparisons but should be combined with other methods for full protection.
3. **Validate Object and Field Names**: For user-supplied object or field names, validate them against a whitelist of acceptable values. Use `Schema.getGlobalDescribe()` to retrieve valid names and confirm user permissions.
4. **Enforce CRUD/FLS Checks**: Ensure the user has the necessary permissions for the objects and fields being queried by enforcing Create, Read, Update, and Delete (CRUD) and Field-Level Security (FLS) checks.
5. **Avoid User-Generated Queries in Apex**: Avoid executing user-generated queries in Apex, as they bypass user permissions. For complex queries, consider using the REST or SOAP API.
6. **Review Query Context**: Sanitize parameters and validate permissions for all public methods containing database operations.
By implementing these practices, you can demonstrate that your dynamic SOQL query is secure and free from injection risks.