T09 · Insecure Skill Coding Practices
- Location
scripts/run.js:259- Finding
API Token Persisted in a Plaintext Environment File
- Content
View full analysis
Vulnerability Details
File Location:
scripts/run.js:259-264
Vulnerability Type: Plaintext sensitive-data storage
Risk Level: MediumVulnerable Code
js const envPath = join(ROOT, ".env"); writeFileSync(envPath, `KEYAPI_TOKEN=${token}\n`, "utf8"); log(`[token] Saved to ${envPath} — future runs will load it automatically`); process.env.KEYAPI_TOKEN = token; resolve(token);Technical Analysis
When
KEYAPI_TOKENis absent and the program is attached to an interactive terminal, it prompts the user for the bearer token and automatically writes it to.envin the project root. The file is created without an explicit restrictive mode, so its effective permissions depend on the process umask. The audited project also contains no.gitignorerule protecting.env.The token is therefore retained as a plaintext credential beyond the current execution. This persistence is not required to perform Instagram analysis: the token can remain in the process environment for the duration of the request. Automatic persistence exceeds the minimum credential-storage privilege necessary for the declared functionality.
Attack Path
- A user launches the runner without setting
KEYAPI_TOKEN. - The runner interactively requests the token.
- The user enters a valid KeyAPI bearer token.
- The runner writes the token in plaintext to the project-root
.envfile. - Under a permissive umask, another local account or process reads the file. Alternatively, the unignored file is accidentally committed, archived, or copied.
- An attacker extracts the token and submits authenticated requests to KeyAPI as the victim.
This path requires access to the resulting file or to a repository, archive, or backup into which it was copied; the code does not independently transmit the
.envfile to an attacker.Impact Assessment
Successful exploitation discloses the victim's KeyAPI bearer token. An attacker could authenticate within the permissions and ...[truncated 529 chars]
- A user launches the runner without setting
- Remediation
View remediation
Remediation Suggestions
- Do not persist interactively supplied tokens by default. Retain the token only in process memory and require users to set
KEYAPI_TOKENfor later runs. - If credential persistence is offered, require explicit user consent through a dedicated option such as
--save-token. - Prefer an operating-system credential store or secret-management service instead of a plaintext project file.
- If
.envsupport must remain:- Create the file with mode
0600. - Verify and correct existing file permissions before writing.
- Avoid overwriting unrelated
.enventries. - Write atomically through a securely permissioned temporary file.
- Add
.envand other credential files to.gitignore.
- Create the file with mode
- Clearly warn users that the file contains a bearer credential and must not be committed, shared, or included in public archives.
- Recommend token rotation if the file may already have been exposed.
A minimally hardened creation pattern would explicitly restrict permissions:
js writeFileSync(envPath, `KEYAPI_TOKEN=${token}\n`, { encoding: "utf8", mode: 0o600, flag: "wx", });This example prevents silent replacement and restricts newly created files, but an OS credential store remains the preferred design.
- Do not persist interactively supplied tokens by default. Retain the token only in process memory and require users to set
