When querying records in Apex, the result includes raw values instead of a mask for encrypted fields even though the user does not have access to view the encrypted data. This results in a UI displaying actual data because the UI is using Apex.
Steps to reproduce :
- Create a new custom object named Sample
- Create a custom field on object Sample named Sensitive__c and set the type to Text (Encrypted)
- Create a new record in the custom object Sample and set the Encrypted__c field to the value TEST
- Save the record.
- Observe that if your profile don't have View Encrypted Data permission, you see a field mask on the field Sensitive__c on the detail page
- If you see the value TEST and you do not see the mask, Then your profile has View Encrypted Data permission.
- Remove View Encrypted Data permission from your profile so that field mask on the field Sensitive__c appear.
- Create a new Apex class named Sample with the below code
@RestResource(urlMapping='/Sample/*')
global class Sample {
public static List<SObject> getSObjects() {
return Database.query('SELECT Sensitive__c FROM Sample__c where Sensitive__c!= null Limit 10 ');
}
@HttpGet
global static String getSerializedRecords() {
return JSON.serialize(Sample.getSObjects());
}
}
- Invoke the get endpoint /services/apexrest/Sample/?getSerializedRecords
Expected: The response displays the **** mask for the Sensitive__c field
Actual: The response displays the unencrypted value TEST for the Sensitive__c field
Masking is not supported for Apex Serialisation. It is only supported for simple Classic View. We will have to use Field Level security to restrict the encrypted field access to the user. In case, FLS is already granted, We will have to implement our own field masking.
Sample Code to implement field masking
@RestResource(urlMapping='/Sample/*')
global class Sample {
public static List<SObject> getSObjects() {
List<SObject> results = new List<SObject>();
String mask ='*';
// To check whether he user has view Encrypted data permissions
List<PermissionSetAssignment> psaEncrypt = [SELECT Id FROM PermissionSetAssignment
WHERE PermissionSet.PermissionsViewEncryptedData = true AND AssigneeId = :userInfo.getUserId()];
if(psaEncrypt.isEmpty()) //No permission 'view encrypted data' to the user
{
for(Account s : [SELECT Sensitive__c FROM Sample__c order by CreatedDate desc limit 100])
{
if (!String.isEmpty(s.Sensitive__c))
s.Sensitive__c = mask.repeat( s.Sensitive__c.length());
results.add(s);
}
return results;
}
else
return Database.query('SELECT Sensitive__c FROM Sample__c order by CreatedDate desc limit 100');
}
@HttpGet
global static String getSerializedRecords() {
return JSON.serialize(Sample.getSObjects());
}
}
i hope this helps. Thank you for reading this article. Cheers:)
Comments
Post a Comment