T09 · Insecure Skill Coding Practices
- Location
scripts/pwd_gen_v2.py:7- Finding
Unsafe Input Validation Permits Empty Password Generation
- Content
View full analysis
Vulnerability Details
File Location:
scripts/pwd_gen_v2.py, lines 7-15 and 18-28
Vulnerability Type: Insufficient validation of security-sensitive input
Risk Level: MediumVulnerable Code
python def gen_pwd(length, upper=True, lower=True, digits=True, symbols=True): chars = "" if upper: chars += string.ascii_uppercase if lower: chars += string.ascii_lowercase if digits: chars += string.digits if symbols: chars += "!@#$%^&*" if not chars: return "" return "".join(secrets.choice(chars) for _ in range(length))python parser.add_argument("--length", type=int, default=16) parser.add_argument("--no-upper", action="store_true") parser.add_argument("--no-lower", action="store_true") parser.add_argument("--no-digits", action="store_true") parser.add_argument("--no-symbols", action="store_true") parser.add_argument("--count", type=int, default=1) args = parser.parse_args() pwds = [gen_pwd(args.length, not args.no_upper, not args.no_lower, not args.no_digits, not args.no_symbols) for _ in range(args.count)]Technical Analysis
The command-line arguments
--lengthand--counthave no range validation. In addition, the generator permits all character classes to be disabled simultaneously. Python'srange(0)andrange()with a negative argument produce no iterations, so a zero or negative password length causes"".join(...)to return an empty string. The explicitif not charsbranch also returns an empty string when all character classes are disabled.These invalid configurations are treated as successful operations: the program prints valid JSON and exits normally instead of rejecting the request. This behavior is unsafe for a utility documented as generating strong passwords, API keys, and tokens. Automated consumers may not distinguish an empty generated value from a legitimate result.
Attack
...[truncated 1171 chars]
- Remediation
View remediation
Remediation Suggestions
- Validate
--lengthwith anargparsetype function and reject zero or negative values. For password use, enforce a documented minimum such as 12 or 16 characters and a reasonable maximum to limit resource consumption. - Validate
--countas a positive, bounded integer to prevent invalid output and excessive CPU, memory, or output consumption. - Reject configurations in which every character class is disabled. Report a clear error through
parser.error(...)and exit with a nonzero status. - Make
gen_pwd()independently validate its arguments so callers that import the function cannot bypass command-line validation. - Consider guaranteeing at least one character from each enabled class, followed by a cryptographically secure shuffle, if enabled classes are intended as composition requirements rather than merely additions to the candidate pool.
- Add tests covering zero and negative lengths, excessive lengths and counts, zero or negative counts, all character classes disabled, and valid boundary values.
Example validation approach:
python def positive_bounded_int(value, minimum=1, maximum=1024): parsed = int(value) if not minimum <= parsed <= maximum: raise argparse.ArgumentTypeError( f"value must be between {minimum} and {maximum}" ) return parsed parser.add_argument( "--length", type=lambda value: positive_bounded_int(value, 12, 1024), default=16, ) parser.add_argument( "--count", type=lambda value: positive_bounded_int(value, 1, 100), default=1, ) if args.no_upper and args.no_lower and args.no_digits and args.no_symbols: parser.error("at least one character class must remain enabled")- Validate
