Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions user_scanner/user_scan/social/facebook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import re

import httpx
from user_scanner.core.result import Result


def _check(user: str) -> Result:
show_url = "https://facebook.com"

if not (1 <= len(user) <= 50):
return Result.error("Length must be 1-50 characters")

if not re.match(r"^[a-zA-Z0-9.]+$", user):
return Result.error("Only letters, numbers and periods allowed")

if user.isdigit():
return Result.error("Username cannot be numbers only")

if user.startswith(".") or user.endswith("."):
return Result.error("Username cannot start or end with a period")

with httpx.Client(http2=True, follow_redirects=False, timeout=10.0) as client:
try:
headers1 = {
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
'Accept-Encoding': "identity",
'sec-ch-ua': '"Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
}
client.get("https://m.facebook.com/login/", headers=headers1)

headers2 = {
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
'Accept': "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
'Accept-Encoding': "identity",
'upgrade-insecure-requests': "1",
'sec-fetch-site': "cross-site",
'sec-fetch-mode': "navigate",
'sec-fetch-user': "?1",
'sec-fetch-dest': "document",
'sec-ch-ua': '"Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
'sec-ch-ua-mobile': "?0",
'sec-ch-ua-platform': '"Linux"',
'referer': "https://www.google.com/",
'accept-language': "en-US,en;q=0.9",
'priority': "u=0, i"
}
res = client.get("https://www.facebook.com", params={'_rdr': ""}, headers=headers2)
html = res.text

lsd_match = re.search(r'\["LSD",\[\],\{"token":"([^"]+)"\}', html) or \
re.search(r'name="lsd"\s+value="([^"]+)"', html) or \
re.search(r'"lsd":"([^"]+)"', html)

j_match = re.search(r'jazoest=(\d+)', html) or \
re.search(r'name="jazoest"\s+value="(\d+)"', html)

lsd = lsd_match.group(1) if lsd_match else None
jazoest = j_match.group(1) if j_match else None

if not lsd or not jazoest:
return Result.error(f"Token extraction failed (LSD: {bool(lsd)}, Jazoest: {bool(jazoest)})")

headers3 = {
'User-Agent': "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36",
'Accept-Encoding': "identity",
'sec-ch-ua-full-version-list': '"Google Chrome";v="143.0.7499.192", "Chromium";v="143.0.7499.192", "Not A(Brand";v="24.0.0.0"',
'sec-ch-ua-platform': '"Linux"',
'sec-ch-ua': '"Google Chrome";v="143", "Chromium";v="143", "Not A(Brand";v="24"',
'sec-ch-ua-model': '""',
'sec-ch-ua-mobile': "?0",
'x-asbd-id': "359341",
'x-fb-lsd': lsd,
'sec-ch-prefers-color-scheme': "dark",
'sec-ch-ua-platform-version': '""',
'origin': "https://www.facebook.com",
'sec-fetch-site': "same-origin",
'sec-fetch-mode': "cors",
'sec-fetch-dest': "empty",
'referer': "https://www.facebook.com/login/identify/?ctx=recover&ars=facebook_login&from_login_screen=0",
'accept-language': "en-US,en;q=0.9",
'priority': "u=1, i"
}

payload = {
'jazoest': jazoest,
'lsd': lsd,
'email': user,
'did_submit': "1",
'__user': "0",
'__a': "1",
'__req': "7"
}

response = client.post(
"https://www.facebook.com/ajax/login/help/identify.php",
params={'ctx': "recover"},
data=payload,
headers=headers3
)
body = response.text

if "These accounts matched your search" in body or "redirectPageTo" in body:
return Result.taken(url=show_url)
elif "No search results" in body or "Your search did not return any results." in body:
return Result.available(url=show_url)
else:
return Result.error("Unexpected response, report it via GitHub issues")

except httpx.TimeoutException:
return Result.error("Connection timed out")
except Exception as e:
return Result.error(f"Unexpected exception: {e}")


def validate_facebook(user: str) -> Result:
return _check(user)