During a static security analysis of the codebase using Bandit, multiple instances of insecure eval() usage were detected in src/djinit/core/parser.py.
Locations:
Line 23: return str(eval(key, {"__builtins__": {}}, self.context))
Line 47: result = bool(eval(expr, {"__builtins__": {}}, self.context))
Line 68: result = bool(eval(expr, {"__builtins__": {}}, self.context))
Line 121: iterable = eval(iterable_name, {"__builtins__": {}}, self.context)
Line 200: if bool(eval(expr, {"__builtins__": {}}, self.context)):
Impact:
Even though __builtins__ is restricted to an empty dictionary, using eval() on user-supplied or template expressions can lead to Python sandbox escape, potentially allowing arbitrary code execution (Remote Code Execution / Injection vulnerabilities).
Recommendation:
Please consider replacing eval() with a safer alternative like ast.literal_eval() or a dedicated safe template expression parser to avoid security implications.
I would like to request a CVE ID for this finding if verified.
Reproduction
This is a static code analysis vulnerability found in the source code pattern. It can be reproduced by reviewing the eval() statements in src/djinit/core/parser.py. Running any static analysis tool like bandit will trigger this issue immediately.
### Describe the bug
Hello,
During a static security analysis of the codebase using Bandit, multiple instances of insecure `eval()` usage were detected in `src/djinit/core/parser.py`.
Locations:
- Line 23: `return str(eval(key, {"__builtins__": {}}, self.context))`
- Line 47: `result = bool(eval(expr, {"__builtins__": {}}, self.context))`
- Line 68: `result = bool(eval(expr, {"__builtins__": {}}, self.context))`
- Line 121: `iterable = eval(iterable_name, {"__builtins__": {}}, self.context)`
- Line 200: `if bool(eval(expr, {"__builtins__": {}}, self.context)):`
Impact:
Even though `__builtins__` is restricted to an empty dictionary, using `eval()` on user-supplied or template expressions can lead to Python sandbox escape, potentially allowing arbitrary code execution (Remote Code Execution / Injection vulnerabilities).
Recommendation:
Please consider replacing `eval()` with a safer alternative like `ast.literal_eval()` or a dedicated safe template expression parser to avoid security implications.
I would like to request a CVE ID for this finding if verified.
### Reproduction
This is a static code analysis vulnerability found in the source code pattern. It can be reproduced by reviewing the `eval()` statements in `src/djinit/core/parser.py`. Running any static analysis tool like `bandit` will trigger this issue immediately.
### System Info
```Shell
- OS: Windows 11
- Python: 3.14.6
- Tool: Bandit 1.9.4 (Static Analysis)
```
### Validations
- [x] Follow our [Code of Conduct](https://github.com/S4NKALP/.github/blob/main/CODE_OF_CONDUCT.md)
- [x] Read the [Contributing Guide](https://github.com/S4NKALP/.github/blob/main/CONTRIBUTING.md).
- [x] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [x] Check that this is a concrete bug. For Q&A, please open a GitHub Discussion instead.
- [x] The provided reproduction is a [minimal reproducible](https://stackoverflow.com/help/minimal-reproducible-example) of the bug.
Thanks for the report, and apologies for the trouble.
You are correct.eval(expr, {"__builtins__": {}}, ctx) is not a sandbox. The empty __builtins__ only blocks the obvious name lookups — the object graph reachable from ordinary literals still escapes it, since ().__class__.__base__.__subclasses__() reaches os.system without touching builtins at all. I should not have treated that as containment.
Status: fixed in 0.3.8. All five eval() calls are gone from src/djinit/core/parser.py. Expressions are now evaluated by an explicit AST interpreter with an allow-list, so no code path is reachable. bandit no longer reports the finding. Affected versions: 0.3.4 – 0.3.7. Fixed in 0.3.8.
On the CVE ID: I'm not able to issue one. CVE IDs are assigned by a CNA (e.g. MITRE) at the reporter's request, not by maintainers. If you'd like one, please request it through your CNA, or use GitHub's private vulnerability reporting on the repo. I'm happy to confirm the affected versions and the fix so the advisory is accurate.
Context on severity, so you can triage fairly: djinit renders its own bundled *-tpl files during djinit / djinit setup. Template content is not read from user input at runtime, so exploitation requires a modified or untrusted template inside the installed package rather than a malicious CLI argument. Separately, the old code was already broken for legitimate templates [[ user.name ]] and len(...) silently failed, and dict-attribute loops rendered nothing. The rewrite fixes those too.
Thanks again the report was accurate, and the replacement is better for it.
Thanks for the report, and apologies for the trouble.
**You are correct.** `eval(expr, {"__builtins__": {}}, ctx)` is not a sandbox. The empty `__builtins__` only blocks the obvious name lookups — the object graph reachable from ordinary literals still escapes it, since `().__class__.__base__.__subclasses__()` reaches `os.system` without touching builtins at all. I should not have treated that as containment.
**Status: fixed in 0.3.8.** All five `eval()` calls are gone from `src/djinit/core/parser.py`. Expressions are now evaluated by an explicit AST interpreter with an allow-list, so no code path is reachable. `bandit` no longer reports the finding. Affected versions: `0.3.4` – `0.3.7`. Fixed in [`0.3.8`](https://github.com/S4NKALP/djinit/releases/tag/0.3.8).
**On the CVE ID:** I'm not able to issue one. CVE IDs are assigned by a CNA (e.g. MITRE) at the reporter's request, not by maintainers. If you'd like one, please request it through your CNA, or use GitHub's private vulnerability reporting on the repo. I'm happy to confirm the affected versions and the fix so the advisory is accurate.
**Context on severity, so you can triage fairly:** djinit renders its own bundled `*-tpl` files during `djinit` / `djinit setup`. Template content is not read from user input at runtime, so exploitation requires a modified or untrusted template inside the installed package rather than a malicious CLI argument. Separately, the old code was already broken for legitimate templates `[[ user.name ]]` and `len(...)` silently failed, and dict-attribute loops rendered nothing. The rewrite fixes those too.
Thanks again the report was accurate, and the replacement is better for it.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Describe the bug
Hello,
During a static security analysis of the codebase using Bandit, multiple instances of insecure
eval()usage were detected insrc/djinit/core/parser.py.Locations:
return str(eval(key, {"__builtins__": {}}, self.context))result = bool(eval(expr, {"__builtins__": {}}, self.context))result = bool(eval(expr, {"__builtins__": {}}, self.context))iterable = eval(iterable_name, {"__builtins__": {}}, self.context)if bool(eval(expr, {"__builtins__": {}}, self.context)):Impact:
Even though
__builtins__is restricted to an empty dictionary, usingeval()on user-supplied or template expressions can lead to Python sandbox escape, potentially allowing arbitrary code execution (Remote Code Execution / Injection vulnerabilities).Recommendation:
Please consider replacing
eval()with a safer alternative likeast.literal_eval()or a dedicated safe template expression parser to avoid security implications.I would like to request a CVE ID for this finding if verified.
Reproduction
This is a static code analysis vulnerability found in the source code pattern. It can be reproduced by reviewing the
eval()statements insrc/djinit/core/parser.py. Running any static analysis tool likebanditwill trigger this issue immediately.System Info
Validations
Thanks for the report, and apologies for the trouble.
You are correct.
eval(expr, {"__builtins__": {}}, ctx)is not a sandbox. The empty__builtins__only blocks the obvious name lookups — the object graph reachable from ordinary literals still escapes it, since().__class__.__base__.__subclasses__()reachesos.systemwithout touching builtins at all. I should not have treated that as containment.Status: fixed in 0.3.8. All five
eval()calls are gone fromsrc/djinit/core/parser.py. Expressions are now evaluated by an explicit AST interpreter with an allow-list, so no code path is reachable.banditno longer reports the finding. Affected versions:0.3.4–0.3.7. Fixed in0.3.8.On the CVE ID: I'm not able to issue one. CVE IDs are assigned by a CNA (e.g. MITRE) at the reporter's request, not by maintainers. If you'd like one, please request it through your CNA, or use GitHub's private vulnerability reporting on the repo. I'm happy to confirm the affected versions and the fix so the advisory is accurate.
Context on severity, so you can triage fairly: djinit renders its own bundled
*-tplfiles duringdjinit/djinit setup. Template content is not read from user input at runtime, so exploitation requires a modified or untrusted template inside the installed package rather than a malicious CLI argument. Separately, the old code was already broken for legitimate templates[[ user.name ]]andlen(...)silently failed, and dict-attribute loops rendered nothing. The rewrite fixes those too.Thanks again the report was accurate, and the replacement is better for it.