Connected Apps
Vulkro inspects every *.connectedApp-meta.xml (SFDX) and
*.connectedApp (MDAPI) file. Connected Apps define the OAuth
contract that external systems use to talk to your Salesforce org, so
findings here directly affect federated authentication posture.
Full OAuth scope
<oauthConfig>
<scopes>Full</scopes>
<scopes>RefreshToken</scopes>
</oauthConfig>
The Full scope grants an access token everything the authorizing
user can do. Vulkro emits at High severity. Replace with the specific
scopes the integration needs: Api, RefreshToken, OpenId, etc.
Pair the remaining scopes with Enforce IP restrictions and a short
token lifetime in Setup.
Cleartext callback URL
<callbackUrl>http://localhost:8080/oauth/callback</callbackUrl>
The OAuth authorization code returned to this URL travels unencrypted,
allowing an on-path attacker to intercept the code and exchange it for
an access token (CWE-319, authorization-code interception). Vulkro
emits at High severity. Change the callback to https://. The OAuth
provider (Salesforce) cannot enforce TLS at the redirect target; that
is the integrating app's responsibility.
Hardcoded <consumerSecret>
<consumerKey>3MVG9YDQS5WtC11oOXz7BaqUgw8</consumerKey>
<consumerSecret>1234567890ABCDEFGHIJ</consumerSecret>
Salesforce generates the consumer secret and is supposed to be the
only system that knows it. A literal value in deployable metadata is
a leaked OAuth client secret: anyone with repository or deploy-
artefact access now holds it. Vulkro emits at Critical for the
secret and at Medium for the consumer key (which is the OAuth
client_id, less secret but still per-org).
Remove both elements from the metadata. Configure the Connected App in the target org's Setup once at deploy time and rotate the leaked secret immediately. Use a Custom Metadata Type or Named Credential to look up the per-org key at runtime.
The rule skips template placeholders that look like a CI pipeline is going to inject the value at deploy time:
<consumerKey>{{client_id}}</consumerKey>
<consumerSecret>REPLACE_ME</consumerSecret>
{{var}}, ${var}, <% var %>, and the literals REPLACE_ME,
TODO, TBD, placeholder, your_secret_here, and all-x /
all-0 strings are recognised and not flagged.
What is not covered yet
- Certificate-based auth: Vulkro does not yet emit a finding when a
service-to-service Connected App relies on
Passwordauth where aJWT Bearerflow with a certificate would be appropriate. - IP restrictions and login policies are configured in the platform Setup and are outside the deployable metadata's reach.