tiktak: не выдавать доступ к несуществующему видео
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>
This commit is contained in:
@@ -232,6 +232,19 @@ func (s *Server) handleAccess(c echo.Context) error {
|
|||||||
key := c.FormValue("token")
|
key := c.FormValue("token")
|
||||||
if keygen.ValidateKey(key, vid) {
|
if keygen.ValidateKey(key, vid) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
|
// AddAccess не проверял существование видео, поэтому можно было
|
||||||
|
// пре-авторизоваться на ещё не созданные id (и на отрицательные).
|
||||||
|
// Такая строка в access переживает любую последующую ротацию
|
||||||
|
// токенов: haveAccess() смотрит в таблицу, а не на токен.
|
||||||
|
v, err := s.db.GetVideo(ctx, vid)
|
||||||
|
if err != nil || v == nil {
|
||||||
|
return c.Render(http.StatusUnprocessableEntity, "access", AccessResponse{
|
||||||
|
ErrorResponse: ErrorResponse{"no such video"},
|
||||||
|
ID: vid,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if err := s.db.AddAccess(ctx, vid, ac.GetId()); err != nil {
|
if err := s.db.AddAccess(ctx, vid, ac.GetId()); err != nil {
|
||||||
return c.Render(http.StatusServiceUnavailable, "access", AccessResponse{
|
return c.Render(http.StatusServiceUnavailable, "access", AccessResponse{
|
||||||
ErrorResponse: ErrorResponse{"try again later: " + err.Error()},
|
ErrorResponse: ErrorResponse{"try again later: " + err.Error()},
|
||||||
|
|||||||
Reference in New Issue
Block a user