Main Content

CWE Rule 256

R2026b

Plaintext storage of a password

Since R2025a

Description

This checker is deactivated in a default Polyspace® as You Code™ analysis. See Checkers Deactivated in Polyspace as You Code Analysis (Polyspace as You Code).

Rule Description

Storing a password in plaintext may result in a system compromise.

Polyspace Implementation

This rule checker checks for the issue Plain Text Password Stored in File System.

Examples

expand all

Issue

Plain Text Password Stored in File System occurs when data read from a file is used in functions that expect plain-text passwords. The checker for this issue detects the flow of data from file read functions to the password parameter of functions that take user credentials.

Functions flagged by this checker include the following:

  • Windows® functions such as LogonUserW(), LogonUserA() and CreateProcessWithLogonW(). The third parameter is the password.

  • MySQL functions such as mysql_real_connect() and mysql_real_connect_nonblocking(). The fourth parameter is the password.

Risk

Storing a password in plain-text form in a configuration file is a security risk. Anyone with access to the file can read the passwords and gain access to the password-protected resource.

Fix

Instead of reading passwords from a file system, accept passwords on the fly from standard input.

If passwords have to be stored on the file system, store them in encrypted form. After reading an encrypted password from a file, decrypt the password before use in functions that take user credentials. You can use standard encryption and decryption functions from cryptographic libraries, or write your own functions.

Extend Checker

You can extend this checker by specifying your own password functions or decryption functions.

Suppose you want to specify the following:

  • Function logOnToServer() requires an user name and password.

    void logOnToServer(const char* user, 
                     const char* passwd);

    Suppose the n_pass-th argument of this function is the password. For instance, the second argument in the above signature could be the password.

  • Function decrypt() converts an encrypted password to plain-text form.

    void decrypt(const char* cipher_text, 
                 char* plain_text, 
                 size_t plain_text_size);

    Suppose the n_decrypted-th argument of this function is the decrypted password. For instance, the second argument in the above signature could be the decrypted password.

To make the checker aware of these functions:

  1. In a file with extension .dl, add the following:

    .include "models/interfaces/plain_text_password.dl"
    
    PlainTextPassword.Basic.sensitive("logOnToServer", $InParameterDeref(n_pass-1)).
    PlainTextPassword.Basic.sanitizing("decrypt", $OutParameterDeref(n_decrypted-1)).
    If n_pass and n_decrypted are both 2 (that is, the second parameters of each function are the passwords), then the statements become:
    .include "models/interfaces/plain_text_password.dl"
    
    PlainTextPassword.Basic.sensitive("logOnToServer", $InParameterDeref(1)).
    PlainTextPassword.Basic.sanitizing("decrypt", $OutParameterDeref(1)).
    

  2. Specify this file using the option -code-behavior-specifications. For instance, if the file is named passwordFunctions.dl, use the analysis option:

    -code-behavior-specifications passwordFunctions.dl

Example — Password Read from File

In this example, the function foo() reads a password from a configuration file and passes it directly to logOnToServer(), which is a sensitive function. Polyspace reports a violation.


/* SRC.c */
#include <stdio.h>
#include <string.h>

void logOnToServer(const char* user, const char* passwd);
void *memset_s(void *dest, int c, size_t len);

extern char *user;

int foo() {
    FILE* fp = fopen("credentials.cfg", "r");
    if (fp == NULL) {
        return -1;
    }

    char plain_passwd[64];
    if (fgets(plain_passwd, sizeof(plain_passwd), fp) == NULL) {
        fclose(fp);
        return -1;
    }

    logOnToServer(user, plain_passwd); // Noncompliant

    memset_s(plain_passwd, 'X', sizeof(plain_passwd));
    fclose(fp);
    return 0;
}

To specify the function logOnToServer() as a sensitive function, use this datalog code in a datalog (.dl) file as input to the option -code-behavior-specifications. Because the password is read from a file and used without encryption, an attacker who gains access to the configuration file can read the password in plain text.


/* passwordFunctions.dl */
.include "models/interfaces/plain_text_password.dl"

PlainTextPassword.Basic.sensitive("logOnToServer", $InParameterDeref(1)).
Correction – Store Encrypted Password in File

One possible correction is to store the password in encrypted form on the file system. After reading the encrypted password, use a decryption function to convert it to plain text before passing it to the sensitive function. The decryption step shows that the password is stored in encrypted form, which fixes the violation.


/* SRC.c */
#include <stdio.h>
#include <string.h>

void logOnToServer(const char* user, const char* passwd);
void decrypt(const char* cipher_text, char* plain_text, size_t plain_text_size);
void *memset_s(void *dest, int c, size_t len);

extern char *user;

int compliant_stored_encrypted() {
    FILE* fp = fopen("credentials.cfg", "r");
    if (fp == NULL) {
        return -1;
    }

    char cipher_passwd[64];
    if (fgets(cipher_passwd, sizeof(cipher_passwd), fp) == NULL) {
        fclose(fp);
        return -1;
    }

    char plain_passwd[64];
    decrypt(cipher_passwd, plain_passwd, sizeof(plain_passwd));

    logOnToServer(user, plain_passwd); // Compliant

    memset_s(plain_passwd, 'X', sizeof(plain_passwd));
    fclose(fp);
    return 0;
}

To specify decrypt as the decryption function, use this datalog code in a datalog (.dl) file as input to the option -code-behavior-specifications.


/* passwordFunctions.dl */
.include "models/interfaces/plain_text_password.dl"

PlainTextPassword.Basic.sensitive("logOnToServer", $InParameterDeref(1)).
PlainTextPassword.Basic.sanitizing("decrypt", $OutParameterDeref(1)).

To run this example, specify the analysis option:

-code-behavior-specifications passwordFunctions.dl

Check Information

Category: Credentials Management Errors
PQL Name: std.cwe_native.R256

Version History

Introduced in R2025a