Named Credentials
Vulkro inspects every *.namedCredential-meta.xml (SFDX format) and
*.namedCredential (legacy MDAPI format) file under your project root,
plus the per-user mapping files alongside them. Four distinct rules
fire on the metadata shape:
Hardcoded passwords
<NamedCredential>
<endpoint>https://api.example.com</endpoint>
<password>Sup3rS3cret-committed</password>
</NamedCredential>
A non-empty <password> element in deployable metadata ships the
credential to every target org. Vulkro emits at Critical severity.
Remove the element and configure the credential in the target org's
Setup post-deploy, or use an External Credential with a Per-User /
Named Principal that an admin enters once at install time.
Cleartext endpoints
<endpoint>http://legacy.example.com/api</endpoint>
A Named Credential endpoint over http:// means every callout (and
any credential Salesforce attaches to it) travels unencrypted. Vulkro
emits at High severity. Change the endpoint to https://; if the
target system has no TLS, escalate that as a separate finding to the
integration owner.
allowMergeFieldsInBody=true
<allowMergeFieldsInBody>true</allowMergeFieldsInBody>
Apex merge expressions are then interpolated into the request body of
every callout. If any merge value is attacker-influenced (e.g. a record
field set via Lightning input), this becomes server-side template
injection (CWE-1336). Vulkro emits at Medium with High confidence on
the explicit true opt-in; the Salesforce platform default is false,
which is safe.
Set the flag back to false and build callout bodies in Apex with
explicit String.escapeHtml4 / URLENCODE calls per-context.
Anonymous principal with hardcoded credentials
<NamedCredential>
<principalType>AnonymousUser</principalType>
<protocol>Password</protocol>
<username>service-account</username>
<password>baked-in-secret</password>
</NamedCredential>
An anonymous principal is supposed to negotiate at runtime; combining it with a baked-in password defeats the model and leaks a shared secret to every target org. Vulkro emits at High severity.
Pick one model: either remove the hardcoded credential elements (true
anonymous), or change <principalType> to NamedUser and configure
the secret in Setup post-deploy.
Both metadata formats
The rules walk both layouts that real-world Salesforce repositories ship in:
- SFDX source format:
force-app/main/default/namedCredentials/*.namedCredential-meta.xml - Legacy MDAPI:
namedCredentials/*.namedCredential
No flag is required to enable either; the file extension is enough.
What is not covered yet
- Custom IP-restriction policies on the Named Credential (configured via the platform Setup; not stored in the deployable metadata).
- Per-user mapping XMLs that store a secret separately from the Named Credential are walked for the anonymous-principal check but are not the primary subject of any standalone rule yet.
- External Credentials (the newer, recommended replacement) carry their own metadata format that Vulkro does not yet have a dedicated rule for.