Skip to content

fix(02moviedownloader): handle AES-256-CBC encrypted API response#41

Merged
An0n-01 merged 9 commits into
cinepro-org:devfrom
Inside4ndroid:main
May 4, 2026
Merged

fix(02moviedownloader): handle AES-256-CBC encrypted API response#41
An0n-01 merged 9 commits into
cinepro-org:devfrom
Inside4ndroid:main

Conversation

@Inside4ndroid

Copy link
Copy Markdown
Contributor

Description

The 02MovieDownloader provider stopped returning sources after the site introduced an encrypted response layer on the /api/download/movie/:id and /api/download/tv/:id/:season/:episode endpoints.

Previously the API returned plaintext JSON. It now returns an encrypted envelope:

{ "encrypted": true, "data": "<iv_base64>:<ciphertext_base64>" }

The payload is AES-256-CBC encrypted using a key derived from SHA-256(sessionToken), where sessionToken is the value issued by /api/verify-robot. This mirrors the browser-side slider CAPTCHA flow — the site's own JavaScript (decryptDownloadPayloadWithToken) performs the same decryption before rendering the download page.

This PR adds server-side decryption of the payload using Node's built-in crypto module, restoring full provider functionality with no new dependencies.

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)

Related Issues

Closes #

Changes Made

  • Added EncryptedResponse interface to 02moviedownloader.types.ts to type the new encrypted envelope response
  • Imported createDecipheriv and createHash from Node's built-in crypto module in the provider
  • Added decryptPayload(cipherBundle: string, token: string) private method that replicates the browser's AES-256-CBC decryption: derives the 256-bit key via SHA-256(token), splits the bundle on : to extract the IV and ciphertext, and returns the decrypted MovieDownloaderResponse
  • Updated fetchPage() to detect encrypted === true in the response and call decryptPayload() before returning, with no change to the existing code path for unencrypted responses

Provider Information

Provider Details

  • Provider Name: 02MovieDownloader
  • Provider ID: 02moviedownloader
  • Base URL: https://02moviedownloader.site
  • Content Types Supported:
    • Movies
    • TV Shows

Provider Testing

Tested with the following TMDB IDs:

  • Movies:
    • TMDB ID: 550 (Fight Club)
  • TV Shows:
    • TMDB ID: 1399/1/1 (Game of Thrones S01E01)

Test Results:

Confirmed the three-step flow works end-to-end:

  1. POST /api/verify-robot → returns { token, expiresIn: 300 }
  2. GET /api/download/movie/:id with x-session-token header → returns { encrypted: true, data: "..." }
  3. AES-256-CBC decryption using SHA-256(token) as key → returns full MovieDownloaderResponse with downloads and externalStreams
Step 1: POST /api/verify-robot → 201 { success: true, token: '...', expiresIn: 300 }
Step 2: GET /api/download/movie/550 → 200 { encrypted: true, data: '<iv>:<ciphertext>' }
Step 3: Decrypted successfully → { success: true, data: { downloads: [...], ... }, externalStreams: [...] }

Checklist

General

  • My code follows the code style of this project
  • My code builds without errors (npm run build)
  • I have tested my changes locally
  • My changes generate no new warnings or errors

Provider Checklist

  • Provider extends BaseProvider from @omss/framework
  • Provider has a unique id and descriptive name
  • Provider declares correct capabilities (movies/tv support)
  • Implements getMovieSources() and getTVSources() correctly
  • All streaming URLs use this.createProxyUrl() for proxying
  • Includes proper error handling with diagnostics
  • Returns standardized ProviderResult format
  • Handles edge cases (missing content, API errors)

Documentation

  • No README or environment variable changes required — this is an internal implementation fix

Testing

How Has This Been Tested?

Manually verified the full token + decryption flow via Node.js against the live API.

Testing Steps:

  1. POST https://02moviedownloader.site/api/verify-robot to obtain a session token
  2. GET https://02moviedownloader.site/api/download/movie/550 with x-session-token: <token> header
  3. Confirmed response is { encrypted: true, data: "..." }
  4. Decrypted using SHA-256(token) as AES-256-CBC key — confirmed MovieDownloaderResponse structure is intact with sources and subtitles

Test Output

Step 1 status: 200
Cookies: []
Step 2 status: 201 { success: true, token: 'MTlk...', expiresIn: 300 }
Step 3 status: 200
Encrypted? true
Has data? true
Keys: [ 'encrypted', 'data' ]
Decrypted successfully — sources and externalStreams present

Additional Context

Performance Impact

  • No performance impact

The decryption happens entirely in-process using Node's native crypto module (no external dependency, no additional network call). The existing getToken() call to /api/verify-robot was already part of the flow.

Breaking Changes

None. The decryptPayload path is only entered when encrypted === true is present in the response. Unencrypted responses (if the site ever reverts) continue to work via the existing code path.

Dependencies

No new dependencies. Uses Node.js built-in crypto module.

@An0n-01 An0n-01 changed the base branch from main to dev May 4, 2026 19:44

@An0n-01 An0n-01 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

@An0n-01 An0n-01 merged commit 7c18050 into cinepro-org:dev May 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants