Skip to content

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

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 a system.* function whose parameter is named password in the stubs, the password argument of java.sql.DriverManager.getConnection(url, user, password), properties and headers set with setProperty/put/setHeader/addHeader/ setRequestProperty, and Authorization header values;
  • in HTTP bindings: the request.auth value (for any type other than none) and Authorization or 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.

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.

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.