Camoufox JS

repository·master·Indexed 42 days ago

https://github.com/apify/camoufox-js

An experimental JavaScript port of Camoufox for Python, providing a client to control the Camoufox browser via the Playwright API. It enables browser automation with advanced fingerprinting, camouflage capabilities, and support for custom addons and geolocation settings. Version 0.12.0.

Tokens
7K
Snippets
21
Records
25
Agent score
49%

What's inside Camoufox

  1. Download the Camoufox browser

    master

    After installing the package, you must download the Camoufox browser binaries using the fetch command. By default, these are stored in the per-user cache directory ($XDG_CACHE_HOME/camoufox or ~/.cache/camoufox on Linux).

    To install the browser to a custom location (recommended for containers or CI environments), set the CAMOUFOX_INSTALL_DIR environment variable.

    # Default installation
    npx camoufox-js fetch
    
    # Custom installation location
    CAMOUFOX_INSTALL_DIR=/opt/camoufox npx camoufox-js fetch
  2. Best practices for configuring Camoufox parameters

    master

    To avoid detection by Web Application Firewalls (WAFs) and maintain a consistent browser fingerprint, follow these configuration guidelines:

    Fingerprint & Identity

    • Navigator & Viewport: Do not manually set navigator properties or screen/window dimensions. Camoufox automatically generates these based on the provided os and screen constraints.
    • User-Agent: Do not manually set the header.User-Agent. Camoufox generates a compatible User-Agent for you.
    • Fingerprints: Avoid passing custom_fingerprint. Camoufox uses BrowserForge to automatically generate fingerprints based on os and screen constraints.
    • Firefox Version: Avoid spoofing the ff_version. If version rotation is required, rotate between different versions of Camoufox instead.

    Localization & Geolocation

    • Locale: Use the locale parameter instead of manual configuration.
    • Geolocation: Instead of manual geolocation, use the geoip parameter. This ensures your geolocation matches your IP address, preventing detection.
      • Pass geoip=True to let Camoufox populate data automatically.
      • Pass a specific IP (e.g., geoip='123.45.67.89') to target a specific location.
    • Region: If no locale region is provided, Camoufox generates one. Ensure your IP matches the generated locale region to avoid suspicion.

    Network & Content

    • Proxies: When using a proxy, it is highly recommended to pass geoip=True.
    • Images: Do not block image requests, as this has been reported to cause detection issues on major WAFs.
    • WebGL: Do not disable WebGL; many WAFs check for its presence.

    Security & System Settings

    • Fonts: Do not use custom_fonts_only (disabling OS-specific fonts) while spoofing an OS. This creates a mismatch between the claimed OS and available system fonts that WAFs can detect.
    • COOP: Do not disable Cross-Origin-Opener-Policy (COOP) handling, as sophisticated WAFs may detect this.
  3. Manage locales and geolocation for Camoufox

    master

    The locale.ts module provides utilities for handling language, region, and script settings, as well as deriving geolocation data from IP addresses. This is useful for configuring browser fingerprinting to match a specific target audience or location.

    Key Concepts

    • Locale: Represents a combination of language, region, and optionally a script (e.g., en-US).
    • Geolocation: Represents physical location data (longitude, latitude, timezone) paired with a Locale.
    • Statistical Selection: When providing only a language or a region, the library uses statistical data (from Unicode territory information) to pick a likely matching pair (e.g., providing en might result in en-US or en-GB based on population weights).

    Usage

    You can normalize locale strings, handle single or multiple locales, and resolve geolocation from an IP address.

  4. Launch Camoufox with custom Playwright options

    master

    If you need to use additional Playwright launch options or override Camoufox defaults, use the launchOptions function. This function returns an object that can be spread into a standard firefox.launch() call from playwright-core.

    import { launchOptions } from 'camoufox-js';
    import { firefox } from 'playwright-core';
    
    // Ensure you have run `npx camoufox-js fetch` first
    const browser = await firefox.launch({
        ...await launchOptions({
            // Camoufox options
        }),
        // other Playwright options, overriding the Camoufox options
    });
                
    const page = await browser.newPage(); // `page` is a Playwright Page instance
  5. Launch Camoufox using the Camoufox helper

    master

    The simplest way to launch a Playwright-controlled Camoufox instance is by calling the Camoufox function. This returns a browser instance where the page object is a standard Playwright Page instance.

    import { Camoufox } from 'camoufox-js';
    
    // Ensure you have run `npx camoufox-js fetch` first
    const browser = await Camoufox({
        // custom camoufox options
    });
                
    const page = await browser.newPage(); // `page` is a Playwright Page instance
  6. Launch Camoufox as a remote websocket server

    master

    You can run Camoufox as a remote websocket server. This allows access from other devices or other programming languages that support the Playwright API. Use launchServer to start the server and firefox.connect() to connect to it via its websocket endpoint.

    import { launchServer } from 'camoufox-js';
    import { firefox } from 'playwright-core';
    
    // Ensure you have run `npx camoufox-js fetch` first
    const server = await launchServer({ port: 8888, ws_path: '/camoufox' });
    const browser = await firefox.connect(server.wsEndpoint());
    
    const page = await browser.newPage();
    
    // ...
    // Use your browser instance as usual
    // ...
    
    await browser.close();  
    await server.close(); // Close the server when done
  7. Validate addon paths with confirmPaths()

    master

    Use confirmPaths to ensure that a list of addon directory paths are valid and ready for use. A valid addon path must:

    1. Exist on the filesystem.
    2. Be a directory.
    3. Contain a manifest.json file (indicating the addon is properly extracted).

    If any path fails these checks, the function throws an InvalidAddonPath error.

    import { confirmPaths } from 'camoufox-js';
    
    try {
      confirmPaths(['./addons/ublock-origin', './addons/custom-addon']);
    } catch (error) {
      console.error('One or more addon paths are invalid:', error);
    }
  8. Use NewBrowser() for low-level browser initialization

    master

    The NewBrowser() function provides a lower-level way to initialize a browser by explicitly passing the Playwright browser type (e.g., firefox). This is useful if you need to control the specific Playwright engine or handle custom launch logic.

    Parameters:

    • playwright: A BrowserType (typically firefox from playwright-core).
    • headless: A boolean or the string 'virtual'. Using 'virtual' enables a VirtualDisplay to simulate a headed environment even in headless mode.
    • fromOptions: An object used to override or provide additional launch configurations.
    • userDataDir: A string path for a persistent context, or false for a non-persistent browser.
    • debug: A boolean to enable debugging features.
    • launch_options: An object of type LaunchOptions.

    Return Value:

    • Returns a BrowserContext if userDataDir is a string.
    • Returns a Browser if userDataDir is false.
    import { NewBrowser } from 'camoufox-js';
    import { firefox } from 'playwright-core';
    
    const browser = await NewBrowser(
      firefox,
      'virtual', // Uses VirtualDisplay
      {},        // fromOptions
      false,     // userDataDir
      false,     // debug
      { headless: true } // launch_options
    );
  9. Manage proxy configurations with ProxyHelper

    master

    The ProxyHelper class provides utilities to parse proxy server strings and convert Proxy objects into various formats required by different HTTP clients.

    • parseServer(server: string): Parses a server string into its components (schema, url, and port). Throws InvalidProxy if the format is incorrect.
    • asString(proxy: Proxy): Converts a Proxy object into a full connection string (e.g., http://user:pass@host:port).
    • asAxiosProxy(proxyString: string): Converts a proxy string into an object compatible with Axios configuration ({ http: proxyString, https: proxyString }).
    import { ProxyHelper, Proxy } from "camoufox-js";
    
    const myProxy: Proxy = {
      server: "http://myproxy.com:8080",
      username: "user123",
      password: "secret"
    };
    
    // Convert to full connection string
    const connectionString = ProxyHelper.asString(myProxy);
    // Result: "http://user123:secret@myproxy.com:8080"
    
    // Convert to Axios format
    const axiosConfig = ProxyHelper.asAxiosProxy(connectionString);
    // Result: { http: "http://user123:secret@myproxy.com:8080", https: "http://user123:secret@myproxy.com:8080" }
  10. Validate IPv4 and IPv6 addresses

    master

    Use the following functions to validate IP address formats:

    • validIPv4(ip: string | false): Returns true if the string is a valid IPv4 address.
    • validIPv6(ip: string | false): Returns true if the string is a valid IPv6 address.
    • validateIP(ip: string): Validates that a string is either a valid IPv4 or IPv6 address. Throws InvalidIP if the validation fails.
    import { validIPv4, validIPv6, validateIP } from "camoufox-js";
    
    validIPv4("192.168.1.1"); // true
    validIPv6("2001:db8::1"); // true
    
    try {
      validateIP("not-an-ip");
    } catch (e) {
      // Throws InvalidIP
    }
  11. Download and extract a custom addon with downloadAndExtract()

    master

    If you have a specific addon URL, use downloadAndExtract to fetch the file and unzip it to a target directory. This is useful for managing custom extensions manually.

    Parameters:

    • url: The direct URL to the addon file (e.g., an .xpi file).
    • extractPath: The local directory where the addon should be extracted.
    • name: A label used for logging progress during download and extraction.
    import { downloadAndExtract } from 'camoufox-js';
    
    await downloadAndExtract(
      'https://example.com/my-addon.xpi',
      './local/path/to/addon',
      'my-custom-addon'
    );