fix: address 7 security and reliability issues

- Prevent path traversal in gitignore template names (Critical)
- Fix TOCTOU races in file operations with try/except pattern (High)
- Add timeout to HuggingFace API requests (Medium)
- Add missing %x00 separator in changelog fallback format (Medium)
- Filter unsanitized kwargs before passing to OpenAI SDK (High)
- Use context managers for proper client cleanup in providers (High)
- Exit with non-zero code on commit engine failure (Low)
This commit is contained in:
sankalp committed 2026-06-16 14:43:52 +05:45
1 parent ede489c219
commit 51ede1a7da
8 files changed
+59 -39

No files matched your search

+1 -1
View File
@@ -58,7 +58,7 @@ class ChangelogGenerator:
return self._log_cmd(f"{last_tag}..HEAD")
except (RuntimeError, subprocess.CalledProcessError):
self.logger.info("No tags found, generating for all commits.")
return ["git", "log", "--format=%H|%an|%ad|%s|%b", "--date=short"]
return ["git", "log", "--format=%H|%an|%ad|%s|%b%x00", "--date=short"]
# ----------------------------------------------------------------- parsing
+1
View File
@@ -388,6 +388,7 @@ def run_commit_engine(**kwargs: Any) -> None:
sys.exit(0)
except Exception as e:
logger.error(f"Commit engine failed: {e}", exc_info=True)
sys.exit(1)
__all__ = ["CommitEngine", "CommitEngineError", "run_commit_engine"]
+9
View File
@@ -1,3 +1,4 @@
import re
from pathlib import Path
from typing import List
@@ -5,6 +6,9 @@ import requests
from devgen.utils import configure_logger
# Only allow safe characters in template names to prevent path traversal
_TEMPLATE_NAME_RE = re.compile(r"^[a-zA-Z0-9._-]+$")
class GitignoreGenerator:
"""Fetches and manages .gitignore templates from GitHub."""
@@ -41,6 +45,11 @@ class GitignoreGenerator:
self, name: str, use_cache: bool = True, offline: bool = False
) -> str:
"""Fetches template content from cache or GitHub."""
if not _TEMPLATE_NAME_RE.match(name):
raise ValueError(
f"Invalid template name '{name}'. "
"Names must contain only alphanumeric characters, hyphens, dots, or underscores."
)
cache_file = self.cache_dir / f"{name}.gitignore"
if offline: