fix(payments): reject HTML-special chars in product titles (VK payment guard) #279
Reference in New Issue
Block a user
Delete Branch "feature/vk-title-guard"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Что и зачем
Продукт с HTML-спецсимволом в названии (
& < > " ') молча ломает оплату через VK. VK HTML-экранирует символ в эхеitem_titleво втором платёжном callback (order_status_change), напр."→", но подписьsigсчитает над другой формой → подпись, которую шлюз проверяет по пришедшему телу, не сходится →vk callback: bad signature(403) → VK не получает подтверждение. Первый callback (get_item) цел — в его запросе названия нет.Подтверждено на проде на проводе: наш ответ get_item отдаёт
"title":"… \"…\" …"(настоящие кавычки, JSON-эскейп), а VK-эхо приходитitem_title=…%26quot%3B…(") — т.е. экранирует именно VK. Корень — сторона VK; у нас — guard от повторения.Правка
validateProduct(единственный валидатор, на путиCreateProduct/UpdateProduct/SetProductActiveиз admin-консоли) теперь отклоняет названия с& < > " '. Reject, не transform: оператор перепечатывает чистое название (ёлочки«»), поэтому сохранённое значение одинаково везде — витрина, кошелёк, платёжное окно VK. Ни второй callback, ни шлюз не трогаем; знать точный набор экранируемых VK символов не требуется — запрещаем весь HTML-спецнабор.Тесты / доки
catalog_admin_test.go— кейсы на" & < > '(ошибка) + ёлочки (ок) + черновик.catalog_editor_test).docs/PAYMENTS.md§7, agent field notes, Go Doc наvalidateProduct.A product title containing & < > " ' silently breaks VK purchases: VK HTML-escapes the character in its order_status_change payment-callback echo (e.g. " -> ") but signs the notification over a different form, so the gateway's signature check no longer matches ("vk callback: bad signature") and the purchase never confirms — while get_item (whose request carries no title) still passes. validateProduct now rejects those characters at the admin catalog editor — the single write path for CreateProduct/UpdateProduct/SetProductActive — so a title can't reintroduce the break. Reject, not transform: the operator retypes a clean title (« » guillemets, not straight quotes), so the stored value stays identical everywhere (storefront, wallet, VK box). Docs: docs/PAYMENTS.md §7 + agent field notes; Go Doc on validateProduct. Test: validateProduct HTML-special-char cases. No wire/schema change.