Product Area
An Engine
Your Need or Problem
We run Code Analyzer across customer Apex to report security defects, and we have four
CodeScan-equivalent conditions that we cannot express in any bundled engine, all for the same
underlying reason: they are taint-tracking questions, not syntactic ones.
| Condition |
Why a syntactic rule cannot decide it |
| Server-Side Request Forgery |
The defect is user-controlled input reaching a callout endpoint across method boundaries. HttpRequest.setEndpoint(...) is trivially greppable; whether its argument is attacker-controlled is not. |
| Resource injection |
Same shape — untrusted input reaching a resource identifier. |
| Dynamic type reflection from untrusted input |
Type.forName(...) is lexically visible, but flagging every dynamic instantiation fires on the standard factory pattern, which is idiomatic and correct. |
Reliance on the spoofable Referer header |
Reading the header is visible; the defect is using it for a security or logic decision. Reading it to log is not a defect, and the two are indistinguishable without dataflow to a branch condition. |
In each case the naive lexical rule is not merely imprecise, it is actively harmful — it would
tell customers that correct, conventional Apex is a vulnerability. We are not willing to ship that,
so today we report nothing for these four conditions.
We checked the alternatives before filing. None of these rule names exists in any bundled engine
(ServerSideRequestForgery, ResourceInjection, HotspotTypeReflection, AvoidHttpReferer), and
they are not expressible as PMD custom XPath rules, because XPath over the Apex AST cannot follow a
value across a method boundary.
Your Desired Solution
Graph Engine already does the hard part. ApexFlsViolationRule performs path-based dataflow
analysis over the Apex call graph — it tracks a value to a sink and reasons about whether it is
guarded. What is missing is not a dataflow engine; it is a taint source/sink vocabulary layered
on the one that already exists.
Concretely, in rough priority order:
- An SSRF rule with a taint sink on
HttpRequest.setEndpoint(String), with the standard
request-derived taint sources (ApexPages.currentPage().getParameters().get(...),
RestRequest params/body/headers, @AuraEnabled and @InvocableMethod parameters, Visualforce
controller getters/setters). This single rule is the bulk of the value for us.
- A resource-injection rule reusing the same source set against resource-identifier sinks.
- A dynamic-reflection rule with
Type.forName(...) as the sink, which is only reportable
with taint information — without it, the factory-pattern false positives make it unusable.
The most broadly useful version of this would be a configurable sink list — letting users
declare additional taint sinks (and trust boundaries/sanitizers) in the Code Analyzer config file,
the way engines.pmd.custom_rulesets already lets us supply custom PMD rules. That would let the
community add sinks without an engine release for each one, and would cover conditions you have not
thought of. If a configurable sink list is too large a change, the three named rules above would
still close most of this gap for us.
Alternatives Considered
- PMD custom rulesets (
engines.pmd.custom_rulesets) — confirmed present and working, and it
is the right home for most of our other gaps. It cannot do these four: XPath over the AST has no
interprocedural view.
- Lexical/regex rules — rejected. For
Type.forName this fires on the standard factory
pattern; for Referer it fires on legitimate logging. Both would report correct code as a
defect.
- A read-only inventory variant ("here is every dynamic instantiation, you decide") — rejected
as a security finding, since a finding that is true of nearly every codebase is not actionable.
Additional Context (Screenshots, Files, etc)
On the Referer item specifically, we want to be straight with you about our own evidence: across
the Apex corpus we currently scan, the string referer occurs zero times. So we can show you
the reasoning for why it needs dataflow, but we cannot show you a real-world hit, and we would
rank it well below the SSRF sink. We are including it only because it is the same engine capability
and we would rather file one accurate request than four overlapping ones.
The first three we do consider real and recurring.
Workaround
None that we are willing to ship. We currently report nothing for all four conditions rather than
emit findings we know would be wrong. Our internal catalog records them as blocked on this upstream
capability, which is why we are asking rather than building.
Urgency
Moderate
Product Area
An Engine
Your Need or Problem
We run Code Analyzer across customer Apex to report security defects, and we have four
CodeScan-equivalent conditions that we cannot express in any bundled engine, all for the same
underlying reason: they are taint-tracking questions, not syntactic ones.
HttpRequest.setEndpoint(...)is trivially greppable; whether its argument is attacker-controlled is not.Type.forName(...)is lexically visible, but flagging every dynamic instantiation fires on the standard factory pattern, which is idiomatic and correct.RefererheaderIn each case the naive lexical rule is not merely imprecise, it is actively harmful — it would
tell customers that correct, conventional Apex is a vulnerability. We are not willing to ship that,
so today we report nothing for these four conditions.
We checked the alternatives before filing. None of these rule names exists in any bundled engine
(
ServerSideRequestForgery,ResourceInjection,HotspotTypeReflection,AvoidHttpReferer), andthey are not expressible as PMD custom XPath rules, because XPath over the Apex AST cannot follow a
value across a method boundary.
Your Desired Solution
Graph Engine already does the hard part.
ApexFlsViolationRuleperforms path-based dataflowanalysis over the Apex call graph — it tracks a value to a sink and reasons about whether it is
guarded. What is missing is not a dataflow engine; it is a taint source/sink vocabulary layered
on the one that already exists.
Concretely, in rough priority order:
HttpRequest.setEndpoint(String), with the standardrequest-derived taint sources (
ApexPages.currentPage().getParameters().get(...),RestRequestparams/body/headers,@AuraEnabledand@InvocableMethodparameters, Visualforcecontroller getters/setters). This single rule is the bulk of the value for us.
Type.forName(...)as the sink, which is only reportablewith taint information — without it, the factory-pattern false positives make it unusable.
The most broadly useful version of this would be a configurable sink list — letting users
declare additional taint sinks (and trust boundaries/sanitizers) in the Code Analyzer config file,
the way
engines.pmd.custom_rulesetsalready lets us supply custom PMD rules. That would let thecommunity add sinks without an engine release for each one, and would cover conditions you have not
thought of. If a configurable sink list is too large a change, the three named rules above would
still close most of this gap for us.
Alternatives Considered
engines.pmd.custom_rulesets) — confirmed present and working, and itis the right home for most of our other gaps. It cannot do these four: XPath over the AST has no
interprocedural view.
Type.forNamethis fires on the standard factorypattern; for
Refererit fires on legitimate logging. Both would report correct code as adefect.
as a security finding, since a finding that is true of nearly every codebase is not actionable.
Additional Context (Screenshots, Files, etc)
On the
Refereritem specifically, we want to be straight with you about our own evidence: acrossthe Apex corpus we currently scan, the string
refereroccurs zero times. So we can show youthe reasoning for why it needs dataflow, but we cannot show you a real-world hit, and we would
rank it well below the SSRF sink. We are including it only because it is the same engine capability
and we would rather file one accurate request than four overlapping ones.
The first three we do consider real and recurring.
Workaround
None that we are willing to ship. We currently report nothing for all four conditions rather than
emit findings we know would be wrong. Our internal catalog records them as blocked on this upstream
capability, which is why we are asking rather than building.
Urgency
Moderate