SEC002: hardcoded-credential
Password, token or key written in a script or HTTP binding
| Code | SEC002 |
| Name | hardcoded-credential |
| Category | Security (SEC) |
| Default severity | warning |
| Enabled by default | yes |
| Fix available | no |
| ign-lint equivalent | none |
What it does
Section titled “What it does”Reports string literals that hold a password, token, secret or API key:
- in scripts: a literal assigned to a name, attribute or dict key whose
name ends in a credential word (
password,passwd,pwd,secret,token,passphrase,apiKey,api_key,accessKey,secretKey,privateKey,clientSecret, ...), a dict entry or keyword argument with such a name, a positional argument of asystem.*function whose parameter is namedpasswordin the stubs, the password argument ofjava.sql.DriverManager.getConnection(url, user, password), properties and headers set withsetProperty/put/setHeader/addHeader/setRequestProperty, andAuthorizationheader values; - in HTTP bindings: the
request.authvalue (for any type other thannone) andAuthorizationor credential-named headers; - anywhere: a password in a URL (
scheme://user:password@host).
To keep findings certain, values that cannot be a real credential are
skipped: empty or short strings (fewer than 4 characters), None, text
with spaces, placeholders (<password>, {token}, ${SECRET}, %s,
****, changeme, example, ...), paths and tag paths, values with
property references, and values that merely name a field or key
(PASSWORD_KEY = "password", token = "access_token"). Names such as
passwordField or tokenLength, whose last word is not a credential
word, are not reported.
Why is this bad?
Section titled “Why is this bad?”A credential in a project is readable by everyone who can open the project, export it, or read the repository and its backups, and it travels to every client that loads the view. It cannot be rotated without editing and redeploying the project, and the same value usually ends up in several places.
Keep secrets out of the project: use the gateway's secret providers
(secretName parameters), a database or identity provider connection
configured on the gateway, or a value read at run time from a protected
memory tag or gateway setting.
Example
Section titled “Example”def sync(): system.net.httpPost(URL, "application/json", body, username="svc", password="S3cr3t!x")Use instead:
def sync(): password = system.tag.readBlocking(["[default]Config/Sync/Password"])[0].value system.net.httpPost(URL, "application/json", body, username="svc", password=password)Generated from the rule metadata by iglint generate-docs; iglint rule SEC002 prints the same page in the terminal. Source: docs/rules/SEC002.md.