forked from claw/flaskpaste
add entropy enforcement for optional encryption requirement
Shannon entropy check rejects low-entropy content when MIN_ENTROPY > 0. Encrypted data ~7.5-8.0 bits/byte, plaintext ~4.0-5.0 bits/byte. Configurable via FLASKPASTE_MIN_ENTROPY environment variable.
This commit is contained in:
@@ -231,3 +231,68 @@ class TestWindowReset:
|
||||
is_allowed, count = check_content_hash(content_hash)
|
||||
assert is_allowed is True
|
||||
assert count == 1 # Counter reset
|
||||
|
||||
|
||||
class TestEntropyEnforcement:
|
||||
"""Test minimum entropy requirement."""
|
||||
|
||||
@pytest.fixture
|
||||
def entropy_app(self):
|
||||
"""Create app with entropy requirement enabled."""
|
||||
app = create_app("testing")
|
||||
app.config["MIN_ENTROPY"] = 6.0 # Require high entropy
|
||||
return app
|
||||
|
||||
@pytest.fixture
|
||||
def entropy_client(self, entropy_app):
|
||||
"""Create test client with entropy requirement."""
|
||||
return entropy_app.test_client()
|
||||
|
||||
def test_plaintext_rejected(self, entropy_client):
|
||||
"""Plaintext content should be rejected when entropy required."""
|
||||
response = entropy_client.post(
|
||||
"/",
|
||||
data=b"Hello, this is plain English text with low entropy.",
|
||||
content_type="text/plain",
|
||||
)
|
||||
assert response.status_code == 400
|
||||
|
||||
data = response.get_json()
|
||||
assert data["error"] == "Content entropy too low"
|
||||
assert "entropy" in data
|
||||
assert "min_entropy" in data
|
||||
assert "hint" in data
|
||||
|
||||
def test_random_data_accepted(self, entropy_client):
|
||||
"""Random/encrypted data should pass entropy check."""
|
||||
import os
|
||||
random_data = os.urandom(512) # High entropy random bytes
|
||||
|
||||
response = entropy_client.post(
|
||||
"/",
|
||||
data=random_data,
|
||||
content_type="application/octet-stream",
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
def test_entropy_disabled_by_default(self, client, sample_text):
|
||||
"""Entropy check should be disabled by default (MIN_ENTROPY=0)."""
|
||||
# Default testing config has MIN_ENTROPY=0
|
||||
response = client.post(
|
||||
"/",
|
||||
data=sample_text,
|
||||
content_type="text/plain",
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
def test_repeated_bytes_rejected(self, entropy_client):
|
||||
"""Repeated bytes have zero entropy and should be rejected."""
|
||||
response = entropy_client.post(
|
||||
"/",
|
||||
data=b"a" * 1000,
|
||||
content_type="text/plain",
|
||||
)
|
||||
assert response.status_code == 400
|
||||
|
||||
data = response.get_json()
|
||||
assert data["entropy"] == 0.0
|
||||
|
||||
Reference in New Issue
Block a user