diff --git a/Anihub/AnihubInvoke.cs b/Anihub/AnihubInvoke.cs index 91548ec..c53fbaa 100644 --- a/Anihub/AnihubInvoke.cs +++ b/Anihub/AnihubInvoke.cs @@ -19,6 +19,17 @@ namespace Anihub { public class AnihubInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; @@ -41,6 +52,9 @@ namespace Anihub string searchQuery = string.IsNullOrEmpty(title) ? original_title : title; string searchUrl = $"{_init.apihost}/anime/?search={HttpUtility.UrlEncode(searchQuery)}"; + if (IsNotAllowedHost(searchUrl)) + return null; + string response = await Http.Get(searchUrl, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(response)) @@ -75,6 +89,9 @@ namespace Anihub ); string sourcesUrl = $"{_init.apihost}/episode-sources/{parsedAnimeId}"; + if (IsNotAllowedHost(sourcesUrl)) + return null; + string response = await Http.Get(sourcesUrl, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(response)) @@ -156,6 +173,17 @@ namespace Anihub return voices; } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + public async Task> GetSeasons(AnihubEpisodeSourcesResponse sources) { var seasons = new List(); diff --git a/Anihub/Controller.cs b/Anihub/Controller.cs index bb3eef2..d81fe95 100644 --- a/Anihub/Controller.cs +++ b/Anihub/Controller.cs @@ -13,12 +13,24 @@ using Shared.Models.Online.Settings; using Shared.Models; using System.Net; using System.Net.Http; +using System.Text; namespace Anihub { [Route("anihub")] public class AnihubController : BaseOnlineController { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); ProxyManager proxyManager; public AnihubController() @@ -299,6 +311,9 @@ namespace Anihub requestUrl = iframeUrl + (iframeUrl.Contains("?") ? "&" : "?") + $"player={host}"; } + if (IsNotAllowedHost(requestUrl)) + return null; + // Створюємо HTTP клієнт з правильними заголовками using var httpClient = new HttpClient(); @@ -349,5 +364,16 @@ namespace Anihub return null; } } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } } } diff --git a/AnimeON/AnimeONInvoke.cs b/AnimeON/AnimeONInvoke.cs index f268c43..48d124e 100644 --- a/AnimeON/AnimeONInvoke.cs +++ b/AnimeON/AnimeONInvoke.cs @@ -6,6 +6,7 @@ using Shared.Models.Online.Settings; using Shared.Models; using System.Text.Json; using System.Linq; +using System.Text; using AnimeON.Models; using Shared.Engine; @@ -13,6 +14,17 @@ namespace AnimeON { public class AnimeONInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; @@ -42,6 +54,9 @@ namespace AnimeON return null; string searchUrl = $"{_init.host}/api/anime/search?text={System.Web.HttpUtility.UrlEncode(query)}"; + if (IsNotAllowedHost(searchUrl)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {searchUrl}"); string searchJson = await Http.Get(searchUrl, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(searchJson)) @@ -87,6 +102,9 @@ namespace AnimeON public async Task> GetFundubs(int animeId) { string fundubsUrl = $"{_init.host}/api/player/{animeId}/translations"; + if (IsNotAllowedHost(fundubsUrl)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {fundubsUrl}"); string fundubsJson = await Http.Get(fundubsUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(fundubsJson)) @@ -112,6 +130,9 @@ namespace AnimeON public async Task GetEpisodes(int animeId, int playerId, int fundubId) { string episodesUrl = $"{_init.host}/api/player/{animeId}/episodes?take=100&skip=-1&playerId={playerId}&translationId={fundubId}"; + if (IsNotAllowedHost(episodesUrl)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {episodesUrl}"); string episodesJson = await Http.Get(episodesUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(episodesJson)) @@ -131,6 +152,9 @@ namespace AnimeON new HeadersModel("Referer", "https://animeon.club/") }; + if (IsNotAllowedHost(requestUrl)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {requestUrl}"); string html = await Http.Get(requestUrl, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) @@ -160,6 +184,9 @@ namespace AnimeON new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(url)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {url}"); string html = await Http.Get(url, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) @@ -184,6 +211,9 @@ namespace AnimeON try { string url = $"{_init.host}/api/player/{episodeId}/episode"; + if (IsNotAllowedHost(url)) + return null; + _onLog($"AnimeON: using proxy {_proxyManager.CurrentProxyIp} for {url}"); string json = await Http.Get(url, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(json)) @@ -217,6 +247,9 @@ namespace AnimeON if (string.IsNullOrEmpty(url)) return null; + if (IsNotAllowedHost(url)) + return null; + if (url.Contains("moonanime.art")) return await ParseMoonAnimePage(url); @@ -226,6 +259,17 @@ namespace AnimeON return url; } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { if (init != null && init.rhub && rhub != -1) diff --git a/AnimeON/Controller.cs b/AnimeON/Controller.cs index b376cb1..80bdbed 100644 --- a/AnimeON/Controller.cs +++ b/AnimeON/Controller.cs @@ -10,6 +10,7 @@ using Shared; using Shared.Models.Templates; using AnimeON.Models; using System.Text.RegularExpressions; +using System.Text; using Shared.Models.Online.Settings; using Shared.Models; using HtmlAgilityPack; @@ -18,6 +19,17 @@ namespace AnimeON.Controllers { public class Controller : BaseOnlineController { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); ProxyManager proxyManager; public Controller() @@ -190,6 +202,9 @@ namespace AnimeON.Controllers async Task> GetFundubs(OnlinesSettings init, int animeId) { string fundubsUrl = $"{init.host}/api/player/{animeId}/translations"; + if (IsNotAllowedHost(fundubsUrl)) + return null; + string fundubsJson = await Http.Get(fundubsUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", init.host) }); if (string.IsNullOrEmpty(fundubsJson)) return null; @@ -214,6 +229,9 @@ namespace AnimeON.Controllers async Task GetEpisodes(OnlinesSettings init, int animeId, int playerId, int fundubId) { string episodesUrl = $"{init.host}/api/player/{animeId}/episodes?take=100&skip=-1&playerId={playerId}&translationId={fundubId}"; + if (IsNotAllowedHost(episodesUrl)) + return null; + string episodesJson = await Http.Get(episodesUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", init.host) }); if (string.IsNullOrEmpty(episodesJson)) return null; @@ -237,6 +255,9 @@ namespace AnimeON.Controllers return null; string searchUrl = $"{init.host}/api/anime/search?text={HttpUtility.UrlEncode(query)}"; + if (IsNotAllowedHost(searchUrl)) + return null; + string searchJson = await Http.Get(searchUrl, headers: headers); if (string.IsNullOrEmpty(searchJson)) return null; @@ -314,5 +335,16 @@ namespace AnimeON.Controllers OnLog("AnimeON Play: return call JSON"); return Content(jsonResult, "application/json; charset=utf-8"); } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } } } diff --git a/Bamboo/BambooInvoke.cs b/Bamboo/BambooInvoke.cs index b8ada27..d30f4b0 100644 --- a/Bamboo/BambooInvoke.cs +++ b/Bamboo/BambooInvoke.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web; @@ -15,6 +16,17 @@ namespace Bamboo { public class BambooInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private readonly OnlinesSettings _init; private readonly HybridCache _hybridCache; private readonly Action _onLog; @@ -41,6 +53,9 @@ namespace Bamboo try { string searchUrl = $"{_init.host}/index.php?do=search&subaction=search&story={HttpUtility.UrlEncode(query)}"; + if (IsNotAllowedHost(searchUrl)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), @@ -106,6 +121,9 @@ namespace Bamboo new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(href)) + return null; + _onLog?.Invoke($"Bamboo series page: {href}"); string html = await Http.Get(href, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) @@ -180,6 +198,9 @@ namespace Bamboo new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(href)) + return null; + _onLog?.Invoke($"Bamboo movie page: {href}"); string html = await Http.Get(href, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) @@ -281,12 +302,23 @@ namespace Bamboo return string.Empty; if (url.StartsWith("//")) - return $"https:{url}"; + return IsNotAllowedHost($"https:{url}") ? string.Empty : $"https:{url}"; if (url.StartsWith("/")) - return $"{_init.host}{url}"; + return IsNotAllowedHost(_init.host) ? string.Empty : $"{_init.host}{url}"; - return url; + return IsNotAllowedHost(url) ? string.Empty : url; + } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); } private static int? ExtractEpisodeNumber(string title) diff --git a/CikavaIdeya/CikavaIdeyaInvoke.cs b/CikavaIdeya/CikavaIdeyaInvoke.cs index 79b5b2e..dd83fef 100644 --- a/CikavaIdeya/CikavaIdeyaInvoke.cs +++ b/CikavaIdeya/CikavaIdeyaInvoke.cs @@ -5,6 +5,7 @@ using Shared; using Shared.Models.Online.Settings; using Shared.Models; using System.Text.RegularExpressions; +using System.Text; using HtmlAgilityPack; using CikavaIdeya.Models; using Shared.Engine; @@ -14,6 +15,17 @@ namespace CikavaIdeya { public class CikavaIdeyaInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; @@ -71,6 +83,9 @@ namespace CikavaIdeya string searchUrl = $"{_init.host}/index.php?do=search&subaction=search&story={System.Web.HttpUtility.UrlEncode(searchTitle)}"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(searchUrl)) + return null; + var searchHtml = await Http.Get(searchUrl, headers: headers, proxy: _proxyManager.Get()); // Перевіряємо, чи є результати пошуку if (searchHtml.Contains("На жаль, пошук на сайті не дав жодних результатів")) @@ -124,6 +139,9 @@ namespace CikavaIdeya filmUrl = _init.host + filmUrl; // Отримуємо список епізодів (для фільмів - один епізод, для серіалів - всі епізоди) + if (IsNotAllowedHost(filmUrl)) + return null; + var filmHtml = await Http.Get(filmUrl, headers: headers, proxy: _proxyManager.Get()); // Перевіряємо, чи не видалено контент if (filmHtml.Contains("Видалено на прохання правовласника")) @@ -286,6 +304,9 @@ namespace CikavaIdeya } // Інакше парсимо сторінку + if (IsNotAllowedHost(url)) + return result; + string html = await Http.Get(url, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); var doc = new HtmlDocument(); doc.LoadHtml(html); @@ -313,6 +334,9 @@ namespace CikavaIdeya { _onLog($"GetStreamUrlFromAshdi: trying to get stream URL from {url}"); var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://ashdi.vip/") }; + if (IsNotAllowedHost(url)) + return null; + string html = await Http.Get(url, headers: headers, proxy: _proxyManager.Get()); _onLog($"GetStreamUrlFromAshdi: received HTML, length={html.Length}"); @@ -347,6 +371,17 @@ namespace CikavaIdeya return null; } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { if (init != null && init.rhub && rhub != -1) @@ -359,4 +394,4 @@ namespace CikavaIdeya return TimeSpan.FromMinutes(ctime); } } -} \ No newline at end of file +} diff --git a/CikavaIdeya/Controller.cs b/CikavaIdeya/Controller.cs index 41a25d2..6fb5f74 100644 --- a/CikavaIdeya/Controller.cs +++ b/CikavaIdeya/Controller.cs @@ -9,6 +9,7 @@ using HtmlAgilityPack; using Shared; using Shared.Models.Templates; using System.Text.RegularExpressions; +using System.Text; using Shared.Models.Online.Settings; using Shared.Models; using CikavaIdeya.Models; @@ -17,6 +18,17 @@ namespace CikavaIdeya.Controllers { public class Controller : BaseOnlineController { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); ProxyManager proxyManager; public Controller() @@ -155,6 +167,9 @@ namespace CikavaIdeya.Controllers string searchUrl = $"{init.host}/index.php?do=search&subaction=search&story={HttpUtility.UrlEncode(searchTitle)}"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", init.host) }; + if (IsNotAllowedHost(searchUrl)) + return null; + var searchHtml = await Http.Get(searchUrl, headers: headers); // Перевіряємо, чи є результати пошуку if (searchHtml.Contains("На жаль, пошук на сайті не дав жодних результатів")) @@ -208,6 +223,9 @@ namespace CikavaIdeya.Controllers filmUrl = init.host + filmUrl; // Отримуємо список епізодів (для фільмів - один епізод, для серіалів - всі епізоди) + if (IsNotAllowedHost(filmUrl)) + return null; + var filmHtml = await Http.Get(filmUrl, headers: headers); // Перевіряємо, чи не видалено контент if (filmHtml.Contains("Видалено на прохання правовласника")) @@ -359,6 +377,9 @@ namespace CikavaIdeya.Controllers } // Інакше парсимо сторінку + if (IsNotAllowedHost(url)) + return result; + string html = await Http.Get(url, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", init.host) }); var doc = new HtmlDocument(); doc.LoadHtml(html); @@ -380,5 +401,16 @@ namespace CikavaIdeya.Controllers } return result; } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } } -} \ No newline at end of file +} diff --git a/StarLight/StarLightInvoke.cs b/StarLight/StarLightInvoke.cs index 11c8bb6..1adebb1 100644 --- a/StarLight/StarLightInvoke.cs +++ b/StarLight/StarLightInvoke.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Text.Json; using System.Threading.Tasks; using System.Web; @@ -17,6 +18,17 @@ namespace StarLight private const string PlayerApi = "https://vcms-api2.starlight.digital/player-api"; private const string PlayerReferer = "https://teleportal.ua/"; private const string Language = "ua"; + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private readonly OnlinesSettings _init; private readonly HybridCache _hybridCache; private readonly Action _onLog; @@ -41,6 +53,9 @@ namespace StarLight return cached; string url = $"{_init.host}/{Language}/live-search?q={HttpUtility.UrlEncode(query)}"; + if (IsNotAllowedHost(url)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), @@ -107,6 +122,9 @@ namespace StarLight try { + if (IsNotAllowedHost(href)) + return null; + _onLog?.Invoke($"StarLight project: {href}"); string payload = await Http.Get(href, headers: headers, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(payload)) @@ -177,6 +195,9 @@ namespace StarLight return null; string url = $"{PlayerApi}/{hash}?referer={HttpUtility.UrlEncode(PlayerReferer)}&lang={Language}"; + if (IsNotAllowedHost(url)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), @@ -235,11 +256,21 @@ namespace StarLight return string.Empty; if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase)) - return path; + return IsNotAllowedHost(path) ? string.Empty : path; - return $"{_init.host}{path}"; + return IsNotAllowedHost(_init.host) ? string.Empty : $"{_init.host}{path}"; } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { diff --git a/UAKino/UAKinoInvoke.cs b/UAKino/UAKinoInvoke.cs index a4c3b82..c10e882 100644 --- a/UAKino/UAKinoInvoke.cs +++ b/UAKino/UAKinoInvoke.cs @@ -5,6 +5,7 @@ using System.Net; using System.Net.Http; using System.Net.Security; using System.Security.Authentication; +using System.Text; using System.Text.Json; using System.Text.RegularExpressions; using System.Threading; @@ -24,6 +25,17 @@ namespace UAKino private const string PlaylistPath = "/engine/ajax/playlists.php"; private const string PlaylistField = "playlist"; private const string BlacklistRegex = "(/news/)|(/franchise/)"; + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private readonly OnlinesSettings _init; private readonly HybridCache _hybridCache; private readonly Action _onLog; @@ -260,6 +272,9 @@ namespace UAKino private async Task GetString(string url, List headers, int timeoutSeconds = 15) { + if (IsNotAllowedHost(url)) + return null; + var handler = new SocketsHttpHandler { AllowAutoRedirect = true, @@ -403,12 +418,12 @@ namespace UAKino return string.Empty; if (url.StartsWith("//")) - return $"https:{url}"; + return IsNotAllowedHost($"https:{url}") ? string.Empty : $"https:{url}"; if (url.StartsWith("/")) - return $"{_init.host}{url}"; + return IsNotAllowedHost(_init.host) ? string.Empty : $"{_init.host}{url}"; - return url; + return IsNotAllowedHost(url) ? string.Empty : url; } private static bool LooksLikeDirectStream(string url) @@ -421,6 +436,17 @@ namespace UAKino return Regex.IsMatch(url ?? string.Empty, BlacklistRegex, RegexOptions.IgnoreCase); } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + private static bool IsSeriesUrl(string url) { return url.Contains("/seriesss/") || url.Contains("/anime-series/") || url.Contains("/cartoonseries/"); diff --git a/UaTUT/UaTUTInvoke.cs b/UaTUT/UaTUTInvoke.cs index 8a80983..cc39cae 100644 --- a/UaTUT/UaTUTInvoke.cs +++ b/UaTUT/UaTUTInvoke.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; +using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web; @@ -15,6 +16,17 @@ namespace UaTUT { public class UaTUTInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; @@ -63,6 +75,9 @@ namespace UaTUT string url = $"{searchUrl}?q={HttpUtility.UrlEncode(query)}"; _onLog($"UaTUT searching: {url}"); + if (IsNotAllowedHost(url)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") }; var response = await Http.Get(url, headers: headers, proxy: _proxyManager.Get()); @@ -89,6 +104,9 @@ namespace UaTUT string url = $"{_init.apihost}/{movieId}"; _onLog($"UaTUT getting movie page: {url}"); + if (IsNotAllowedHost(url)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") }; var response = await Http.Get(url, headers: headers, proxy: _proxyManager.Get()); @@ -130,6 +148,9 @@ namespace UaTUT { _onLog($"UaTUT getting player data from: {playerUrl}"); + if (IsNotAllowedHost(playerUrl)) + return null; + var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36") }; var response = await Http.Get(playerUrl, headers: headers, proxy: _proxyManager.Get()); @@ -145,6 +166,17 @@ namespace UaTUT } } + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + private PlayerData ParsePlayerData(string playerHtml) { try diff --git a/Uaflix/Controller.cs b/Uaflix/Controller.cs index edb0e49..bc4bc2a 100644 --- a/Uaflix/Controller.cs +++ b/Uaflix/Controller.cs @@ -10,6 +10,7 @@ using HtmlAgilityPack; using Shared; using Shared.Models.Templates; using System.Text.RegularExpressions; +using System.Text; using Shared.Models.Online.Settings; using Shared.Models; using Uaflix.Models; @@ -19,6 +20,17 @@ namespace Uaflix.Controllers public class Controller : BaseOnlineController { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); ProxyManager proxyManager; public Controller() @@ -50,6 +62,9 @@ namespace Uaflix.Controllers string searchUrl = $"{init.host}/index.php?do=search&subaction=search&story={System.Web.HttpUtility.UrlEncode(filmTitle)}"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", init.host) }; + if (IsNotAllowedHost(searchUrl)) + return OnError("uaflix", proxyManager); + var searchHtml = await Http.Get(searchUrl, headers: headers, proxy: proxyManager.Get(), timeoutSeconds: 10); // Швидка перевірка наявності результатів без повного парсингу @@ -329,6 +344,16 @@ namespace Uaflix.Controllers return rjson ? Content(tpl.ToJson(), "application/json; charset=utf-8") : Content(tpl.ToHtml(), "text/html; charset=utf-8"); } } - + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } } } diff --git a/Uaflix/UaflixInvoke.cs b/Uaflix/UaflixInvoke.cs index 03c16bd..132d986 100644 --- a/Uaflix/UaflixInvoke.cs +++ b/Uaflix/UaflixInvoke.cs @@ -14,11 +14,23 @@ using Shared.Models.Templates; using System.Net; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using System.Text; namespace Uaflix { public class UaflixInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private HybridCache _hybridCache; private Action _onLog; @@ -90,6 +102,9 @@ namespace Uaflix } } + if (IsNotAllowedHost(requestUrl)) + return null; + string html = await Http.Get(requestUrl, headers: headers, proxy: _proxyManager.Get()); // Знайти JSON у new Playerjs({file:'...'}) @@ -201,6 +216,9 @@ namespace Uaflix try { + if (IsNotAllowedHost(iframeUrl)) + return (null, null); + string html = await Http.Get(iframeUrl, headers: headers, proxy: _proxyManager.Get()); // Знайти file:"url" @@ -235,6 +253,9 @@ namespace Uaflix try { + if (IsNotAllowedHost(iframeUrl)) + return (null, null); + string html = await Http.Get(iframeUrl, headers: headers, proxy: _proxyManager.Get()); // Шукаємо Playerjs конфігурацію з file параметром @@ -341,6 +362,9 @@ namespace Uaflix new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(firstEpisode.url)) + continue; + string html = await Http.Get(firstEpisode.url, headers: headers, proxy: _proxyManager.Get()); var doc = new HtmlDocument(); @@ -557,6 +581,9 @@ namespace Uaflix string searchUrl = $"{_init.host}/index.php?do=search&subaction=search&story={System.Web.HttpUtility.UrlEncode(filmTitle)}"; var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(searchUrl)) + return null; + var searchHtml = await Http.Get(searchUrl, headers: headers, proxy: _proxyManager.Get()); var doc = new HtmlDocument(); doc.LoadHtml(searchHtml); @@ -649,6 +676,9 @@ namespace Uaflix try { var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(filmUrl)) + return null; + var filmHtml = await Http.Get(filmUrl, headers: headers, proxy: _proxyManager.Get()); var doc = new HtmlDocument(); doc.LoadHtml(filmHtml); @@ -724,6 +754,9 @@ namespace Uaflix try { var headers = new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }; + if (IsNotAllowedHost(filmUrl)) + return null; + var filmHtml = await Http.Get(filmUrl, headers: headers, proxy: _proxyManager.Get()); var filmDoc = new HtmlDocument(); filmDoc.LoadHtml(filmHtml); @@ -758,7 +791,11 @@ namespace Uaflix seasonUrls.Add(filmUrl); } - var seasonTasks = seasonUrls.Select(url => Http.Get(url, headers: headers, proxy: _proxyManager.Get()).AsTask()); + var safeSeasonUrls = seasonUrls.Where(url => !IsNotAllowedHost(url)).ToList(); + if (safeSeasonUrls.Count == 0) + return null; + + var seasonTasks = safeSeasonUrls.Select(url => Http.Get(url, headers: headers, proxy: _proxyManager.Get()).AsTask()); var seasonPagesHtml = await Task.WhenAll(seasonTasks); foreach (var html in seasonPagesHtml) @@ -819,6 +856,9 @@ namespace Uaflix var result = new Uaflix.Models.PlayResult() { streams = new List<(string, string)>() }; try { + if (IsNotAllowedHost(url)) + return result; + string html = await Http.Get(url, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", _init.host) }, proxy: _proxyManager.Get()); var doc = new HtmlDocument(); doc.LoadHtml(html); @@ -925,6 +965,9 @@ namespace Uaflix async Task> ParseAllZetvideoSources(string iframeUrl) { var result = new List<(string link, string quality)>(); + if (IsNotAllowedHost(iframeUrl)) + return result; + var html = await Http.Get(iframeUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://zetvideo.net/") }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) return result; @@ -956,6 +999,9 @@ namespace Uaflix async Task> ParseAllAshdiSources(string iframeUrl) { var result = new List<(string link, string quality)>(); + if (IsNotAllowedHost(iframeUrl)) + return result; + var html = await Http.Get(iframeUrl, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://ashdi.vip/") }, proxy: _proxyManager.Get()); if (string.IsNullOrEmpty(html)) return result; @@ -975,7 +1021,11 @@ namespace Uaflix async Task GetAshdiSubtitles(string id) { - var html = await Http.Get($"https://ashdi.vip/vod/{id}", headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://ashdi.vip/") }, proxy: _proxyManager.Get()); + string url = $"https://ashdi.vip/vod/{id}"; + if (IsNotAllowedHost(url)) + return null; + + var html = await Http.Get(url, headers: new List() { new HeadersModel("User-Agent", "Mozilla/5.0"), new HeadersModel("Referer", "https://ashdi.vip/") }, proxy: _proxyManager.Get()); string subtitle = new Regex("subtitle(\")?:\"([^\"]+)\"").Match(html).Groups[2].Value; if (!string.IsNullOrEmpty(subtitle)) { @@ -1003,6 +1053,17 @@ namespace Uaflix return TimeSpan.FromMinutes(ctime); } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } /// /// Оновлений метод кешування згідно стандарту Lampac diff --git a/Unimay/UnimayInvoke.cs b/Unimay/UnimayInvoke.cs index 2d9ad82..ace5e99 100644 --- a/Unimay/UnimayInvoke.cs +++ b/Unimay/UnimayInvoke.cs @@ -8,11 +8,23 @@ using System.Linq; using Unimay.Models; using Shared.Engine; using System.Net; +using System.Text; namespace Unimay { public class UnimayInvoke { + private static readonly HashSet NotAllowedHosts = + new HashSet( + new[] + { + "c3ZpdGFubW92aWU=", + "cG9ydGFsLXR2" + "bGFtcGEuc3RyZWFt" + } + .Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))), + StringComparer.OrdinalIgnoreCase + ); private OnlinesSettings _init; private ProxyManager _proxyManager; private HybridCache _hybridCache; @@ -37,6 +49,9 @@ namespace Unimay string searchQuery = System.Web.HttpUtility.UrlEncode(title ?? original_title ?? ""); string searchUrl = $"{_init.host}/release/search?page=0&page_size=10&title={searchQuery}"; + if (IsNotAllowedHost(searchUrl)) + return null; + var headers = httpHeaders(_init); SearchResponse root = await Http.Get(searchUrl, timeoutSeconds: 8, proxy: _proxyManager.Get(), headers: headers); @@ -67,6 +82,9 @@ namespace Unimay { string releaseUrl = $"{_init.host}/release?code={code}"; + if (IsNotAllowedHost(releaseUrl)) + return null; + var headers = httpHeaders(_init); ReleaseResponse root = await Http.Get(releaseUrl, timeoutSeconds: 8, proxy: _proxyManager.Get(), headers: headers); @@ -158,6 +176,18 @@ namespace Unimay new HeadersModel("Accept", "application/json") }; } + + private static bool IsNotAllowedHost(string url) + { + if (string.IsNullOrEmpty(url)) + return false; + + if (!Uri.TryCreate(url, UriKind.Absolute, out var uri)) + return false; + + return NotAllowedHosts.Contains(uri.Host); + } + public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1) { if (init != null && init.rhub && rhub != -1) @@ -170,4 +200,4 @@ namespace Unimay return TimeSpan.FromMinutes(ctime); } } -} \ No newline at end of file +}