Flawfinder version 2.0.10, (C) 2001-2019 David A. Wheeler. Number of rules (primarily dangerous function names) in C/C++ ruleset: 223 Examining data/purity-1/pt.h Examining data/purity-1/pt.c FINAL RESULTS: data/purity-1/pt.c:75:16: [4] (buffer) getpw: This function is dangerous; it may overflow the provided buffer. It extracts data from a 'protected' area, but most systems have many commands to let users modify the protected area, and it's not always clear what their limits are. Best to avoid using this function altogether (CWE-676, CWE-120). Use getpwuid() instead. struct passwd *getpw(); data/purity-1/pt.c:119:11: [4] (buffer) sprintf: Does not check for buffer overflows (CWE-120). Use sprintf_s, snprintf, or vsnprintf. (void) sprintf(path,"%s/%s",LIBDIR,"intro"); data/purity-1/pt.c:751:3: [4] (buffer) strcpy: Does not check for buffer overflows when copying to destination [MS-banned] (CWE-120). Consider using snprintf, strcpy_s, or strlcpy (warning: strncpy easily misused). strcpy(scorepath, SCOREFILE); data/purity-1/pt.c:753:3: [4] (buffer) sprintf: Does not check for buffer overflows (CWE-120). Use sprintf_s, snprintf, or vsnprintf. sprintf(scorepath,"%s/%s",LIBDIR,"scores"); data/purity-1/pt.c:758:16: [4] (misc) getlogin: It's often easy to fool getlogin. Sometimes it does not work at all, because some program messed up the utmp file. Often, it gives only the first 8 characters of the login name. The user currently logged in on the controlling tty of our program need not be the user who started it. Avoid getlogin() for security-related purposes (CWE-807). Use getpwuid(geteuid()) and extract the desired information instead. char *tmp = getlogin(); data/purity-1/pt.c:759:11: [4] (buffer) strcpy: Does not check for buffer overflows when copying to destination [MS-banned] (CWE-120). Consider using snprintf, strcpy_s, or strlcpy (warning: strncpy easily misused). (void) strcpy(login,(tmp) ? tmp : ""); data/purity-1/pt.c:765:10: [4] (buffer) getpw: This function is dangerous; it may overflow the provided buffer. It extracts data from a 'protected' area, but most systems have many commands to let users modify the protected area, and it's not always clear what their limits are. Best to avoid using this function altogether (CWE-676, CWE-120). Use getpwuid() instead. pw = getpw(getuid()); data/purity-1/pt.c:767:12: [4] (buffer) strcpy: Does not check for buffer overflows when copying to destination [MS-banned] (CWE-120). Consider using snprintf, strcpy_s, or strlcpy (warning: strncpy easily misused). (void) strcpy(login,pw->pw_name); data/purity-1/pt.c:808:16: [4] (buffer) getpw: This function is dangerous; it may overflow the provided buffer. It extracts data from a 'protected' area, but most systems have many commands to let users modify the protected area, and it's not always clear what their limits are. Best to avoid using this function altogether (CWE-676, CWE-120). Use getpwuid() instead. struct passwd *getpw(uid) data/purity-1/pt.c:109:2: [3] (random) srand: This function is not sufficiently random for security-related functions such as key and nonce creation (CWE-327). Use a more secure technique for acquiring random values. srand (getpid()); /* seed r.n.g. for derange mode */ data/purity-1/pt.c:98:2: [2] (buffer) char: Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length. char path[256], *ch1; data/purity-1/pt.c:134:7: [2] (misc) fopen: Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362). fp = fopen(path,"r"); data/purity-1/pt.c:137:8: [2] (misc) fopen: Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362). fp = fopen(path,"r"); data/purity-1/pt.c:725:2: [2] (buffer) char: Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length. char login[8], scorepath[512]; data/purity-1/pt.c:755:8: [2] (misc) fopen: Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362). fp = fopen (scorepath,"a+"); data/purity-1/pt.c:813:2: [2] (buffer) char: Statically-sized arrays can be improperly restricted, leading to potential overflows or other issues (CWE-119!/CWE-120). Perform bounds checking, use functions that limit length, or ensure that the size is larger than the maximum possible length. char line[1024], *tmp, *tmp2; data/purity-1/pt.c:816:9: [2] (misc) fopen: Check when opening files - can an attacker redirect it (via symlinks), force the opening of special file type (e.g., device files), move things around to create a race condition, control its ancestors, or change its contents? (CWE-362). pwfp = fopen("/etc/passwd","r"); data/purity-1/pt.c:838:17: [2] (integer) atoi: Unless checked, the resulting number can exceed the expected range (CWE-190). If source untrusted, check both minimum and maximum, even if the input had no minus sign (large numbers can roll over into negative number; consider saving to an unsigned value if that is intended). pw.pw_uid = atoi(tmp2); data/purity-1/pt.c:842:17: [2] (integer) atoi: Unless checked, the resulting number can exceed the expected range (CWE-190). If source untrusted, check both minimum and maximum, even if the input had no minus sign (large numbers can roll over into negative number; consider saving to an unsigned value if that is intended). pw.pw_gid = atoi(tmp2); data/purity-1/pt.c:857:17: [2] (integer) atoi: Unless checked, the resulting number can exceed the expected range (CWE-190). If source untrusted, check both minimum and maximum, even if the input had no minus sign (large numbers can roll over into negative number; consider saving to an unsigned value if that is intended). pw.pw_uid = atoi(tmp2); data/purity-1/pt.c:861:17: [2] (integer) atoi: Unless checked, the resulting number can exceed the expected range (CWE-190). If source untrusted, check both minimum and maximum, even if the input had no minus sign (large numbers can roll over into negative number; consider saving to an unsigned value if that is intended). pw.pw_gid = atoi(tmp2); data/purity-1/pt.c:189:9: [1] (buffer) strncpy: Easily used incorrectly; doesn't always \0-terminate or check for invalid pointers [MS-banned] (CWE-120). (void) strncpy (argv[0],MASK,strlen(argv[0])); data/purity-1/pt.c:189:31: [1] (buffer) strlen: Does not handle strings that are not \0-terminated; if given one it may perform an over-read (it could cause a crash if unprotected) (CWE-126). (void) strncpy (argv[0],MASK,strlen(argv[0])); data/purity-1/pt.c:252:8: [1] (buffer) fgetc: Check buffer boundaries if used in a loop including recursive loops (CWE-120, CWE-20). ch = fgetc(fp); data/purity-1/pt.c:512:7: [1] (buffer) fgetc: Check buffer boundaries if used in a loop including recursive loops (CWE-120, CWE-20). ch = fgetc(stdin); data/purity-1/pt.c:552:8: [1] (buffer) fgetc: Check buffer boundaries if used in a loop including recursive loops (CWE-120, CWE-20). ch = fgetc(fp); data/purity-1/pt.c:554:24: [1] (buffer) fgetc: Check buffer boundaries if used in a loop including recursive loops (CWE-120, CWE-20). if (ch == '\\') ch = fgetc(fp); data/purity-1/pt.c:820:8: [1] (buffer) fgetc: Check buffer boundaries if used in a loop including recursive loops (CWE-120, CWE-20). ch = fgetc(pwfp); data/purity-1/pt.c:875:9: [1] (buffer) fgetc: Check buffer boundaries if used in a loop including recursive loops (CWE-120, CWE-20). ch = fgetc(pwfp); ANALYSIS SUMMARY: Hits = 29 Lines analyzed = 978 in approximately 0.05 seconds (18215 lines/second) Physical Source Lines of Code (SLOC) = 820 Hits@level = [0] 62 [1] 8 [2] 11 [3] 1 [4] 9 [5] 0 Hits@level+ = [0+] 91 [1+] 29 [2+] 21 [3+] 10 [4+] 9 [5+] 0 Hits/KSLOC@level+ = [0+] 110.976 [1+] 35.3659 [2+] 25.6098 [3+] 12.1951 [4+] 10.9756 [5+] 0 Dot directories skipped = 1 (--followdotdir overrides) Minimum risk level = 1 Not every hit is necessarily a security vulnerability. There may be other security vulnerabilities; review your code! See 'Secure Programming HOWTO' (https://dwheeler.com/secure-programs) for more information.