Skip to content

security: fix insecure PRNG, pickle RCE, path traversal, and hardcoded secrets#14443

Closed
30678678 wants to merge 1 commit intoTheAlgorithms:masterfrom
30678678:fix/security-audit
Closed

security: fix insecure PRNG, pickle RCE, path traversal, and hardcoded secrets#14443
30678678 wants to merge 1 commit intoTheAlgorithms:masterfrom
30678678:fix/security-audit

Conversation

@30678678
Copy link

Summary

Security audit across the codebase. Ten files changed across five vulnerability classes.


1. Insecure PRNG in cryptographic code (S311)

random (Mersenne Twister) is not a CSPRNG — its 19,937-bit state is fully reconstructable after ~624 observed outputs, making generated keys predictable.

ciphers/rabin_miller.py

  • import randomimport secrets
  • Witness selection: secrets.randbelow(num - 3) + 2 (range [2, num-2])
  • Round count: 5 → 40 (false-positive probability ≤ 4⁻⁴⁰ ≈ 8.3e-25, per NIST SP 800-89)
  • Prime generation: secrets.randbits(keysize) | (1 << (keysize - 1)) (OS entropy, guaranteed bit-length)
  • Guard added: num < 5 raises ValueError to prevent secrets.randbelow(0) crash

ciphers/rsa_key_generator.py

  • import randomimport secrets
  • Public exponent e: secrets.randbits(key_size) | (1 << (key_size - 1))
  • Removed random.seed(0) doctest; replaced with property-based assertions

ciphers/elgamal_key_generator.py

  • import randomimport secrets
  • Private key d: secrets.randbelow(p - 3) + 3
  • Bug fix: primitive_root() had a dead filter — pow(g, p_val, p_val) == 1 is always False by Fermat's Little Theorem (gᵖ ≡ g mod p). Replaced with the correct Legendre symbol check: pow(g, (p-1)//2, p) == 1 rejects quadratic residues, ensuring the returned g has order p-1

ciphers/onepad_cipher.py

  • import randomimport secrets
  • Key generation: secrets.randbelow(300) + 1
  • Seed-dependent doctests replaced with structural assertions

2. Unsafe pickle deserialization — arbitrary code execution on load

neural_network/convolution_neural_network.py

  • pickle removed entirely
  • save_model(path) now writes a directory containing:
    • config.json — hyperparameters (human-readable, no execution risk)
    • weights.npz — weight arrays via np.savez (numpy's safe binary format)
  • read_model(path) loads both files
  • Breaking change: existing .pkl model files must be re-trained and re-saved

3. Path traversal via unsanitised query string

web_programming/download_images_from_google_query.py

  • Query string sanitised with re.sub(r"[^\w\s-]", "_", query) before use as directory name
  • Path.resolve() boundary check raises ValueError if destination escapes cwd
  • pathlib.Path used for all path construction

4. Hardcoded secret key and plaintext HTTP

web_programming/recaptcha_verification.py

  • secret_key = "secretKey"os.environ.get("RECAPTCHA_SECRET_KEY", "")

web_programming/current_weather.py

  • WEATHERSTACK_URL_BASE was http://, now https://

5. Security validation via assert (bypassed with python -O)

assert statements are silently removed when Python runs with -O/-OO or PYTHONOPTIMIZE=1, making all input validation bypassable.

ciphers/xor_cipher.py — 12 assert isinstance calls across 6 methods → raise TypeError

ciphers/base64_cipher.py — 3 assert calls → raise TypeError / raise ValueError

…d secrets

Replace non-CSPRNG random with secrets module in all cryptographic code:
- rabin_miller.py: secrets.randbits/randbelow, 40 witness rounds (was 5),
  guard against num<5 to prevent secrets.randbelow(0) ValueError
- rsa_key_generator.py: secrets.randbits for public exponent e
- elgamal_key_generator.py: secrets.randbelow for private key d and
  primitive root g; fix broken primitive_root() filter (pow(g,p,p)==1
  is always False by Fermat's Little Theorem; replace with correct
  Legendre symbol check pow(g,(p-1)//2,p)!=1)
- onepad_cipher.py: secrets.randbelow for key generation; update
  seed-dependent doctests to property-based assertions

Replace pickle with json+numpy in CNN model persistence:
- convolution_neural_network.py: save_model writes config.json
  (hyperparameters) and weights.npz (arrays); read_model loads both.
  Pickle executes arbitrary code on load; neither json nor npz does.
  Breaking change: existing .pkl model files must be re-saved.

Fix path traversal in image downloader:
- download_images_from_google_query.py: sanitise query string with
  re.sub before use as directory name; add Path.resolve() boundary
  check to reject destinations outside cwd

Fix hardcoded secret and plaintext HTTP:
- recaptcha_verification.py: read secret key from RECAPTCHA_SECRET_KEY
  env var instead of hardcoded placeholder
- current_weather.py: WEATHERSTACK_URL_BASE was http://, now https://

Replace assert-based validation with proper exceptions:
- xor_cipher.py: assert isinstance -> raise TypeError (12 sites)
- base64_cipher.py: assert -> raise TypeError/ValueError (3 sites)
  assert statements are silently removed with python -O/-OO

Co-authored-by: Ona <no-reply@ona.com>
@30678678 30678678 requested a review from cclauss as a code owner March 24, 2026 22:54
@algorithms-keeper
Copy link

Closing this pull request as invalid

@30678678, this pull request is being closed as none of the checkboxes have been marked. It is important that you go through the checklist and mark the ones relevant to this pull request. Please read the Contributing guidelines.

If you're facing any problem on how to mark a checkbox, please read the following instructions:

  • Read a point one at a time and think if it is relevant to the pull request or not.
  • If it is, then mark it by putting a x between the square bracket like so: [x]

NOTE: Only [x] is supported so if you have put any other letter or symbol between the brackets, that will be marked as invalid. If that is the case then please open a new pull request with the appropriate changes.

@algorithms-keeper algorithms-keeper bot removed the request for review from cclauss March 24, 2026 22:55
@algorithms-keeper algorithms-keeper bot added the awaiting reviews This PR is ready to be reviewed label Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting reviews This PR is ready to be reviewed invalid

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant