This document outlines the comprehensive security controls implemented in the Mirrexa Salesforce application to ensure compliance with Salesforce AppExchange security review requirements and enterprise security standards.
All Apex classes implement proper Create, Read, Update, Delete (CRUD) permission checks before performing any data operations.
Implementation Pattern:
// Check object accessibility before SOQL queries
if (!Schema.sObjectType.PermissionSetAssignment.isAccessible()) {
throw new AuraHandledException('Insufficient permissions to access Permission Set Assignments');
}
// Check object permissions before DML operations
if (!Schema.sObjectType.PermissionSetAssignment.isCreateable()) {
throw new AuraHandledException('Insufficient permissions to create Permission Set Assignments');
}Applied to:
MirrexaAdminController.cls- All SOQL queries and DML operationsMirrexaApiService.cls- User and Organization object access- All permission set assignment operations
All field access is validated before reading or writing field data to ensure users can only access fields they have permission to view.
Implementation Pattern:
// Check field-level security before accessing fields
if (!Schema.sObjectType.User.fields.Username.isAccessible() ||
!Schema.sObjectType.User.fields.Email.isAccessible()) {
throw new AuraHandledException('Insufficient field permissions for User records');
}Applied to:
- User fields:
Id,Username,Email,Name,IsActive - PermissionSetAssignment fields:
Id,AssigneeId,SystemModstamp - PermissionSet fields:
Id,Name,Label,Description,Type - NamedCredential fields:
Id,DeveloperName - Organization fields:
InstanceName
All Apex classes use with sharing to enforce record-level security:
public with sharing class MirrexaAdminController {
// Class respects user's sharing rules and record access
}
public with sharing class MirrexaApiService {
// Class respects user's sharing rules and record access
}The Mirrexa_App_Access_2GP permission set follows the principle of least privilege:
<objectPermissions>
<allowCreate>false</allowCreate> <!-- No create permissions -->
<allowDelete>false</allowDelete> <!-- No delete permissions -->
<allowEdit>false</allowEdit> <!-- No edit permissions -->
<allowRead>true</allowRead> <!-- Read-only access -->
<modifyAllRecords>false</modifyAllRecords>
<viewAllRecords>false</viewAllRecords> <!-- No view all access -->
<object>UserExternalCredential</object>
</objectPermissions>All user inputs are sanitized to prevent SOQL injection attacks:
// Sanitize input to prevent SOQL injection
String sanitizedSearchTerm = String.escapeSingleQuotes(searchTerm.trim());
if (sanitizedSearchTerm.length() > 255) {
throw new AuraHandledException('Search term too long');
}Strict validation patterns for all user inputs:
// Salesforce ID format validation
if (!Pattern.matches('[a-zA-Z0-9]{15}|[a-zA-Z0-9]{18}', userId)) {
throw new AuraHandledException('Invalid User ID format: ' + userId);
}
// Template ID format validation
if (!Pattern.matches('[a-zA-Z0-9_-]{1,50}', templateId)) {
throw new AuraHandledException('Invalid template ID format');
}Protection against resource exhaustion:
// Limit bulk operations to prevent resource abuse
if (userIds.size() > 200) {
throw new AuraHandledException('Cannot process more than 200 users at once');
}All external API calls implement security best practices:
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:Mirrexa_API/api/user');
req.setMethod('GET');
req.setHeader('Content-Type', 'application/json;charset=UTF-8');
req.setTimeout(30000); // 30-second timeout to prevent hanging requestsAll API responses are validated before processing:
if (res.getStatusCode() >= 200 && res.getStatusCode() < 300) {
String responseBody = res.getBody();
// Validate response is not empty
if (String.isBlank(responseBody)) {
throw new AuraHandledException('Empty response from Mirrexa API');
}
// Validate JSON format to prevent malformed data processing
try {
Object parsedResponse = JSON.deserializeUntyped(responseBody);
return responseBody;
} catch (JSONException e) {
System.debug('Invalid JSON response from Mirrexa API: ' + responseBody);
throw new AuraHandledException('Invalid response format from Mirrexa API');
}
}Secure authentication using Salesforce Named Credentials:
- OAuth 2.0 flow for user authentication
- Encrypted credential storage
- Per-user principal access control
Error handling preserves security exceptions while gracefully handling unexpected errors:
try {
// Business logic with security checks
} catch (AuraHandledException e) {
// Re-throw validation and security exceptions
throw e;
} catch (Exception e) {
// Log unexpected errors without exposing sensitive information
System.debug('Error in operation: ' + e.getMessage());
result.put('error', 'An unexpected error occurred');
}- Security violations return appropriate error messages
- Sensitive information is never exposed in error messages
- Debug logs contain detailed information for troubleshooting
- No personally identifiable information is stored locally
- All user data is accessed through Salesforce's secure APIs
- External API calls use encrypted HTTPS connections
- No persistent data storage outside of Salesforce
- Temporary data is processed in memory only
- External API responses are not cached
Comprehensive security test suite validates all security controls:
MirrexaSecurityValidationTest.cls- Core security pattern validationMirrexaSecurityTest.cls- Integration security testing- SOQL injection prevention testing
- Input validation testing
- Bulk operation limit testing
- Exception handling testing
# Run security validation tests
sfdx force:apex:test:run --tests MirrexaSecurityValidationTest --result-format human
# Run comprehensive security tests
sfdx force:apex:test:run --tests MirrexaSecurityTest --result-format humanExternal API access is restricted to necessary endpoints:
https://api.mirrexa.ai- Mirrexa API endpoint (HTTPS only)
- Minimal OAuth scopes
- Per-user authentication
- Secure token handling
- Manual assignment required
- No automatic permission escalation
- Regular access review recommended
- Security exceptions are logged for monitoring
- Failed authentication attempts are tracked
- Unusual API usage patterns are logged
- All permission set assignments are tracked
- User access changes are logged
- API usage is monitored through Salesforce logs
This implementation meets the following security standards:
✅ Salesforce AppExchange Security Review Requirements ✅ OWASP Top 10 Web Application Security Risks ✅ Principle of Least Privilege ✅ Defense in Depth ✅ Secure by Design
- CRUD/FLS checks implemented on all data operations
- Input validation and SOQL injection prevention
- Proper sharing model (
with sharing) - Least privilege permission sets
- Secure external API handling
- Comprehensive error handling
- Security test coverage
- Documentation and code comments
- No hardcoded secrets or credentials
- HTTPS-only external communications
- Regular review of permission sets and access controls
- Monitoring of Salesforce security advisories
- Updates to input validation patterns as needed
- All security-related code changes require review
- Security patterns must be maintained in new features
- Regular security audits recommended
Document Version: 1.0
Last Updated: 2025-08-13
Next Review: 2025-11-13