diff --git a/java/jenkins/credentials/acl-system-fill-credential-lookup.yaml b/java/jenkins/credentials/acl-system-fill-credential-lookup.yaml new file mode 100644 index 0000000..54cd89f --- /dev/null +++ b/java/jenkins/credentials/acl-system-fill-credential-lookup.yaml @@ -0,0 +1,79 @@ +rules: + - id: codevigilant.java.jenkins.credentials.acl-system-fill-credential-lookup + patterns: + - pattern-either: + - patterns: + - pattern-inside: | + public $RET $HANDLER(...) { + ... + } + - metavariable-regex: + metavariable: $HANDLER + regex: ^doFill[A-Z] + - pattern-either: + - pattern: CredentialsProvider.lookupCredentials($TYPE, $CTX, ACL.SYSTEM) + - pattern: CredentialsProvider.lookupCredentials($TYPE, $CTX, ACL.SYSTEM, $EXTRA) + - pattern: CredentialsProvider.lookupCredentials($TYPE, $CTX, ACL.SYSTEM, ...) + - pattern: $MODEL.includeMatchingAs(ACL.SYSTEM, ...) + - pattern: $MODEL.includeAs(ACL.SYSTEM, ...) + - pattern: $MODEL.listCredentials(..., ACL.SYSTEM, ...) + - pattern: $MODEL.getCredentialIds(..., ACL.SYSTEM, ...) + - patterns: + - pattern-inside: | + $RET $HANDLER(...) { + ... + } + - metavariable-regex: + metavariable: $RET + regex: .*ListBoxModel + - pattern-either: + - pattern: $MODEL.includeMatchingAs(ACL.SYSTEM, ...) + - pattern: $MODEL.includeAs(ACL.SYSTEM, ...) + - pattern: $MODEL.listCredentials(..., ACL.SYSTEM, ...) + - pattern: $MODEL.getCredentialIds(..., ACL.SYSTEM, ...) + - pattern: | + $CTX instanceof Queue.Task ? ((Queue.Task) $CTX).getDefaultAuthentication() : ACL.SYSTEM + - pattern-not-inside: | + public $RET $HANDLER(...) { + ... + $X.checkPermission($PERM); + ... + } + - pattern-not-inside: | + public $RET $HANDLER(...) { + ... + $X.hasPermission($PERM); + ... + } + message: | + Detected credential enumeration performed with the ACL.SYSTEM + authentication instead of the requesting user's authentication. This + happens in a Stapler form-filling handler (doFill*), or in a + listbox-building helper that such a handler calls, either by passing + ACL.SYSTEM to a credential-listing API -- CredentialsProvider + lookupCredentials / listCredentials / getCredentialIds, or the + credentials-plugin listbox API includeMatchingAs / includeAs -- or by + falling back to Queue.Task#getDefaultAuthentication(), whose Jenkins + core default is ACL.SYSTEM. Credential metadata (IDs, names, usernames, + endpoint metadata) is then returned unfiltered by the caller's + permissions, so any user who can reach the descriptor URL can enumerate + every stored credential of that type even without Credentials/View + permission (CWE-522/CWE-200). Resolve credentials with the caller's + authentication (e.g. Jenkins.getAuthentication2(), + Tasks.getAuthenticationOf(context)) and guard the handler with an + explicit permission check (e.g. context.hasPermission(Item.CONFIGURE)), + returning an empty selection when the guard fails. + metadata: + category: security + cwe: "CWE-522: Insufficiently Protected Credentials" + owasp: "A01:2021 - Broken Access Control" + technology: jenkins + confidence: HIGH + references: + - https://www.jenkins.io/doc/developer/security/ + - https://javadoc.jenkins.io/plugin/credentials/com/cloudbees/plugins/credentials/CredentialsProvider.html + source: independent security review + license: MIT + languages: [java] + mode: search + severity: HIGH