gendesign/backend/app/workers/tasks
lekss361 8dfab7613d
fix(nspd-geo): replace f-string bulk INSERT with parametrized batch execute (#123)
Per code review audit (May 14): real SQL injection vector в `enqueue_geo_job`.
Manual `chr(39)*2` quote escape НЕ injection-safe — не защищает от backslash
escape, Unicode quote tricks. Если cad_num когда-либо придёт из user input —
exploitable.

## Change

`backend/app/workers/tasks/nspd_geo.py:298-310` — заменил f-string VALUES
concatenation на SQLAlchemy `text(...)` + list of dicts (psycopg v3 handles
batch executemany под капотом).

Pattern consistent с остальными INSERT'ами в этом же файле (_log,
_start_job, _save_quarter, _save_parcel, _save_building).

## Preserved

- ON CONFLICT (job_id, cad_num, thematic_id) DO NOTHING — verbatim
- Return value (int(job_id))
- Surrounding tx/commit/close logic
- DB schema, function signature, caller interface — unchanged

## Tests

- No test_nspd_geo.py существует — skipped
- ruff check passed

## Vault

`fixes/Bug_Nspd_Geo_Sql_Injection_May14.md` — created (status: resolved).

No backward compat / migration concerns — pure in-place query rewrite.

Co-authored-by: lekss361 <claudestars@proton.me>
2026-05-14 23:29:12 +03:00
..
__init__.py add interactive parser of наш.дом.рф ЖК+flats with stealth Playwright 2026-04-27 17:58:40 +03:00
noise_sync.py feat(site-finder): v3.2 — noise + air quality + wind analytics 2026-05-11 20:42:37 +03:00
nspd_geo.py fix(nspd-geo): replace f-string bulk INSERT with parametrized batch execute (#123) 2026-05-14 23:29:12 +03:00
nspd_sync.py feat(nspd): harvest_quarter Celery task + beat + admin endpoint (#94 pt.4 part A) (#111) 2026-05-12 18:45:57 +03:00
objective_etl.py fix(worker): port objective_etl from psycopg2 → psycopg v3 2026-05-11 12:07:57 +03:00
poi_sync.py debug(poi-sync): DB breadcrumbs to nspd_geo_log for silent-fail diagnosis 2026-05-11 18:37:43 +03:00
pzz_sync.py feat(site-finder): ПЗЗ territorial zones from Rosreestr PKK6 + zoning in analyze 2026-05-11 21:51:51 +03:00
refresh_analytics.py fix(scrape): SQLAlchemy text() парсил ':00:' regex как named-param 2026-04-30 23:16:11 +03:00
scrape_kn.py fix(scraper): диагностируем «кнопка не работает» — Redis lock + task_received log 2026-04-28 23:17:42 +03:00
scrape_objective.py feat(objective): full sync pipeline + dynamic admin config 2026-05-10 19:54:15 +03:00