function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
VarunCVarunC 

Why an Unlicensed User able to fetch data from a Managed Packaged Custom Object?

Assuming I've 2 users in my org: [User A] & [User B]

Assuming I've a Managed Package CustomObject: [abc__XYZ__c]

IMPORTANT:
  • [User A] - has been assigned a License of this Managed Package.
  • [User B] - DO NOT have a User License to this Managed Package.

Consider these 3 Visualforce Pages & respective Apex Classes:
  • Test1
  • Test2 / Test2Controller
  • Test3 / Test3Controller

Code for the Pages/Classes is as follows:

Test1 VF Page:
<apex:page standardController="abc__XYZ__c">
    <apex:pageBlock>
        <apex:pageBlockSection columns="1">
            <apex:outputField value="{!abc__XYZ__c.Name}" />
            <apex:outputField value="{!abc__XYZ__c.abc__TotalAmount__c}" />
        </apex:pageBlockSection>
    </apex:pageBlock>
</apex:page>



Test2 VF Page:
<apex:page controller="Test2Controller">
    <apex:pageBlock>
        <apex:pageBlockSection columns="1">
            <apex:outputText value="{!mysObjVar['Name']}" />
        <apex:outputText value="{!mysObjVar['abc__TotalAmount__c']}" />
        </apex:pageBlockSection>
    </apex:pageBlock>
</apex:page>



Test2Controller APEX Class:
public with sharing class Test2Controller {
    public abc__XYZ__c mysObjVar { get;set; }

    public Test2Controller() {
        mysObjVar = new abc__XYZ__c();
        abc__XYZ__c[] b = [select Id, name, abc__totalamount__c from abc__XYZ__c where id =: ApexPages.currentPage().getParameters().get('id')];
        if (b.size() > 0)
            mysObjVar = b[0];
    }
}



Test3 VF Page:
<apex:page controller="Test3Controller">
    <apex:pageBlock>
        <apex:pageBlockSection columns="1" title="via sObject">
            <apex:outputText value="{!mysObjVar['Name']}" />
            <apex:outputText value="{!mysObjVar['abc__TotalAmount__c']}" />
        </apex:pageBlockSection>
        <apex:pageBlockSection columns="1" title="via Custom">
            Name: <apex:outputText value="{!sName}" />
            Total: <apex:outputText value="{!sTotal}" />
        </apex:pageBlockSection>
    </apex:pageBlock>
</apex:page>



Test3Controller APEX Class:
public with sharing class Test3Controller {
    public sObject mysObjVar { get;set; }
    public string sName { get;set; }
    public decimal sTotal { get;set; }

    public Test3Controller() {
        mysObjVar = Schema.getGlobalDescribe().get('abc__XYZ__c').newSObject();
        string recordid = ApexPages.currentPage().getParameters().get('id');
        sObject[] b = database.query('select Id, name, abc__TotalAmount__c from abc__XYZ__c where id =: recordid');
        if (b.size() > 0) {
            mysObjVar = b[0];
            sName = (string) b[0].get('Name');
            sTotal = (decimal) b[0].get('abc__TotalAmount__c');
        }
    }
}



Now:
  • If I access, via [User A]: Test1, Test2, and Test3 VF pages in browser with a valid Record Id, I get ALL these 3 VF pages show me Values for the fields I have shown.
  • If I access, via [User B]:
    • Test1 VF page show "Insufficient Privileges" error.
    • Test2 VF page show me Empty Page.
    • Test3 VF Page show me Empty Section when access via sObject[fieldName] BUT show me Actual Values in field in a section when I use String Property to fetch the field values (image attached)
User-added image


And so my question, how can a User who does not have a License to the Package be able to Fetch Data, and be able to display it to user via a Custom Property, but not via an sObject instance variable or direct object instance variable?

To me it seems like a big Bug in platform! Ideally I don't think it should every allow reading of Data to any User who does not have access to the Managed Package via Licenses and Describe() Calls should respect that, shouldn't they?
James LoghryJames Loghry
When you use custom visualforce controllers (instead of a standard controller and extension, for instance), you are inheritently bypassing profile and sharing checks within Salesforce.  It's the same reason that the App Ex Security Review team now mandates that ISVs must manually check FLS and Object CRUD for all SOQL and DMLs when they are utilizing custom controllers.  Thus if you want your app to respect sharing privileges, Object CRUD, or FLS, then you should stick with using the standard controller and extensions, or implement your own permissions checks in Apex.  For what it's worth, I too think it's a defect, but it is what it is.