CounterFeint / data /landing_pages.py
QuantumTransformer's picture
Upload folder using huggingface_hub
26bf1c9 verified
Raw
History Blame Contribute Delete
9.78 kB
"""
Simulated landing page investigation data.
When the agent investigates 'landing_page' for an ad, this module
generates the findings text based on the ad's ground truth label.
"""
from __future__ import annotations
import random
from dataclasses import dataclass
from typing import List
@dataclass
class LandingPageData:
domain: str
domain_age_days: int
ssl_valid: bool
registrar: str
content_summary: str
redirect_chain: List[str]
similarity_to_known_scams: float # 0.0-1.0
key_claims: List[str]
suspicious_elements: List[str]
def to_investigation_text(self) -> str:
ssl_status = "Valid SSL certificate" if self.ssl_valid else "NO SSL / expired certificate"
redirects = " -> ".join(self.redirect_chain) if self.redirect_chain else "No redirects (direct)"
suspicious = "\n".join(f" - {s}" for s in self.suspicious_elements) if self.suspicious_elements else " None detected"
claims = "\n".join(f" - {c}" for c in self.key_claims) if self.key_claims else " None"
lines = [
f"Domain: {self.domain}",
f"Domain age: {self.domain_age_days} days",
f"SSL: {ssl_status}",
f"Registrar: {self.registrar}",
f"WHOIS privacy: {'Enabled' if 'privacy' in self.registrar.lower() or 'proxy' in self.registrar.lower() else 'Disabled (registrant info public)'}",
f"Redirect chain: {redirects}",
f"Similarity to known scam templates: {self.similarity_to_known_scams:.0%}",
f"Key claims on page:\n{claims}",
f"Suspicious elements:\n{suspicious}",
f"Content summary: {self.content_summary}",
]
return "\n".join(lines)
_LEGIT_REGISTRARS = ["GoDaddy", "Namecheap", "Google Domains", "Cloudflare Registrar", "AWS Route 53"]
_SUSPICIOUS_REGISTRARS = ["NameSilo", "Epik", "Njalla (privacy)", "Tucows (privacy proxy)", "Openprovider"]
_LEGIT_DOMAINS_SUFFIXES = [".com", ".co", ".org", ".io", ".net"]
_SCAM_DOMAINS_SUFFIXES = [".shop", ".store", ".xyz", ".click", ".top", ".buzz", ".site"]
def generate_landing_page(
rng: random.Random,
ad_id: str,
is_fraud: bool,
fraud_type: str = "",
*,
domain_override: str | None = None,
registrar_override: str | None = None,
) -> LandingPageData:
"""Generate simulated landing page investigation data."""
base_word = rng.choice(["deal", "offer", "shop", "store", "buy", "get", "best", "top", "pro", "elite"])
if is_fraud:
suffix = rng.choice(_SCAM_DOMAINS_SUFFIXES)
domain = domain_override or f"{base_word}{rng.randint(10, 9999)}{suffix}"
domain_age = rng.randint(1, 60)
ssl_valid = rng.random() < 0.4
registrar = registrar_override or rng.choice(_SUSPICIOUS_REGISTRARS)
similarity = round(rng.uniform(0.5, 0.95), 2)
redirect_count = rng.randint(1, 4)
redirect_chain = [domain]
for _ in range(redirect_count):
redirect_chain.append(f"redirect{rng.randint(1, 999)}{rng.choice(['.click', '.top', '.xyz'])}")
redirect_chain.append(f"final-{rng.randint(1, 999)}{rng.choice(['.site', '.store'])}")
suspicious = _get_fraud_suspicious_elements(rng, fraud_type)
claims = _get_fraud_claims(rng, fraud_type)
content = _get_fraud_content_summary(rng, fraud_type)
else:
suffix = rng.choice(_LEGIT_DOMAINS_SUFFIXES)
brand = rng.choice(["homenest", "stylehaven", "taskflow", "fitlife", "sparkle", "codeacademy", "nutri"])
domain = domain_override or f"{brand}{suffix}"
domain_age = rng.randint(365, 5000)
ssl_valid = True
registrar = registrar_override or rng.choice(_LEGIT_REGISTRARS)
similarity = round(rng.uniform(0.0, 0.15), 2)
redirect_chain = []
suspicious = []
claims = _get_legit_claims(rng)
content = _get_legit_content_summary(rng)
return LandingPageData(
domain=domain,
domain_age_days=domain_age,
ssl_valid=ssl_valid,
registrar=registrar,
content_summary=content,
redirect_chain=redirect_chain,
similarity_to_known_scams=similarity,
key_claims=claims,
suspicious_elements=suspicious,
)
def _get_fraud_suspicious_elements(rng: random.Random, fraud_type: str) -> List[str]:
common = [
"No physical address listed",
"No contact phone number",
"Privacy policy copied from template",
"Terms of service link returns 404",
]
type_specific = {
"fake_giveaway": ["Countdown timer with fake urgency", "Requests personal info before any value provided"],
"counterfeit": ["Product images appear stolen from official brand site", "Price comparison shows 90%+ discount vs retail"],
"miracle_cure": ["FDA disclaimer buried in footer", "Before/after photos appear digitally altered"],
"advance_fee_scam": ["Wire transfer requested upfront", "No company registration found"],
"fake_crypto": ["Smart contract not verified on-chain", "Team photos are stock images"],
"fake_endorsement": ["Celebrity quote not found in any verified source", "Affiliate tracking parameters in URL"],
"brand_impersonation": ["Domain mimics well-known brand with character substitution", "Logo appears edited from official assets"],
"gray_area": ["Citations reference unpublished or retracted studies", "Testimonials lack verifiable details"],
"coordinated_network": ["Identical page template used across multiple domains", "Contact form submits to third-party aggregator"],
}
elements = list(common)
elements.extend(type_specific.get(fraud_type, []))
rng.shuffle(elements)
return elements[: rng.randint(2, min(5, len(elements)))]
def _get_fraud_claims(rng: random.Random, fraud_type: str) -> List[str]:
by_type = {
"fake_giveaway": ["100% free, no purchase necessary", "Guaranteed winner", "Act now — expires in 2 hours"],
"counterfeit": ["Authentic products", "Direct from manufacturer", "90% below retail price"],
"miracle_cure": ["Clinically proven results", "Works in 7 days or less", "Endorsed by doctors"],
"advance_fee_scam": ["Guaranteed returns", "Low processing fee required", "Confidential opportunity"],
"fake_crypto": ["12-15% monthly returns guaranteed", "Audited by top security firms", "Risk-free investment"],
"fake_endorsement": ["As seen on TV", "Celebrity recommended", "Limited exclusive offer"],
"brand_impersonation": ["Official authorized retailer", "Factory direct pricing", "Same quality, lower price"],
"gray_area": ["Clinically studied ingredients", "Doctor recommended", "30-day money-back guarantee"],
"coordinated_network": ["Limited stock available", "Thousands of 5-star reviews", "Fast free shipping"],
}
return by_type.get(fraud_type, ["Special limited offer", "Act now"])
def _get_fraud_content_summary(rng: random.Random, fraud_type: str) -> str:
summaries = {
"fake_giveaway": "Landing page features a large countdown timer and a form requesting name, email, phone, and address. No clear sponsor or rules disclosure.",
"counterfeit": "Product catalog showing luxury branded items at extreme discounts. Stock photos. Payment accepted via wire transfer and crypto only.",
"miracle_cure": "Long-form sales page with testimonials, before/after images, and pseudoscientific explanations. Multiple urgency CTAs.",
"advance_fee_scam": "Simple page with a letter-style appeal requesting wire transfer. Grammar errors. No company details.",
"fake_crypto": "Professional-looking platform with dashboard screenshots. Whitepaper link leads to a generic PDF. Team bios use stock photos.",
"fake_endorsement": "News article-style page with celebrity photos. Comments section appears pre-populated with positive feedback.",
"brand_impersonation": "Near-replica of the official brand website. URL uses character substitution. Cart and checkout flow functional but data destination unclear.",
"gray_area": "Well-designed supplement product page. Ingredient list present but efficacy claims exceed scientific evidence. Has a real return policy.",
"coordinated_network": "Standard e-commerce template. Products appear legitimate but company details are vague. Identical template to other flagged sites.",
}
return summaries.get(fraud_type, "Generic landing page with minimal content and heavy use of urgency language.")
def _get_legit_claims(rng: random.Random) -> List[str]:
options = [
"Free shipping on orders over $50",
"14-day free trial",
"Money-back guarantee",
"Established since 2010",
"4.5-star average customer rating",
"Licensed and insured",
"BBB accredited",
"Certified organic ingredients",
]
rng.shuffle(options)
return options[: rng.randint(2, 4)]
def _get_legit_content_summary(rng: random.Random) -> str:
options = [
"Well-structured business website with clear product catalog, about page, contact information, and shipping policy.",
"Professional service website with team bios, case studies, client testimonials, and clear pricing.",
"E-commerce store with detailed product descriptions, customer reviews, FAQ section, and accessible support.",
"SaaS landing page with feature breakdown, pricing tiers, integration docs, and live demo option.",
]
return rng.choice(options)