caarleexx commited on
Commit
1fa35ea
·
verified ·
1 Parent(s): 8dc9826

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +201 -188
app.py CHANGED
@@ -4,10 +4,12 @@ import json
4
  import time
5
  import logging
6
  import requests
 
7
  from flask import Flask, request, jsonify, render_template_string
8
  from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError
9
- from playwright_stealth import stealth_sync
10
  import traceback
 
 
11
 
12
  # Configuração de logging
13
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
@@ -15,7 +17,7 @@ logger = logging.getLogger(__name__)
15
 
16
  app = Flask(__name__)
17
 
18
- # Template HTML para interface simples
19
  HTML_TEMPLATE = """
20
  <!DOCTYPE html>
21
  <html>
@@ -24,6 +26,7 @@ HTML_TEMPLATE = """
24
  <meta charset="utf-8">
25
  <meta name="viewport" content="width=device-width, initial-scale=1">
26
  <style>
 
27
  body {
28
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
29
  max-width: 1200px;
@@ -129,6 +132,14 @@ HTML_TEMPLATE = """
129
  margin: 10px 0;
130
  border-radius: 4px;
131
  }
 
 
 
 
 
 
 
 
132
  </style>
133
  </head>
134
  <body>
@@ -136,7 +147,7 @@ HTML_TEMPLATE = """
136
  <h1>🛡️ Bypass AWS WAF - STF Jurisprudência</h1>
137
 
138
  <div class="info-box">
139
- <strong>📌 Sobre:</strong> Teste de bypass do AWS WAF usando Playwright + Stealth para acessar a API de jurisprudência do STF.
140
  <br>
141
  <strong>🔗 API Alvo:</strong> https://jurisprudencia.stf.jus.br/api/search/search
142
  </div>
@@ -203,9 +214,9 @@ HTML_TEMPLATE = """
203
  let resultHtml = '<div class="success">✅ Teste executado com sucesso!</div>';
204
  resultHtml += '<pre>' + JSON.stringify(data.data, null, 2) + '</pre>';
205
 
206
- if (data.token) {
207
  resultHtml += '<div class="info-box"><strong>🔑 Token AWS WAF obtido:</strong><br>' +
208
- '<code style="word-break: break-all;">' + data.token + '</code></div>';
209
  }
210
 
211
  resultDiv.innerHTML = resultHtml;
@@ -213,8 +224,16 @@ HTML_TEMPLATE = """
213
  failCount++;
214
  document.getElementById('failCount').textContent = failCount;
215
 
216
- resultDiv.innerHTML = '<div class="error">❌ Falha no teste: ' + data.error + '</div>' +
217
- '<pre>' + JSON.stringify(data.details, null, 2) + '</pre>';
 
 
 
 
 
 
 
 
218
  }
219
  } catch (error) {
220
  failCount++;
@@ -231,121 +250,117 @@ HTML_TEMPLATE = """
231
  </html>
232
  """
233
 
234
- # Dados da requisição (extraídos do curl)
235
  URL_API = "https://jurisprudencia.stf.jus.br/api/search/search"
236
  HEADERS = {
237
  "Accept": "application/json, text/plain, */*",
238
  "Content-Type": "application/json",
239
- "User-Agent": "Mozilla/5.0 (Linux; Android 10; Pixel 4a Build/QD4A.200805.003; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/129.0.6668.71 Mobile Safari/537.36",
240
- "Referer": "https://jurisprudencia.stf.jus.br/pages/search?base=acordaos&pesquisa_inteiro_teor=false&sinonimo=true&plural=true&radicais=false&buscaExata=true&page=1&pageSize=250&queryString=*&sort=_score&sortBy=desc&isAdvanced=true",
241
  "Accept-Encoding": "gzip, deflate, br",
242
  "Connection": "keep-alive",
243
  "Origin": "https://jurisprudencia.stf.jus.br"
244
  }
245
 
246
- # Payload completo (resumido para não sobrecarregar o código - o payload completo está no histórico)
247
  PAYLOAD = {
248
  "query": {
249
- "function_score": {
250
- "functions": [
251
- {"exp": {"julgamento_data": {"origin": "now", "scale": "47450d", "offset": "1095d", "decay": 0.1}}},
252
- {"filter": {"term": {"orgao_julgador.keyword": "Tribunal Pleno"}}, "weight": 1.15}
253
- ],
254
- "query": {
255
- "bool": {
256
- "filter": [
257
- {"query_string": {
258
- "default_operator": "AND",
259
- "fields": ["ementa_texto.plural^3", "acordao_ata.plural^3"],
260
- "query": "*",
261
- "type": "cross_fields",
262
- "fuzziness": "AUTO:4,7"
263
- }}
264
- ],
265
- "should": []
266
- }
267
- }
268
  }
269
  },
270
- "_source": ["id", "titulo", "ementa_texto", "processo_numero", "julgamento_data"],
271
- "size": 10,
272
  "from": 0,
273
  "sort": [{"_score": "desc"}]
274
  }
275
 
276
- def extract_waf_token_from_cookies(response):
277
- """Extrai o token AWS WAF dos cookies da resposta"""
278
- cookies = response.cookies
279
- for cookie in cookies:
280
- if cookie.get('name') == 'aws-waf-token':
281
- return cookie.get('value')
282
-
283
- # Tentar extrair de headers de resposta
284
- set_cookie = response.headers.get('set-cookie', '')
285
- if 'aws-waf-token=' in set_cookie:
286
- import re
287
- match = re.search(r'aws-waf-token=([^;]+)', set_cookie)
288
- if match:
289
- return match.group(1)
290
-
291
- return None
 
 
 
 
292
 
293
  def test_with_requests():
294
- """Testa acesso direto com requests"""
295
- logger.info("Tentando acesso direto com requests...")
296
 
297
  try:
298
- # Primeiro, tentar acessar a página principal para obter token inicial
299
  session = requests.Session()
 
300
 
301
- # Acessar página de busca primeiro
302
- search_page_url = "https://jurisprudencia.stf.jus.br/pages/search"
 
 
 
303
  headers_page = HEADERS.copy()
304
  headers_page.pop("Content-Type", None)
305
 
306
- page_response = session.get(search_page_url, headers=headers_page, timeout=30)
307
- logger.info(f"Página principal: status {page_response.status_code}")
308
-
309
- # Verificar se recebemos token
310
- token = extract_waf_token_from_cookies(page_response)
311
- if token:
312
- logger.info(f"Token AWS WAF obtido da página: {token[:30]}...")
 
 
 
 
313
 
314
- # Tentar a API
315
  api_response = session.post(
316
  URL_API,
317
  headers=HEADERS,
318
  json=PAYLOAD,
319
- timeout=30
 
320
  )
321
 
322
  logger.info(f"API Response: status {api_response.status_code}")
323
 
324
  if api_response.status_code == 200:
325
- data = api_response.json()
326
- return {
327
- "success": True,
328
- "method": "requests",
329
- "status_code": api_response.status_code,
330
- "token": token,
331
- "data": data
332
- }
333
- elif api_response.status_code in [403, 202]:
334
- # AWS WAF detectado
335
- return {
336
- "success": False,
337
- "method": "requests",
338
- "status_code": api_response.status_code,
339
- "error": "AWS WAF detectado - necessário bypass com navegador",
340
- "response_text": api_response.text[:500]
341
- }
342
  else:
343
  return {
344
  "success": False,
345
  "method": "requests",
346
  "status_code": api_response.status_code,
347
- "error": f"Status inesperado: {api_response.status_code}",
348
- "response_text": api_response.text[:500]
349
  }
350
 
351
  except Exception as e:
@@ -357,99 +372,76 @@ def test_with_requests():
357
  "traceback": traceback.format_exc()
358
  }
359
 
360
- def test_with_playwright():
361
- """Testa acesso usando Playwright com stealth"""
362
- logger.info("Tentando acesso com Playwright + stealth...")
363
-
364
- token = None
365
- playwright = None
366
 
367
  try:
368
  with sync_playwright() as p:
369
- # Configurar navegador com argumentos anti-detecção
370
  browser = p.chromium.launch(
371
  headless=True,
372
- args=[
373
- '--disable-blink-features=AutomationControlled',
374
- '--disable-dev-shm-usage',
375
- '--no-sandbox',
376
- '--disable-setuid-sandbox',
377
- '--disable-web-security',
378
- '--disable-features=IsolateOrigins,site-per-process',
379
- '--start-maximized'
380
- ]
381
  )
382
 
383
  context = browser.new_context(
384
  viewport={'width': 1920, 'height': 1080},
385
- user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
386
- locale='pt-BR',
387
- timezone_id='America/Sao_Paulo',
388
- permissions=['geolocation']
389
  )
390
 
391
  page = context.new_page()
392
 
393
- # Aplicar stealth
394
- stealth_sync(page)
395
-
396
- # Navegar para página principal
397
- logger.info("Navegando para página de busca...")
398
  response = page.goto(
399
  "https://jurisprudencia.stf.jus.br/pages/search",
400
- wait_until='networkidle',
401
  timeout=30000
402
  )
403
 
404
  if not response:
405
- raise Exception("Sem resposta da página")
406
 
407
  logger.info(f"Página carregada: status {response.status}")
408
 
409
- # Aguardar um pouco para execução de JS
410
- page.wait_for_timeout(5000)
411
 
412
- # Coletar cookies
413
  cookies = context.cookies()
 
414
  for cookie in cookies:
415
  if cookie.get('name') == 'aws-waf-token':
416
  token = cookie.get('value')
417
- logger.info(f"Token AWS WAF encontrado: {token[:30]}...")
418
 
419
- if not token:
420
- # Tentar extrair do localStorage
421
- token = page.evaluate("""
422
- () => {
423
- for(let i=0; i<localStorage.length; i++) {
424
- let key = localStorage.key(i);
425
- if(key.includes('waf') || key.includes('token')) {
426
- return localStorage.getItem(key);
427
- }
428
- }
429
- return null;
430
- }
431
- """)
432
- if token:
433
- logger.info(f"Token encontrado no localStorage: {token[:30]}...")
434
-
435
- # Fazer requisição à API via JavaScript
436
- logger.info("Executando requisição à API via JavaScript...")
437
  api_result = page.evaluate("""
438
- async (payload, headers) => {
439
  try {
440
  const response = await fetch('https://jurisprudencia.stf.jus.br/api/search/search', {
441
  method: 'POST',
442
- headers: headers,
443
- body: JSON.stringify(payload)
 
 
 
 
 
 
444
  });
445
 
446
- const data = await response.json();
447
- return {
448
- success: response.ok,
449
- status: response.status,
450
- data: data,
451
- headers: Object.fromEntries(response.headers)
452
- };
 
 
 
 
 
453
  } catch (error) {
454
  return {
455
  success: false,
@@ -457,7 +449,7 @@ def test_with_playwright():
457
  };
458
  }
459
  }
460
- """, PAYLOAD, HEADERS)
461
 
462
  browser.close()
463
 
@@ -465,7 +457,6 @@ def test_with_playwright():
465
  return {
466
  "success": True,
467
  "method": "playwright",
468
- "status_code": api_result.get('status'),
469
  "token": token,
470
  "data": api_result.get('data')
471
  }
@@ -477,15 +468,6 @@ def test_with_playwright():
477
  "token": token
478
  }
479
 
480
- except PlaywrightTimeoutError:
481
- error_msg = "Timeout ao carregar página"
482
- logger.error(error_msg)
483
- return {
484
- "success": False,
485
- "method": "playwright",
486
- "error": error_msg,
487
- "traceback": traceback.format_exc()
488
- }
489
  except Exception as e:
490
  logger.error(f"Erro no Playwright: {str(e)}")
491
  return {
@@ -510,34 +492,28 @@ def test_bypass():
510
  "attempts": []
511
  }
512
 
513
- # Tentar primeiro com requests
514
  requests_result = test_with_requests()
515
  result["attempts"].append(requests_result)
516
 
517
  # Se requests falhou, tentar com playwright
518
  if not requests_result.get("success"):
519
  logger.info("Requests falhou, tentando Playwright...")
520
- time.sleep(2) # Pequena pausa entre tentativas
521
 
522
- playwright_result = test_with_playwright()
523
  result["attempts"].append(playwright_result)
524
 
525
  if playwright_result.get("success"):
526
  result["success"] = True
527
  result["method"] = "playwright"
528
- result["token"] = playwright_result.get("token")
529
  result["data"] = playwright_result.get("data")
530
- else:
531
- result["success"] = True
532
- result["method"] = "requests"
533
- result["token"] = requests_result.get("token")
534
- result["data"] = requests_result.get("data")
535
 
536
- # Preparar resposta
537
  response_data = {
538
  "success": result["success"],
539
  "timestamp": time.time(),
540
- "method": result.get("method"),
541
  "attempts": [
542
  {
543
  "method": a.get("method"),
@@ -549,50 +525,87 @@ def test_bypass():
549
  ]
550
  }
551
 
552
- if result.get("success") and result.get("data"):
553
- response_data["data"] = result["data"]
554
- response_data["token_preview"] = result.get("token", "")[:50] + "..." if result.get("token") else None
555
-
556
- if not result["success"]:
557
  response_data["error"] = "Todas as tentativas falharam"
558
- response_data["details"] = result["attempts"]
559
- return jsonify(response_data), 500
 
 
 
 
 
 
560
 
561
  return jsonify(response_data)
562
 
563
  @app.route('/api/health', methods=['GET'])
564
  def health():
565
  """Endpoint de health check"""
 
566
  return jsonify({
567
  "status": "healthy",
568
  "timestamp": time.time(),
569
- "playwright_installed": True,
570
  "python_version": sys.version
571
  })
572
 
573
- @app.route('/api/token-status', methods=['GET'])
574
- def token_status():
575
- """Verifica status do token atual"""
576
- # Este endpoint poderia verificar se o token ainda é válido
577
- return jsonify({
578
- "message": "Para obter um token, execute /api/test-bypass primeiro"
579
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
580
 
581
  if __name__ == '__main__':
582
- # Verificar dependências na inicialização
 
 
 
 
 
 
 
 
 
 
 
583
  logger.info("Iniciando aplicação de bypass AWS WAF")
584
  logger.info(f"Python version: {sys.version}")
585
 
586
- # Testar playwright na inicialização
587
- try:
588
- with sync_playwright() as p:
589
- browser = p.chromium.launch(headless=True)
590
- logger.info("Playwright iniciado com sucesso")
591
- browser.close()
592
- except Exception as e:
593
- logger.error(f"Erro ao iniciar Playwright: {str(e)}")
594
- logger.error("Verifique se as dependências do sistema estão instaladas")
595
 
596
- # Iniciar servidor Flask
597
  port = int(os.environ.get('PORT', 7860))
598
  app.run(host='0.0.0.0', port=port, debug=False)
 
4
  import time
5
  import logging
6
  import requests
7
+ import subprocess
8
  from flask import Flask, request, jsonify, render_template_string
9
  from playwright.sync_api import sync_playwright, TimeoutError as PlaywrightTimeoutError
 
10
  import traceback
11
+ import ssl
12
+ import certifi
13
 
14
  # Configuração de logging
15
  logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
 
17
 
18
  app = Flask(__name__)
19
 
20
+ # Template HTML (mesmo do código anterior)
21
  HTML_TEMPLATE = """
22
  <!DOCTYPE html>
23
  <html>
 
26
  <meta charset="utf-8">
27
  <meta name="viewport" content="width=device-width, initial-scale=1">
28
  <style>
29
+ /* Mesmo CSS do código anterior */
30
  body {
31
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
32
  max-width: 1200px;
 
132
  margin: 10px 0;
133
  border-radius: 4px;
134
  }
135
+ .warning {
136
+ color: #ff9800;
137
+ background: #fff3e0;
138
+ border-left: 4px solid #ff9800;
139
+ padding: 15px;
140
+ margin: 10px 0;
141
+ border-radius: 4px;
142
+ }
143
  </style>
144
  </head>
145
  <body>
 
147
  <h1>🛡️ Bypass AWS WAF - STF Jurisprudência</h1>
148
 
149
  <div class="info-box">
150
+ <strong>📌 Sobre:</strong> Teste de bypass do AWS WAF usando Playwright para acessar a API de jurisprudência do STF.
151
  <br>
152
  <strong>🔗 API Alvo:</strong> https://jurisprudencia.stf.jus.br/api/search/search
153
  </div>
 
214
  let resultHtml = '<div class="success">✅ Teste executado com sucesso!</div>';
215
  resultHtml += '<pre>' + JSON.stringify(data.data, null, 2) + '</pre>';
216
 
217
+ if (data.token_preview) {
218
  resultHtml += '<div class="info-box"><strong>🔑 Token AWS WAF obtido:</strong><br>' +
219
+ '<code style="word-break: break-all;">' + data.token_preview + '</code></div>';
220
  }
221
 
222
  resultDiv.innerHTML = resultHtml;
 
224
  failCount++;
225
  document.getElementById('failCount').textContent = failCount;
226
 
227
+ let errorHtml = '<div class="error">❌ Falha no teste</div>';
228
+
229
+ if (data.attempts) {
230
+ data.attempts.forEach(attempt => {
231
+ errorHtml += `<div class="warning"><strong>Tentativa (${attempt.method}):</strong> ${attempt.error || 'Sem erro detalhado'}</div>`;
232
+ });
233
+ }
234
+
235
+ errorHtml += '<pre>' + JSON.stringify(data.details || data, null, 2) + '</pre>';
236
+ resultDiv.innerHTML = errorHtml;
237
  }
238
  } catch (error) {
239
  failCount++;
 
250
  </html>
251
  """
252
 
253
+ # Dados da requisição
254
  URL_API = "https://jurisprudencia.stf.jus.br/api/search/search"
255
  HEADERS = {
256
  "Accept": "application/json, text/plain, */*",
257
  "Content-Type": "application/json",
258
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
259
+ "Referer": "https://jurisprudencia.stf.jus.br/pages/search",
260
  "Accept-Encoding": "gzip, deflate, br",
261
  "Connection": "keep-alive",
262
  "Origin": "https://jurisprudencia.stf.jus.br"
263
  }
264
 
265
+ # Payload simplificado para teste
266
  PAYLOAD = {
267
  "query": {
268
+ "bool": {
269
+ "filter": [
270
+ {"term": {"base": "acordaos"}}
271
+ ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  }
273
  },
274
+ "_source": ["id", "titulo", "ementa_texto", "processo_numero"],
275
+ "size": 5,
276
  "from": 0,
277
  "sort": [{"_score": "desc"}]
278
  }
279
 
280
+ def verify_playwright_dependencies():
281
+ """Verifica e tenta instalar dependências do Playwright"""
282
+ try:
283
+ # Tentar importar para ver se já está funcionando
284
+ with sync_playwright() as p:
285
+ p.chromium.launch(headless=True).close()
286
+ return True
287
+ except Exception as e:
288
+ logger.warning(f"Playwright não está pronto: {e}")
289
+
290
+ # Tentar instalar dependências
291
+ try:
292
+ logger.info("Tentando instalar dependências do Playwright...")
293
+ subprocess.run(["python", "-m", "playwright", "install", "chromium"], check=True)
294
+ subprocess.run(["python", "-m", "playwright", "install-deps"], check=True)
295
+ logger.info("Dependências instaladas com sucesso")
296
+ return True
297
+ except Exception as install_error:
298
+ logger.error(f"Falha ao instalar dependências: {install_error}")
299
+ return False
300
 
301
  def test_with_requests():
302
+ """Testa acesso direto com requests (ignorando SSL)"""
303
+ logger.info("Tentando acesso direto com requests (SSL ignorado)...")
304
 
305
  try:
306
+ # Configurar sessão ignorando verificação SSL
307
  session = requests.Session()
308
+ session.verify = False # Ignorar SSL
309
 
310
+ # Suprimir warnings de SSL
311
+ import urllib3
312
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
313
+
314
+ # Headers sem Content-Type para página
315
  headers_page = HEADERS.copy()
316
  headers_page.pop("Content-Type", None)
317
 
318
+ # Tentar página principal
319
+ try:
320
+ page_response = session.get(
321
+ "https://jurisprudencia.stf.jus.br/pages/search",
322
+ headers=headers_page,
323
+ timeout=30,
324
+ verify=False
325
+ )
326
+ logger.info(f"Página principal: status {page_response.status_code}")
327
+ except Exception as page_error:
328
+ logger.warning(f"Erro ao acessar página principal: {page_error}")
329
 
330
+ # Tentar API diretamente
331
  api_response = session.post(
332
  URL_API,
333
  headers=HEADERS,
334
  json=PAYLOAD,
335
+ timeout=30,
336
+ verify=False
337
  )
338
 
339
  logger.info(f"API Response: status {api_response.status_code}")
340
 
341
  if api_response.status_code == 200:
342
+ try:
343
+ data = api_response.json()
344
+ return {
345
+ "success": True,
346
+ "method": "requests",
347
+ "status_code": api_response.status_code,
348
+ "data": data
349
+ }
350
+ except:
351
+ return {
352
+ "success": True,
353
+ "method": "requests",
354
+ "status_code": api_response.status_code,
355
+ "data": {"text": api_response.text[:500]}
356
+ }
 
 
357
  else:
358
  return {
359
  "success": False,
360
  "method": "requests",
361
  "status_code": api_response.status_code,
362
+ "error": f"Status {api_response.status_code}",
363
+ "response_text": api_response.text[:500] if api_response.text else ""
364
  }
365
 
366
  except Exception as e:
 
372
  "traceback": traceback.format_exc()
373
  }
374
 
375
+ def test_with_playwright_simple():
376
+ """Versão simplificada do Playwright para teste"""
377
+ logger.info("Tentando acesso com Playwright...")
 
 
 
378
 
379
  try:
380
  with sync_playwright() as p:
381
+ # Configuração mínima
382
  browser = p.chromium.launch(
383
  headless=True,
384
+ args=['--no-sandbox']
 
 
 
 
 
 
 
 
385
  )
386
 
387
  context = browser.new_context(
388
  viewport={'width': 1920, 'height': 1080},
389
+ user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
 
 
 
390
  )
391
 
392
  page = context.new_page()
393
 
394
+ # Navegar
 
 
 
 
395
  response = page.goto(
396
  "https://jurisprudencia.stf.jus.br/pages/search",
397
+ wait_until='domcontentloaded',
398
  timeout=30000
399
  )
400
 
401
  if not response:
402
+ raise Exception("Sem resposta")
403
 
404
  logger.info(f"Página carregada: status {response.status}")
405
 
406
+ # Aguardar um pouco
407
+ page.wait_for_timeout(3000)
408
 
409
+ # Tentar extrair token dos cookies
410
  cookies = context.cookies()
411
+ token = None
412
  for cookie in cookies:
413
  if cookie.get('name') == 'aws-waf-token':
414
  token = cookie.get('value')
415
+ break
416
 
417
+ # Fazer requisição à API via página
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
418
  api_result = page.evaluate("""
419
+ async () => {
420
  try {
421
  const response = await fetch('https://jurisprudencia.stf.jus.br/api/search/search', {
422
  method: 'POST',
423
+ headers: {
424
+ 'Content-Type': 'application/json',
425
+ 'Accept': 'application/json'
426
+ },
427
+ body: JSON.stringify({
428
+ query: {bool: {filter: [{term: {base: "acordaos"}}]}},
429
+ size: 5
430
+ })
431
  });
432
 
433
+ if (response.ok) {
434
+ return {
435
+ success: true,
436
+ data: await response.json()
437
+ };
438
+ } else {
439
+ return {
440
+ success: false,
441
+ status: response.status,
442
+ statusText: response.statusText
443
+ };
444
+ }
445
  } catch (error) {
446
  return {
447
  success: false,
 
449
  };
450
  }
451
  }
452
+ """)
453
 
454
  browser.close()
455
 
 
457
  return {
458
  "success": True,
459
  "method": "playwright",
 
460
  "token": token,
461
  "data": api_result.get('data')
462
  }
 
468
  "token": token
469
  }
470
 
 
 
 
 
 
 
 
 
 
471
  except Exception as e:
472
  logger.error(f"Erro no Playwright: {str(e)}")
473
  return {
 
492
  "attempts": []
493
  }
494
 
495
+ # Tentar com requests (ignorando SSL)
496
  requests_result = test_with_requests()
497
  result["attempts"].append(requests_result)
498
 
499
  # Se requests falhou, tentar com playwright
500
  if not requests_result.get("success"):
501
  logger.info("Requests falhou, tentando Playwright...")
502
+ time.sleep(1)
503
 
504
+ playwright_result = test_with_playwright_simple()
505
  result["attempts"].append(playwright_result)
506
 
507
  if playwright_result.get("success"):
508
  result["success"] = True
509
  result["method"] = "playwright"
510
+ result["token_preview"] = str(playwright_result.get("token", ""))[:50] + "..." if playwright_result.get("token") else None
511
  result["data"] = playwright_result.get("data")
 
 
 
 
 
512
 
513
+ # Preparar resposta simplificada
514
  response_data = {
515
  "success": result["success"],
516
  "timestamp": time.time(),
 
517
  "attempts": [
518
  {
519
  "method": a.get("method"),
 
525
  ]
526
  }
527
 
528
+ if result.get("success"):
529
+ response_data["data"] = result.get("data")
530
+ response_data["token_preview"] = result.get("token_preview")
531
+ else:
 
532
  response_data["error"] = "Todas as tentativas falharam"
533
+ response_data["details"] = [
534
+ {
535
+ "method": a["method"],
536
+ "error": a.get("error", "Erro desconhecido"),
537
+ "traceback": a.get("traceback", "") if a.get("traceback") else None
538
+ }
539
+ for a in result["attempts"]
540
+ ]
541
 
542
  return jsonify(response_data)
543
 
544
  @app.route('/api/health', methods=['GET'])
545
  def health():
546
  """Endpoint de health check"""
547
+ playwright_status = verify_playwright_dependencies()
548
  return jsonify({
549
  "status": "healthy",
550
  "timestamp": time.time(),
551
+ "playwright_ready": playwright_status,
552
  "python_version": sys.version
553
  })
554
 
555
+ @app.route('/api/install-deps', methods=['POST'])
556
+ def install_deps():
557
+ """Endpoint para instalar dependências manualmente"""
558
+ try:
559
+ result = subprocess.run(
560
+ ["python", "-m", "playwright", "install", "chromium"],
561
+ capture_output=True,
562
+ text=True,
563
+ timeout=60
564
+ )
565
+
566
+ deps_result = subprocess.run(
567
+ ["python", "-m", "playwright", "install-deps"],
568
+ capture_output=True,
569
+ text=True,
570
+ timeout=120
571
+ )
572
+
573
+ return jsonify({
574
+ "success": True,
575
+ "install_output": result.stdout,
576
+ "deps_output": deps_result.stdout,
577
+ "install_error": result.stderr if result.stderr else None,
578
+ "deps_error": deps_result.stderr if deps_result.stderr else None
579
+ })
580
+ except Exception as e:
581
+ return jsonify({
582
+ "success": False,
583
+ "error": str(e)
584
+ }), 500
585
 
586
  if __name__ == '__main__':
587
+ # Configurar SSL
588
+ try:
589
+ import certifi
590
+ os.environ['SSL_CERT_FILE'] = certifi.where()
591
+ os.environ['REQUESTS_CA_BUNDLE'] = certifi.where()
592
+ except:
593
+ pass
594
+
595
+ # Suprimir warnings de SSL
596
+ import urllib3
597
+ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
598
+
599
  logger.info("Iniciando aplicação de bypass AWS WAF")
600
  logger.info(f"Python version: {sys.version}")
601
 
602
+ # Verificar Playwright
603
+ playwright_ready = verify_playwright_dependencies()
604
+ if playwright_ready:
605
+ logger.info("✅ Playwright pronto para uso")
606
+ else:
607
+ logger.warning("⚠️ Playwright pode não estar totalmente configurado")
 
 
 
608
 
609
+ # Iniciar servidor
610
  port = int(os.environ.get('PORT', 7860))
611
  app.run(host='0.0.0.0', port=port, debug=False)