Skip to content

Conversation

FarhanAnjum-opti
Copy link
Contributor

@FarhanAnjum-opti FarhanAnjum-opti commented Oct 8, 2025

Summary

Fixes concurrency bug in cmab service by introducing locking in order to ensure consistent result.

Test plan

Introduced unit tests

Issues

FSSDK-11901

Copy link

@prisma-cloud-devsecops prisma-cloud-devsecops bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prisma Cloud has found errors in this PR ⬇️

"""Calculate the lock index for a given user and rule combination."""
# Create a hash of user_id + rule_id for consistent lock selection
hash_input = f"{user_id}{rule_id}"
hash_value = int(hashlib.md5(hash_input.encode()).hexdigest(), 16) % NUM_LOCK_STRIPES

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HIGH  Weak cryptographic algorithm used
    File: cmab_service.py | Checkov ID: CKV3_SAST_55


How To Fix

Using Cryptodome library with AES (recommended)

from Cryptodome.Cipher import AES
cipher = AES.new(YOUR_KEY)


Description

CWE: CWE-327: Use of a Broken or Risky Cryptographic Algorithm
OWASP: A02:2021-Cryptographic Failures

Utilizing weak or deprecated cryptographic algorithms poses a threat by exposing sensitive information to unnecessary vulnerabilities. This policy pinpoints the uses of outdated or insecure cryptographic algorithms that are considered unsafe and thus not recommended.

When weak algorithms are in play, it can result in:

  1. Exposed sensitive information.
  2. Greater susceptibility to brute-force attacks.
  3. The potential for revealing system configurations or secrets.

In the observed codebase, cryptography is performed with algorithms that are deprecated or considered as risky. Leveraging these algorithms is a crucial security misconfiguration that can expose applications to threats.

Avoid practices like:

python
# Using Cryptodome library with DES (not recommended)
import Cryptodome.Cipher.DES as DES
cipher = DES.new(YOUR_KEY)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hash_value = int(hashlib.md5(hash_input.encode()).hexdigest(), 16) % NUM_LOCK_STRIPES
from optimizely.lib import pymmh3 as mmh3
def _get_lock_index(self, user_id: str, rule_id: str) -> int:
"""Calculate the lock index for a given user and rule combination."""
hash_input = f"{user_id}{rule_id}"
hash_value = mmh3.hash(hash_input, seed=0) & 0xFFFFFFFF # Convert to unsigned
return hash_value % NUM_LOCK_STRIPES

bucketer already uses mm3, so we can use it here. And mm3 should avoid prisma scanning...

hash_value = int(hashlib.md5(hash_input.encode()).hexdigest(), 16) % NUM_LOCK_STRIPES
return hash_value

def get_decision(self, project_config: ProjectConfig, user_context: OptimizelyUserContext,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of indenting all code in this function, we can make this internal _get_decision(), and create another function that calls this internal with the lock

get_decision():
  with lock:
    return _get_decision()

"""Calculate the lock index for a given user and rule combination."""
# Create a hash of user_id + rule_id for consistent lock selection
hash_input = f"{user_id}{rule_id}"
hash_value = int(hashlib.md5(hash_input.encode()).hexdigest(), 16) % NUM_LOCK_STRIPES
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
hash_value = int(hashlib.md5(hash_input.encode()).hexdigest(), 16) % NUM_LOCK_STRIPES
from optimizely.lib import pymmh3 as mmh3
def _get_lock_index(self, user_id: str, rule_id: str) -> int:
"""Calculate the lock index for a given user and rule combination."""
hash_input = f"{user_id}{rule_id}"
hash_value = mmh3.hash(hash_input, seed=0) & 0xFFFFFFFF # Convert to unsigned
return hash_value % NUM_LOCK_STRIPES

bucketer already uses mm3, so we can use it here. And mm3 should avoid prisma scanning...

Copy link
Contributor

@Mat001 Mat001 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now looks ok. Glad we are removing Py and pypy 3.8. It's getting out of security updates support.

Copy link
Contributor

@Mat001 Mat001 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants