Commit Graph
4 Commits
Author SHA1 Message Date
bobiqqandClaude Opus 5 b88fc06d36 tiktak: не выдавать доступ к несуществующему видео
build-and-push / detect (push) Successful in 10s
build-and-push / build (${{ fromJSON(needs.detect.outputs.services) }}) (push) Successful in 30s
handleAccess вызывал AddAccess не проверяя, что видео существует. Значит
можно было пре-авторизоваться на ещё не созданные id (и на отрицательные):
POST /access videoID=<top+3000> с форженным токеном возвращает 302, строка
в access создаётся, и когда чекер создаст видео с этим id -- доступ уже
есть.

Главное: такая строка ПЕРЕЖИВАЕТ ротацию токенов. haveAccess() смотрит в
таблицу access, а не на токен, поэтому переход на HMAC от заранее набитых
записей не защищает.

Проверено на 10.10.10.5: /access для id=top+3000 -> 302 /watch/63481.

Чистка уже накопленного мусора (легитимных записей на несуществующие видео
быть не может):
  DELETE a FROM access a LEFT JOIN video v ON v.id = a.video_id
  WHERE v.id IS NULL;

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 13:15:58 +03:00
bobiqqandClaude Opus 5 576baa3949 tiktak: защита от decompression bomb в /create
Приходят 100 КБ webm с VP8-кадром гигантского разрешения (boundary у них
буквально ----bomb*). Проверку f.Size > 5MB он проходит, validateWebm смотрит
только первые 512 байт, а ffmpeg разворачивает такой кадр в ~1 ГБ сырых
пикселей. При семафоре на 75 параллельных это укладывает box, чекер не
укладывается в свои 7 секунд => MUMBLE.

- video/probe.go: ffprobe читает geometry из заголовка (кадр не декодируется),
  режем > 4096 по стороне и > 8 Mpx.
- Blur: image.DecodeConfig до image.Decode, тот же лимит по пикселям.
  imaging.Blur держит несколько копий битмапа, без лимита это OOM сам по себе.
  Заодно f.Close(), которого не было.
- ffmpeg -threads 1, семафор 75 -> 16.
- BodyLimit 8M: размер видео проверялся, а форма нет. Огромные субтитры
  превращались в слайс на миллионы строк в GenerateVtt. Плюс явный
  MaxSubtitlesSize 64K.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 12:16:56 +03:00
bobiqqandClaude Opus 5 fac56abb1d tiktak: LFI/auth-bypass в /vtt/, утечка превью, креды
- handleVtt: id валидируется как положительное целое, ошибка GetVideo
  больше не игнорируется. Закрывает сразу два вектора: обход ACL через
  нулевой db.Video (Private=false => haveAccess пропускал анонима) и
  path traversal в path.Join(VttFolder, vid+".vtt").
- handleCreate: резкое превью приватного видео удаляется после блюра,
  иначе оно оставалось доступным в public/static через echo.Static.
- main.go: DSN приведён к паролю из compose (5935004 поменял только
  compose, из-за чего сервис не достучался бы до базы).
- db: пароли хешируются sha256 с pepper, сверка в Go constant-time,
  плейнтекст принимается как legacy => старые юзеры не теряют доступ.
- cookies: HttpOnly + Path=/ + SameSite=Lax.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 11:42:05 +03:00
bobiqq c231be0094 services
build-and-push / detect (push) Successful in 7s
build-and-push / build (${{ fromJSON(needs.detect.outputs.services) }}) (push) Failing after 3m33s
2026-08-26 11:04:23 +03:00