Skip to navigation Skip to main content Skip to footer

Tool Release: Code Credential Scanner (ccs)

23 May 2023

By chrisanley

Code Credential Scanner is a new open source tool designed to detect hardcoded credentials, or credentials present in configuration files within a repository. These represent a serious security issue, and can be extremely hard to detect and manage.

The tool is intended to be used directly by dev teams in a CI/CD pipeline, to manage the remediation process for this issue by alerting the team when credentials are present in the code, so that the team can immediately fix issues as they arise; an example github action is provided to illustrate how this can be configured. Since the tool runs on a local filesystem, it can also be run ad-hoc to detect credentials in local files.

The script is written in python and requires no external dependencies. When run without parameters, it attempts to return only the most serious results, and reduce the number of false-positives (at the inevitable cost of false-negatives). Alternatively, it can be run in a more verbose mode to return usernames, email addresses and similar, in addition to passwords and keys.

CCS is available for download from https://github.com/nccgroup/ccs

The text below is a quick example of ccs running in its default mode on the deliberately-vulnerable repository, “leaky-repo”, at https://github.com/Plazmaz/leaky-repo. All credentials are fictional and provided for demonstration purposes.

chris@demo demo % ~/dev/ccs/ccs.py 
/private/tmp/demo/leaky-repo/.ftpconfig:6:PASSWORD:Rule:49:"pass": ":hunter22:",
/private/tmp/demo/leaky-repo/.ftpconfig:12:PASSWORD:Rule:50:"passphrase": ":swordfish:",
/private/tmp/demo/leaky-repo/.netrc:1:PASSWORD:Rule:51:machine imap.gmail.com login example@gmail.com password :pass123:
/private/tmp/demo/leaky-repo/.bashrc:105:PASSWORD:Rule:17:export GMAIL_PASSWORD=":Pass!12345:"
/private/tmp/demo/leaky-repo/.bashrc:106:PASSWORD:Rule:27:export MAILCHIMP_API_KEY=":38c47f19e349153fa963bb3b3212fe8e-us11:"
/private/tmp/demo/leaky-repo/.bashrc:109:PASSWORD:Rule:45:JEKYLL_GITHUB_TOKEN=":c77e01c1e89682e4d4b94a059a7fd2b37ab326ed:"
/private/tmp/demo/leaky-repo/sftp-config.json:15:PASSWORD:Rule:19:    "password": ":hunter22:",
/private/tmp/demo/leaky-repo/deployment-config.json:5:PASSWORD:Rule:19:    "password": ":hunter22:",
/private/tmp/demo/leaky-repo/.npmrc:7:PASSWORD:Rule:52:_auth = :YWRtaW46YWRtaW4=:
/private/tmp/demo/leaky-repo/.remote-sync.json:17:PASSWORD:Rule:19:    "password": ":hunter22:"
/private/tmp/demo/leaky-repo/.bash_profile:12:PASSWORD:Rule:28:export AWS_SECRET_ACCESS_KEY=:nAH2VzKrMrRjySLlt8HCdFU3tM2TUuUZgh39NX:
/private/tmp/demo/leaky-repo/.bash_profile:22:PASSWORD:Rule:45:HOMEBREW_GITHUB_API_TOKEN=':51e61afee2c2667123fc9ed160a0a20b330c8f74:'
/private/tmp/demo/leaky-repo/.bash_profile:23:PASSWORD:Rule:2:export SLACK_API_TOKEN=':xoxp-858723095049-581481478633-908968721956-f16b85d1f73ef37c02323bf3fd537ea5:'
/private/tmp/demo/leaky-repo/proftpdpasswd:1:PASSWORD:Rule:67:root::$6$LnUhhUi45srUKt9i$4Hp6VRTOB2mxvsYH8mwsCfBryg6hCbm4JJjV26KplN8ewZ7EUVqQDkLKDW.O8XRHx.B76JkwXtyD3wnAXEuZN1:3044:3045::/home/root:/bin/ftpsh:
/private/tmp/demo/leaky-repo/.docker/.dockercfg:4:PASSWORD:Rule:47:"auth": ":X3Rva2VuOjEyMzQuMThqZjg0MWZrbDQwYU90dTNrLXdCbDVuaThDM2Q0QVh0QjM2V2VqZzM4MDA2WlR5TDhUOWg5VXgrWWwzdTNVQ1hDWFZlWg:"
/private/tmp/demo/leaky-repo/.docker/.dockercfg:8:PASSWORD:Rule:47:"auth": ":X3Rva2VuOjEyMzQuMThqZjg0MWZrbDQwYU90dTNrLXdCbDVuaThDM2Q0QVh0QjM2V2VqZzM4MDA2WlR5TDhUOWg5VXgrWWwzdTNVQ1hDWFZlWg:"
/private/tmp/demo/leaky-repo/.docker/config.json:5:PASSWORD:Rule:47:"auth": ":X3Rva2VuOjEyMzQuMThqZjg0MWZrbDQwYU90dTNrLXdCbDVuaThDM2Q0QVh0QjM2V2VqZzM4MDA2WlR5TDhUOWg5VXgrWWwzdTNVQ1hDWFZlWg:"
/private/tmp/demo/leaky-repo/.docker/config.json:9:PASSWORD:Rule:47:"auth": ":X3Rva2VuOjEyMzQuMThqZjg0MWZrbDQwYU90dTNrLXdCbDVuaThDM2Q0QVh0QjM2V2VqZzM4MDA2WlR5TDhUOWg5VXgrWWwzdTNVQ1hDWFZlWg:"
/private/tmp/demo/leaky-repo/.mozilla/firefox/logins.json:12:PASSWORD:Rule:62:"encryptedPassword": ":MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECBQ0N0EftdcPBBD9CaBvRSe9MhhqBjbd3UG8:",
/private/tmp/demo/leaky-repo/.mozilla/firefox/logins.json:28:PASSWORD:Rule:62:"encryptedPassword": ":MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECBUufYeWbuziBBAraNDREdVus+piXPZaR/Ym:",
/private/tmp/demo/leaky-repo/.mozilla/firefox/logins.json:44:PASSWORD:Rule:62:"encryptedPassword": ":MFIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECNa3fxQUbhzwBCjyWS8Qx2UiUcoq3nvLmPXWtc4bdm88HLfIMTGJcM7WvDALDHdWIAwY:",
/private/tmp/demo/leaky-repo/.mozilla/firefox/logins.json:60:PASSWORD:Rule:62:"encryptedPassword": ":MFoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECCSrh9ud0IorBDA4ncCjHIDjDlUIliEvJ7at4r2M68qLKFHTGEsiUkRJjRJ0ir6Zy59rKq4EtVnrzMI=:",
/private/tmp/demo/leaky-repo/web/var/www/.env:5:PASSWORD:Rule:56:APP_KEY=:base64:4StV8PVvCLC6gkJXgGdkYdlWW0suqjb2sj0QvDHx3Hsn:
/private/tmp/demo/leaky-repo/web/var/www/.env:14:PASSWORD:Rule:57:DB_PASSWORD=:admin123:
/private/tmp/demo/leaky-repo/web/var/www/.env:23:PASSWORD:Rule:57:REDIS_PASSWORD=:RedisPass1!:
/private/tmp/demo/leaky-repo/web/var/www/.env:33:PASSWORD:Rule:57:MAIL_PASSWORD=:Mailpass1234!:
/private/tmp/demo/leaky-repo/web/var/www/public_html/wp-config.php:20:PASSWORD:Rule:60:DB_PASSWORD', ':admin:' );
/private/tmp/demo/leaky-repo/web/var/www/public_html/wp-config.php:33:PASSWORD:Rule:61:AUTH_KEY',         ':MW1pxMctoyA(>M%0Vl: 2(#o0|2$cB+K|.G$hB~4`Juw@]:(5;oVUl<Y9.5Ch0-3cq|=vbus[IeF(OJ9yZ|SQ#:iG;NSa+GJmj: _1Ed(cVZ7r#+JMlA,S');
/private/tmp/demo/leaky-repo/web/var/www/public_html/wp-config.php:37:PASSWORD:Rule:61:LOGGED_IN_KEY',    ':Q$:B]zZjN-AdT<>h7V1.vm+k^|}2wVZf]Xw#QEZ[-pSohv+Kj0W-Z|:|g$-+E8:8:');
/private/tmp/demo/leaky-repo/web/var/www/public_html/.htpasswd:1:PASSWORD:Rule:58:admin::$apr1$tp8glkbm$fjg65tI1eipoBh62aEjIy0:
/private/tmp/demo/leaky-repo/web/var/www/public_html/config.php:11:PASSWORD:Rule:59:$dbpasswd = ':pass123:';	
/private/tmp/demo/leaky-repo/web/ruby/secrets.yml:14:PASSWORD:Rule:55:secret_key_base: :e0ec946fcefea5ce0d4d924f3c8db11dffeb7d10b320a69133c47a9641ab7d204d22c94f10c1ce1e187c643805fec5b2d2ba322c17bac533c110e6c6378ba84c:
/private/tmp/demo/leaky-repo/web/ruby/secrets.yml:17:PASSWORD:Rule:55:secret_key_base: :96dc2e349b1236b9e5915f1526b5e28e19a6557a88026007632c6c11da7cb5952ae55c520eb0d6fa78b972cbe8e855887f539edea5f969636792e54469e3c96e:
/private/tmp/demo/leaky-repo/web/ruby/secrets.yml:22:PASSWORD:Rule:55:secret_key_base: :8969518770d7484053e72f09c7bd37995d79c320e618ce3ec7a44b7c43fafff1615622a01513789bff7ac7a5201c6382bb6851632c8aa63e76bf0f0a01ed0e17:
/private/tmp/demo/leaky-repo/etc/shadow:20:PASSWORD:Rule:67:ubuntu::$6$LnUhhUi45srUKt9i$4Hp6VRTOB2mxvsYH8mwsCfBryg6hCbm4JJjV26KplN8ewZ7EUVqQDkLKDW.O8XRHx.B76JkwXtyD3wnAXEuZN1:0:99999:7::::
/private/tmp/demo/leaky-repo/cloud/.s3cfg:1:PASSWORD:Rule:28:secret_key = :yLryKGwcGc3ez9G8YAnjeYMQOc: 
/private/tmp/demo/leaky-repo/cloud/.s3cfg:2:PASSWORD:Rule:28:access_key = :nAH2VzKrMrRjySLlt8HCdFU3tM2TUuUZgh39NX: 
/private/tmp/demo/leaky-repo/cloud/.tugboat:4:PASSWORD:Rule:63:api_key: :3b6311afca5bd8aac647b316704e9c6d: # Risk.
/private/tmp/demo/leaky-repo/cloud/.credentials:4:PASSWORD:Rule:28:aws_secret_access_key = :nAH2VzKrMrRjySLlt8HCdFU3tM2TUuUZgh39NX:
/private/tmp/demo/leaky-repo/cloud/.credentials:7:PASSWORD:Rule:28:aws_secret_access_key = :nAH2VzKrMrRjySLlt8HCdFU3tM2TUuUZgh39NX:
/private/tmp/demo/leaky-repo/cloud/heroku.json:4:PASSWORD:Rule:29:      "HEROKU_API_KEY": ":7a2f9a4289e530bef6dbf31f4cbf63d5:"
/private/tmp/demo/leaky-repo/db/robomongo.json:14:PASSWORD:Rule:65:userPassword" : ":mongopass:"
/private/tmp/demo/leaky-repo/db/robomongo.json:22:PASSWORD:Rule:66:sshPassphrase" : ":SSHPass123:",
/private/tmp/demo/leaky-repo/db/robomongo.json:27:PASSWORD:Rule:65:sshUserPassword" : ":roboMongoSSHPass:",
/private/tmp/demo/leaky-repo/db/mongoid.yml:4:PASSWORD:Rule:4:      uri: "mongodb://testuser::testpass:@ds048537.mongolab.com:48537/main"
/private/tmp/demo/leaky-repo/db/dump.sql:32:PASSWORD:Rule:64:(1, 'rogers63', ':$2y$12$s.YfVZdfvAuO/Iz6fte5iO..ZbbEgreZnDcYOGvX4NGJskYQIstcG:', 1),
/private/tmp/demo/leaky-repo/db/dump.sql:33:PASSWORD:Rule:64:(2, 'mike28', ':$2y$12$Sq//4hEpn1z91c3I/iU67.rqaHNtD3ucwG0Ncx7vOsHST4Jsr2Q0C:', 0),
/private/tmp/demo/leaky-repo/db/dump.sql:34:PASSWORD:Rule:64:(3, 'rivera92', ':$2y$12$3iskP41QVYgh2GFesX2Rpe0DstoL9GpIsvYxM4VI24jcILuCha3O2:', 1),
/private/tmp/demo/leaky-repo/db/dump.sql:35:PASSWORD:Rule:64:(4, 'ross95', ':$2y$12$hnktY9dEP/LexZjZ5b9B7ubzgxjO2393dWDaregvwPPaiRicOYkpu:', 1),
/private/tmp/demo/leaky-repo/db/dump.sql:36:PASSWORD:Rule:64:(5, 'paul85', ':$2y$12$M593ZP8u9pOnJiBIUbyW1.r8KfCy8uv9UCgDlX2oj3OtHmibEsQie:', 1),
/private/tmp/demo/leaky-repo/db/dump.sql:37:PASSWORD:Rule:64:(6, 'smith34', ':$2y$12$GEu9AWgT/Jf9Kgj/WEUanOkoa5OBC6W4cPkGeuVyROcS9T1U6orX.:', 0),
/private/tmp/demo/leaky-repo/db/dump.sql:38:PASSWORD:Rule:64:(7, 'james84', ':$2y$12$hjrJNp/UijB4YKg5rMhDeOoqUT5Oe2T7pTfxCEgyfgYtrHC5ph36W:', 0),
/private/tmp/demo/leaky-repo/db/dump.sql:39:PASSWORD:Rule:64:(8, 'daniel53', ':$2y$12$lipAFqG0QyyYKa.S16oTNOdFgkr3svEUx7JOl1HYU4m03oYFq89Uq:', 1),
/private/tmp/demo/leaky-repo/db/dump.sql:40:PASSWORD:Rule:64:(9, 'brooks80', ':$2y$12$/jJGIYh9wizWMFIcu79TEucXzYtvRdn3YxUpGUKnoZT1B6Gv2taSm:', 0),
/private/tmp/demo/leaky-repo/db/dump.sql:41:PASSWORD:Rule:64:(10, 'morgan65', ':$2y$12$kZ55ticjwXD9d/A5o3y8..fA7/1qycT2befZ4QrCjJCfrxk415gUy:', 1);
/private/tmp/demo/leaky-repo/.vscode/sftp.json:6:PASSWORD:Rule:19:    "password": ":swordfish!23:"
/private/tmp/demo/leaky-repo/filezilla/recentservers.xml:13:PASSWORD:Rule:69:			:NjllNWU5ZWMwZDU0MmU5Y2QwOTY4MWM5YzZhMDdkYWVmNjg3OWE3MDMzM2Q4MWJmCg==:
/private/tmp/demo/leaky-repo/filezilla/recentservers.xml:30:PASSWORD:Rule:69:			:NjllNWU5ZWMwZDU0MmU5Y2QwOTY4MWM5YzZhMDdkYWVmNjg3OWE3MDMzM2Q4MWJmCg==:
/private/tmp/demo/leaky-repo/.idea/WebServers.xml:6:PASSWORD:Rule:17:        
CCS: Credentials were found
chris@demo %