T09 · Insecure Skill Coding Practices
- Location
references/models-api.md:143- Finding
Salesforce Apex examples perform database operations without consistent CRUD and field-level authorization enforcement
- Content
View full analysis
cases = [ SELECT Id, Subject, Description FROM Case WHERE Id IN :caseIds WITH USER_MODE ]; List toUpdate = new List(); for (Case c : cases) { try { // Generate summary using Models API String summary = generateCaseSummary(c); if (String.isNotBlank(summary)) { c.AI_Summary__c = summary; toUpdate.add(c); } } catch (Exception e) { System.debug(LoggingLevel.ERROR, 'AI Summary Error for Case ' + c.Id + ': ' + e.getMessage()); } } // Update records if (!toUpdate.isEmpty()) { update toUpdate; } } ``` The Opportunity batch example performs both its query and update without user-mode enforcement: ```apex public Database.QueryLocator start(Database.BatchableContext bc) { // Query records needing AI summary return Database.getQueryLocator([ SELECT Id, Name, Description, StageName, Amount FROM Opportunity WHERE AI_Summary__c = null AND Description != null ORDER BY CreatedDate DESC ]); } public void execute(Database.BatchableContext bc, List scope) { List toUpdate = new List(); for (Opportunity opp : scope) { try { String summary = generateOpportunitySummary(opp); if (String.isNotBlank(summary)) { opp.AI_Summary__c = summary; toUpdate.add(opp); success ...[truncated 2744 chars]- Remediation
View remediation
opportunities = [ SELECT Id, Name, Description, StageName, Amount FROM Opportunity WHERE AI_Summary__c = null AND Description != null WITH USER_MODE ]; ``` 2. Use user-mode DML rather than default system-mode DML: ```apex Database.update(toUpdate, AccessLevel.USER_MODE); ``` 3. Where user-mode operations cannot be used, verify object and field permissions explicitly: ```apex if (!Schema.sObjectType.Case.isUpdateable() || !Schema.sObjectType.Case.fields.AI_Summary__c.isUpdateable()) { throw new SecurityException('Insufficient permission to update the AI summary.'); } ``` 4. Apply equivalent checks to every field read from Case, Opportunity, and Account. 5. Use `Security.stripInaccessible` as an additional defensive layer before DML or serialization. 6. Ensure every externally reachable entry point validates record identifiers and authorization before enqueuing asynchronous work. 7. Add negative authorization tests using users who lack access to the queried source fields and `AI_Summary__c`. ]]>
