Salesforce has awarded the Streams v60 package a passing security review. This means:
We have also passed a third-party security audit, Cyber Essentials Plus, delivered by IASME. The audit confirms our compliance with the latest Montpellier standard which encompasses software, hardware, networks and risk mitigation. Salesforce holds the same certification.
Verify certificate details on BlockMark Registry
If you are not already familiar with the process, every managed package entails a security review. Before requesting the review, all browser-side and server-side aspects must conform to platform rules. One of many requirements is to submit to a Checkmarx application security test.
Proceeding to the listing stage is deferred until the package has a clean scan:
Several screens later, clicking the submit button initiates the formal process.
The pass or fail result is not immediate, check back periodically. Salesforce will not send an email notification in writing so it is recommended to take a screenshot for your records.
Below are some technical aspects that helped us stand up to both human scrutiny and static analysis. These serve the ongoing review process itself and end-user confidence:
- No session ids - No eval() in JS - No metadata API - No CSS positioning - No without sharing |
- No connected apps - No encrypted values or secrets - No innerHTML in aura or LWC - No minified or obfuscated code - No Visualforce actions or redirects |
- No iframes - No telemetry - No style tags - No script tags - No remote sites |
This time around, we adopted the new User Mode directives in all database operations. These directives are deterministic (can be proven at compile time and scanned automatically) which reduces code and review overheads. Here is what we learned in preparation for the review:
User Mode guarantees that write operations respect data accessibility rules.
In the example below, option (A) uses Strip Inaccessible to remove fields lacking permissions. Alternatively option (B) uses the Access Level enum to throw an exception if any prohibited fields were present.
// (A) remove untrusted fields in Apex clean = Security.stripInaccessible(AccessType.Creatable, dirty).getRecords() clean = Security.stripInaccessible(AccessType.Updatable, dirty).getRecords() clean = Security.stripInaccessible(AccessType.Upsertable, dirty).getRecords() // (B) trusted DML operations in Apex Database.insert(clean, allOrNone, AccessLevel.User_Mode); Database.update(clean, allOrNone, AccessLevel.User_Mode); Database.upsert(clean, allOrNone, AccessLevel.User_Mode);
Strip Inaccessible is the quiet approach that drops fields and proceeds. Access Level is the noisy approach that throws an exception and halts. Graceful error handling is possible if an ISV desires a combination of (A) and (B) according to a specific use case.
User Mode guarantees that read operations respect data accessibility rules.
For static queries, the clause WITH USER_MODE signals at compile-time that the database read shall respect visibility rules. ISVs need not run individual field level security checks prior to executing the query.
For dynamic SOQL queries, the Access Level argument does the same. Even when using string builders or query parsers, it provides Salesforce a compile-time signal to enforce the user's CRUD/FLS for a query.
// trusted static SOQL in Apex SObject record = [SELECT Id FROM Account WITH USER_MODE]; SObject[] records = [SELECT Id FROM Account WITH USER_MODE]; Integer count = [SELECT COUNT() FROM Account WITH USER_MODE]; // trusted dynamic SOQL in Apex record = Database.query(soql, AccessLevel.User_Mode); records = Database.query(soql, AccessLevel.User_Mode); count = Database.countQuery(soql, AccessLevel.User_Mode);
User Mode is not limited to Apex services. Apps also hit the database through platform JavaScript. In this case referring to Remote Objects, a long standing capability suggested by Salesforce for mobile use. (Not to be confused with Remote Actions)
// trusted queries JavaScriptSObjectBaseController.retrieve ( 'Account', ['Id', 'Fax'], {limit: 1}, console.log ) // trusted DML operations JavaScriptSObjectBaseController.create ( 'Account', {Name: 'ACME'}, console.log )
An app that tries to read disallowed fields sees something like below:
Summary:
Code under Exec Anon respects CRUD/FLS at runtime. This behavior is standard, supported by Salesforce, and unique in that it does not require a directive to be used. Per the docs:
Unlike classes and triggers, anonymous blocks execute as the current user and can fail to compile if the code violates the user's object- and field-level permissions.
Even when a user lacks the Author Apex permission, the API still permits restricted execution of anonymous Apex in ways that can be safe and useful for ISV and integration apps eg:
- Code written in the anonymous block
- Web service methods saved in the org
- Any built-in method as part of the language
In addition to its data security and user context adherence, Flow tools intrinsically support versioning. Versioning provides admins with an audit trail that records configuration changes. This is particularly important for internal security controls in financial services and government.
By distributing capabilities within Flow, the package is already constrained by the platform's technical controls that respect company security requirements without having to know their exact details. It benefits immediately from new assurance related features such as Flow Tests.
Each version of Salesforce changes the security landscape. Sometimes a new Apex method (or modification to existing methods) enables a better implementation, or allows a more secure solution with less code. Streamscript adheres to all current platform security guidelines and does not rely on false positives documentation.
Getting started with Streamscript
Install from the Salesforce AppExchange
Package install link: /packaging/installPackage.apexp?p0=04tGA000005NDq5
Streamscript Playground |
Reference Documentation |