Skip to content

Instantly share code, notes, and snippets.

@yasinkuyu
Last active September 30, 2025 21:53
Show Gist options
  • Select an option

  • Save yasinkuyu/bb3e1abe15ebdc099201724f4cbd2100 to your computer and use it in GitHub Desktop.

Select an option

Save yasinkuyu/bb3e1abe15ebdc099201724f4cbd2100 to your computer and use it in GitHub Desktop.
PHP CURL function which bypasses the Cloudflare
<?php
/*
Cloudflare Bypass Class with JavaScript Challenge Solver
Advanced PHP CURL implementation to bypass Cloudflare protection
Features:
- Automatic JavaScript challenge solving
- HTTP redirect handling
- Content decompression (gzip/deflate)
- Browser-like headers simulation
- Error handling and debugging
- Object-oriented design with configurable options
@yasinkuyu
CHANGELOG:
v3.0 (Latest) - Object-Oriented Version
- ✅ Converted to class-based architecture
- ✅ Added configurable user agent and headers
- ✅ Added timeout and retry options
- ✅ Enhanced error handling with exceptions
- ✅ Added debug mode for detailed logging
- ✅ Improved code organization and reusability
v2.0 (Previous)
- ✅ Added JavaScript challenge solver (solveJavaScriptChallenge function)
- ✅ Implemented HTTP redirect following (CURLOPT_FOLLOWLOCATION)
- ✅ Added automatic content decompression (CURLOPT_ENCODING)
- ✅ Enhanced browser simulation with realistic headers
- ✅ Improved error handling and debugging output
- ✅ Fixed User-Agent string formatting
- ✅ Added Cloudflare challenge detection indicators
- ✅ Support for mathematical operations in JS challenges (+, -, *, domain length)
- ✅ Full content output instead of truncated preview
v1.0 (Initial)
- Basic Cloudflare bypass functionality
- Simple cURL implementation
*/
class CloudflareBypass {
private $userAgent;
private $timeout;
private $maxRedirects;
private $debugMode;
private $lastError;
/**
* Constructor
* @param array $options Configuration options
*/
public function __construct($options = []) {
$this->userAgent = $options['userAgent'] ?? "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 5X Build/MMB29P) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)";
$this->timeout = $options['timeout'] ?? 30;
$this->maxRedirects = $options['maxRedirects'] ?? 5;
$this->debugMode = $options['debugMode'] ?? false;
$this->lastError = null;
}
/**
* Get the last error message
* @return string|null
*/
public function getLastError() {
return $this->lastError;
}
/**
* Set debug mode
* @param bool $debug
*/
public function setDebugMode($debug) {
$this->debugMode = $debug;
}
/**
* Set custom user agent
* @param string $userAgent
*/
public function setUserAgent($userAgent) {
$this->userAgent = $userAgent;
}
/**
* Solve JavaScript challenge from Cloudflare
* @param string $html HTML content
* @param string $url Target URL
* @return int Challenge answer
*/
private function solveJavaScriptChallenge($html, $url) {
// Extract domain from URL for length calculation
$domain = parse_url($url, PHP_URL_HOST);
$domain_length = strlen($domain);
// Look for various Cloudflare challenge patterns
$patterns = [
'/setTimeout\(function\(\)\s*\{\s*var\s+s,t,o,p,b,r,e,a,k,i,n,g,f,\s*([^;]+);/',
'/<script[^>]*>.*?var\s+s,t,o,p,b,r,e,a,k,i,n,g,f,\s*([^;]+);.*?<\/script>/s',
'/jschl-answer["\']?\s*:\s*([^,}]+)/',
'/\.length\s*\+\s*(\d+)/',
'/(\d+)\s*\+\s*(\d+)/',
'/(\d+)\s*\*\s*(\d+)/',
'/(\d+)\s*-\s*(\d+)/'
];
foreach ($patterns as $pattern) {
if (preg_match($pattern, $html, $matches)) {
// Handle different types of challenges
if (strpos($matches[0], '.length') !== false) {
// Domain length based challenge
$number = isset($matches[1]) ? intval($matches[1]) : 0;
$result = $domain_length + $number;
if ($this->debugMode) {
echo "Debug: Domain length challenge solved: {$domain_length} + {$number} = {$result}\n";
}
return $result;
} elseif (strpos($matches[0], '+') !== false && isset($matches[1]) && isset($matches[2])) {
// Simple addition
$result = intval($matches[1]) + intval($matches[2]);
if ($this->debugMode) {
echo "Debug: Addition challenge solved: {$matches[1]} + {$matches[2]} = {$result}\n";
}
return $result;
} elseif (strpos($matches[0], '*') !== false && isset($matches[1]) && isset($matches[2])) {
// Multiplication
$result = intval($matches[1]) * intval($matches[2]);
if ($this->debugMode) {
echo "Debug: Multiplication challenge solved: {$matches[1]} * {$matches[2]} = {$result}\n";
}
return $result;
} elseif (strpos($matches[0], '-') !== false && isset($matches[1]) && isset($matches[2])) {
// Subtraction
$result = intval($matches[1]) - intval($matches[2]);
if ($this->debugMode) {
echo "Debug: Subtraction challenge solved: {$matches[1]} - {$matches[2]} = {$result}\n";
}
return $result;
}
}
}
// Fallback: return domain length (common in Cloudflare challenges)
if ($this->debugMode) {
echo "Debug: Using fallback domain length: {$domain_length}\n";
}
return $domain_length;
}
/**
* Check if content contains Cloudflare challenge indicators
* @param string $html HTML content
* @return bool
*/
private function isCloudflareChallenge($html) {
$cloudflare_indicators = [
'Checking your browser before accessing',
'cloudflare',
'jschl_vc',
'cf-browser-verification',
'Just a moment',
'Please wait while we check your browser'
];
foreach ($cloudflare_indicators as $indicator) {
if (stripos($html, $indicator) !== false) {
return true;
}
}
return false;
}
/**
* Bypass Cloudflare protection
* @param string $url Target URL
* @return string|false HTML content or false on failure
*/
public function bypass($url) {
$this->lastError = null;
if ($this->debugMode) {
echo "Debug: Starting bypass for URL: {$url}\n";
}
$ct = curl_init();
curl_setopt_array($ct, Array(
CURLOPT_URL => $url,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => $this->maxRedirects,
CURLOPT_TIMEOUT => $this->timeout,
CURLOPT_ENCODING => "", // Enable automatic decompression
CURLOPT_HTTPHEADER => array(
"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Language: en-US,en;q=0.5",
"Connection: keep-alive",
"Upgrade-Insecure-Requests: 1"
),
CURLOPT_REFERER => $url,
CURLOPT_USERAGENT => $this->userAgent,
CURLOPT_HEADER => false
));
$html = curl_exec($ct);
$http_code = curl_getinfo($ct, CURLINFO_HTTP_CODE);
if ($html === false) {
$this->lastError = "cURL error: " . curl_error($ct);
curl_close($ct);
return false;
}
if ($this->debugMode) {
echo "Debug: Initial request completed. HTTP Code: {$http_code}, Content Length: " . strlen($html) . "\n";
}
$dochtml = new DOMDocument();
@$dochtml->loadHTML($html);
$xpath = new DOMXpath($dochtml);
// Check if Cloudflare challenge is present
if(isset($xpath->query("//input[@name='r']/@value")->item(0)->textContent)){
if ($this->debugMode) {
echo "Debug: Cloudflare challenge detected, attempting to solve...\n";
}
$action = $url . $xpath->query("//form/@action")->item(0)->textContent;
$r = $xpath->query("//input[@name='r']/@value")->item(0)->textContent;
$jschl_vc = $xpath->query("//input[@name='jschl_vc']/@value")->item(0)->textContent;
$pass = $xpath->query("//input[@name='pass']/@value")->item(0)->textContent;
// Extract and solve JavaScript challenge
$jschl_answer = $this->solveJavaScriptChallenge($html, $url);
// Generate curl post data
$post_data = array(
'r' => $r,
'jschl_vc' => $jschl_vc,
'pass' => $pass,
'jschl_answer' => $jschl_answer
);
curl_close($ct); // Close curl
$ct = curl_init();
// Post cloudflare auth parameters
curl_setopt_array($ct, Array(
CURLOPT_HTTPHEADER => array(
'Accept: application/json, text/javascript, */*; q=0.01',
'Accept-Language: ro-RO,ro;q=0.8,en-US;q=0.6,en-GB;q=0.4,en;q=0.2',
'Referer: '. $url,
'Origin: '. $url,
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With: XMLHttpRequest'
),
CURLOPT_URL => $action,
CURLOPT_REFERER => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_USERAGENT => $this->userAgent,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($post_data),
CURLOPT_TIMEOUT => $this->timeout
));
$html_response = curl_exec($ct);
$http_code = curl_getinfo($ct, CURLINFO_HTTP_CODE);
if ($html_response === false) {
$this->lastError = "cURL error on challenge submission: " . curl_error($ct);
}
if ($this->debugMode) {
echo "Debug: Challenge submission completed. HTTP Code: {$http_code}, Content Length: " . strlen($html_response) . "\n";
}
curl_close($ct); // Close curl
return $html_response;
}else{
// Already authenticated or no challenge
if ($this->debugMode) {
echo "Debug: No Cloudflare challenge detected, content already accessible\n";
}
curl_close($ct);
return $html;
}
}
/**
* Test bypass with detailed output
* @param string $url Target URL
* @return array Result array with status and content
*/
public function testBypass($url) {
$result = $this->bypass($url);
$response = [
'success' => false,
'content' => null,
'content_length' => 0,
'is_challenge' => false,
'error' => null
];
if ($result) {
$response['success'] = true;
$response['content'] = $result;
$response['content_length'] = strlen($result);
$response['is_challenge'] = $this->isCloudflareChallenge($result);
} else {
$response['error'] = $this->getLastError();
}
return $response;
}
}
// Handle POST request from HTML form
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['test_url'])) {
$test_url = $_POST['test_url'];
} else {
// Default test URL
$test_url = "https://www.turkanime.co/"; # https://www.turkanime.net/
}
echo "Testing Cloudflare bypass for: " . $test_url . "\n\n";
// Create CloudflareBypass instance with options
$bypass = new CloudflareBypass([
'debugMode' => false, // Set to true for detailed debugging
'timeout' => 30,
'maxRedirects' => 5
]);
// Test the bypass
$result = $bypass->testBypass($test_url);
if ($result['success']) {
echo "Success! Retrieved content length: " . $result['content_length'] . " characters\n";
if ($result['is_challenge']) {
echo "⚠️ Cloudflare challenge detected - attempting to solve...\n";
} else {
echo "✅ Successfully bypassed Cloudflare protection!\n";
}
echo "Full content:\n";
echo htmlspecialchars($result['content']) . "\n";
} else {
echo "Failed to retrieve content\n";
if ($result['error']) {
echo "Error: " . $result['error'] . "\n";
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cloudflare Bypass Test Interface</title>
<!--
Cloudflare Bypass Test Interface
Web-based testing interface for the PHP Cloudflare bypass script
Features:
- Real-time bypass testing via AJAX
- Dual view: Source code + Rendered preview
- Responsive design for mobile/desktop
- Error handling and status indicators
- Full content display without truncation
@yasinkuyu
CHANGELOG:
v2.1 (Latest)
- ✅ Fixed source code overflow issues with min-width: 0
- ✅ Improved HTML escaping for iframe srcdoc
- ✅ Added responsive flex layout for dual view
- ✅ Enhanced CSS for better content display
- ✅ Fixed preview rendering in iframe
- ✅ Added proper overflow handling
v2.0
- ✅ Added dual view (source code + rendered preview)
- ✅ Implemented iframe srcdoc for HTML rendering
- ✅ Enhanced CSS styling and responsive design
- ✅ Improved JavaScript parsing and error handling
- ✅ Added full content display (no truncation)
v1.0 (Initial)
- Basic form interface for testing
- Simple result display
-->
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
max-width: 100%;
overflow-x: auto;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input[type="url"] {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
button {
background-color: #007cba;
color: white;
padding: 12px 24px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
}
button:hover {
background-color: #005a87;
}
.result {
margin-top: 20px;
padding: 15px;
background-color: #f8f9fa;
border-radius: 4px;
border-left: 4px solid #007cba;
}
.success {
border-left-color: #28a745;
background-color: #d4edda;
}
.warning {
border-left-color: #ffc107;
background-color: #fff3cd;
}
.error {
border-left-color: #dc3545;
background-color: #f8d7da;
}
pre {
background-color: #f8f9fa;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
overflow-y: auto;
border: 1px solid #dee2e6;
font-family: 'Courier New', monospace;
font-size: 10px;
line-height: 1.2;
white-space: pre-wrap;
word-wrap: break-word;
max-height: 400px;
width: 100%;
box-sizing: border-box;
}
.flex-container {
min-width: 0;
}
.flex-container>div {
min-width: 0;
overflow: hidden;
}
@media (max-width: 768px) {
.flex-container {
flex-direction: column !important;
}
}
</style>
</head>
<body>
<div class="container">
<h1>🛡️ Cloudflare Bypass Test</h1>
<p>Test the PHP Cloudflare bypass script with any URL:</p>
<form id="testForm">
<div class="form-group">
<label for="url">Website URL:</label>
<input type="url" id="url" name="url" value="https://www.turkanime.co/" required>
</div>
<button type="submit">Test Bypass</button>
</form>
<div id="result"></div>
</div>
<script>
document.getElementById('testForm').addEventListener('submit', async function (e) {
e.preventDefault()
const url = document.getElementById('url').value
const resultDiv = document.getElementById('result')
resultDiv.innerHTML = '<div class="result">Testing bypass for: ' + url + '<br>Please wait...</div>'
try {
const response = await fetch('cloudflare_bypass.php', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'test_url=' + encodeURIComponent(url)
})
const text = await response.text()
// Parse the response
const lines = text.split('\n')
const contentLength = lines.find(line => line.includes('Retrieved content length:'))?.split(':')[1]?.trim()
const status = lines.find(line => line.includes('Successfully bypassed') || line.includes('Cloudflare challenge detected') || line.includes('attempting to solve') || line.includes('Failed to retrieve'))
let resultClass = 'result'
let statusText = ''
if (status) {
if (status.includes('Successfully bypassed')) {
resultClass += ' success'
statusText = '✅ ' + status
} else if (status.includes('Cloudflare challenge detected') || status.includes('attempting to solve')) {
resultClass += ' warning'
statusText = '⚠️ ' + status
} else {
resultClass += ' error'
statusText = '❌ ' + status
}
}
// Extract the actual content
const contentStart = text.indexOf('First 500 characters:')
let content = ''
if (contentStart > -1) {
content = text.substring(contentStart + 22).trim()
} else {
// Fallback: show the entire response if no specific content marker found
content = text
}
// Clean up the content (remove extra whitespace)
content = content.replace(/\n\s*\n/g, '\n').trim()
// Create a safer HTML content for iframe
const safeContent = content.replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
resultDiv.innerHTML = `
<div class="${resultClass}">
<strong>${statusText}</strong><br>
${contentLength ? 'Content length: ' + contentLength : ''}<br><br>
<div class="flex-container" style="display: flex; gap: 20px; margin-top: 15px;">
<div style="flex: 1; min-width: 0;">
<strong>Source Code:</strong><br>
<pre style="overflow-x: auto; max-width: 100%;">${content}</pre>
</div>
<div style="flex: 1; min-width: 0;">
<strong>Rendered View:</strong><br>
<iframe srcdoc="${safeContent}"
style="width: 100%; height: 400px; border: 1px solid #dee2e6; border-radius: 4px; background: white; box-sizing: border-box; min-width: 0;">
</iframe>
</div>
</div>
</div>
`
} catch (error) {
resultDiv.innerHTML = '<div class="result error">❌ Error: ' + error.message + '</div>'
}
});
</script>
</body>
</html>
@canerd7u
Copy link

canerd7u commented May 5, 2021

Copy link

ghost commented Sep 30, 2021

is not working...
Tried the script and it didn't get past Cloudflare

@hamidhaghdoost
Copy link

not working :(

@kibodmitry
Copy link

Not working...

@kicktv
Copy link

kicktv commented Oct 30, 2022

Thank you very much,
the script is working for me

@porp
Copy link

porp commented Dec 5, 2022

not working sorry...

@ilkersen3
Copy link

@yasinkuyu güncel bybass için yardımın dokunur mu veya bir fikir

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment