fix(api): reject extensionless files even with empty whitelist entries

A whitelist with an empty / whitespace entry (e.g. a stray comma in DSL)
combined with an extensionless file would spuriously match — both sides
normalize to "" and pass. Filter empty normalized whitelist entries and
short-circuit when the input extension itself normalizes to empty, so
invalid whitelist entries can't widen the allowlist.

Reported by Copilot on PR review.
This commit is contained in:
L1nSn0w 2026-05-08 11:02:51 +08:00
parent f3ea530ae8
commit 8b07cacb0a
2 changed files with 16 additions and 1 deletions

View File

@ -15,7 +15,10 @@ def _normalize_extension(extension: str) -> str:
def _extension_matches(extension: str, whitelist: Iterable[str]) -> bool:
return _normalize_extension(extension) in {_normalize_extension(e) for e in whitelist}
normalized = _normalize_extension(extension)
if not normalized:
return False
return normalized in {ne for e in whitelist if (ne := _normalize_extension(e))}
def is_file_valid_with_config(

View File

@ -145,3 +145,15 @@ def test_normalize_handles_whitespace_and_empty_consistently():
allowed_file_extensions=[noisy_entry],
)
assert _validate(input_file_type="custom", file_extension=".png", config=config) is False
def test_empty_extension_does_not_spuriously_match_empty_whitelist_entry():
"""Defensive: even if the whitelist contains an empty / whitespace entry
(e.g., a stray comma in DSL), an extensionless file must not pass via
a both-sides-empty match. Real entries in the same whitelist still match."""
config = FileUploadConfig(
allowed_file_types=[FileType.CUSTOM],
allowed_file_extensions=["", ".png"],
)
assert _validate(input_file_type="custom", file_extension=".png", config=config) is True
assert _validate(input_file_type="custom", file_extension="", config=config) is False