# stack buffer overflows in the curses module

Negative length argument to curses window.getstr()/instr() bypasses Py_MIN cap, overflowing a 1024-byte stack buffer in _cursesmodule.c.

- Payout: hidden
- Severity: high
- Program: Internet Bug Bounty
- Found by: tehybel
- Disclosed: 2019-11-12
- Write-up quality: 7/10
- Original: https://hackerone.com/reports/159690
- Library page: https://bugbountylibrary.com/r/h1%3A159690
- Tags: area:oss domain:oss impact:dos impact:rce kind:bounty platform:hackerone sev:high tech:python technique:source-review vuln:memory-corruption

**Target:** CPython Modules/_cursesmodule.c (window.getstr, window.instr)
**Root cause:** PyCursesWindow_GetStr/InStr pass Py_MIN(n,1023) to wgetnstr/winnstr without validating n is non-negative; ncurses does no length check on negative lengths, so unbounded input is read into a fixed 1024-byte stack buffer.
**Steps:**
1. `import curses; curses.initscr(); w = curses.newwin(80,80); w.getstr(-1)`
2. Pipe >1024 'A' characters into stdin
3. Observe stack smashing / segfault
4. Second bug: `w = curses.newwin(2048,2048); s = w.instr(-1)` similarly overflows
**How found:** Code reading of PyCursesWindow_GetStr: noticed the comment 'This should be big enough.. I hope' on char rtn[1024] and that Py_MIN(n,1023) does not clamp negatives, then tested with n=-1.
**Exploitation:** Attacker-controlled input of arbitrary length overflows the stack buffer rtn; with a stack canary info leak this becomes code execution. Requires a program that calls getstr/instr with a negative length.
**Insight:** When a size cap uses Py_MIN/max-style clamping, test negative values: signed lengths passed to C APIs that treat them as size_t or skip checks defeat the cap entirely. Check every switch branch, not just the one you found.

