AWAFAWAF

For developers

How the Antibot/AWAF source repository githubniko/antibot is organized: entry points, modular checks, lists, captcha, blocking, logs, updates, and safe extension points.

Repository purpose

Antibot/AWAF from https://github.com/githubniko/antibot is a PHP protection layer loaded before the protected site application. It evaluates a visitor through configuration, lists, and browser signals, then chooses one of three outcomes: allow, show the verification page with captcha, or block.

The protection code is usually installed on a protected site as /antibot/index.php.

index.php
xhr.php
includes/
includes/Checks/
includes/Utility/
lists/
templates/
skins/
js/
images/README/
VERSION

Entry points

  • index.php is the main protection entry point. It does not run in CLI, skips xhr and favicon, loads includes/autoload.php, creates WAFSystem::getInstance(), and calls run() when protection is enabled.
  • xhr.php is the JSON/XHR entry point for the verification page. It starts the session, disables caching, serves captcha skin requests, runs the second check phase through isAllowed2(), and sets the marker after a successful captcha.
  • .htaccess and the README example allow integration through a direct require_once in the protected site or through auto_prepend_file.

Central assembly

The main object is includes/WAFSystem.class.php. It is a singleton that wires dependencies and checker modules:

includes/autoload.php recursively requires PHP files under includes/ after sorting file names. When adding a class, do not assume Composer or PSR autoloading; the file must work with this simple loader.

  • Config reads and extends config.ini, creates cache/, and stores BasePath, CachePath, DOCUMENT_ROOT, and ANTIBOT_PATH.
  • Profile normalizes IP, HTTP protocol, User-Agent, Referer, Request URI, language, RayID, and RayIDSecret.
  • Logger, Marker, Template, GrayList, and session storage are shared by the checks.
  • includes/Checks/* contains independent modules for IP, ASN, URL, Referer, User-Agent, Tor, FingerPrint, HTTP, Mobile, FPS, IFrame, and index bots.

Check flow

The first phase runs before the verification page is shown:

The second phase runs from xhr.php after browser JavaScript posts func: "checks":

  • If the marker is already valid, the visitor is allowed immediately.
  • Fast allow rules run first: whitelist_ip, whitelist ASN, and index bots.
  • Block rules follow: IPv6 when configured as BLOCK, HTTP protocol, blacklist_ip, ASN block, Tor, URL block, and User-Agent block.
  • URL, User-Agent, and Referer rules can allow a request without captcha when the corresponding allow rules are enabled.
  • If no rule allows the visitor, Template->showVerificationPage() returns templates/template.inc.php.
  • js/api.js collects fingerprint, FPS, screen metrics, pixel ratio, referrer, location, BAS/old Mozilla engine signals, iframe state, and other browser data.
  • Api accepts only POST JSON, limits input size, requires a CSRF token, and adds bad requests to graylist.
  • isAllowed2() blocks missing required signals, BAS/old driver, and mobile/FPS/Fingerprint/IFrame/HTTP/ASN/Tor according to action BLOCK, or returns captcha according to action CAPTCHA.
  • If every filter passes, Marker->set() stores the marker and the API returns allow.

Modular checks

Most checks live as separate classes under includes/Checks/. Many modules follow the same shape: enabled, action, a list path under lists/, and Checking() or isListed().

When extending the system, prefer a new checker class and wire it explicitly in initializeComponents() and the relevant phase, isAllowed() or isAllowed2(). Do not fold unrelated behavior into an existing class when it needs separate settings, a separate list, or a separate action.

  • WhiteListIP and BlackListIP extend ListBase and support IPv4, IPv6, CIDR, and ranges through network utility classes.
  • RequestChecker, RefererChecker, and UserAgentChecker use string or regex-style lists for URL, referrer, and User-Agent rules.
  • ASNChecker caches ASN networks in a SQLite database under cache/ and refreshes them according to updateTime.
  • TorChecker downloads and caches Tor exit node lists.
  • FingerPrint checks the browser fingerprint against blacklist_fingerprint and can add the IP to blacklist_ip.
  • FPSChecker, MobileChecker, HTTPChecker, and IFrameChecker do not use list files; they decide from config and profile values.
  • IndexBot validates search bots through PTR rules from indexbot_rules; this is a heavier DNS check, so rule order matters.

Lists and configuration

config.ini is created and extended through Config->init() and Config->set(). If a parameter is missing, the module writes a default value and comment. Boolean values are parsed from On/Off, true/false, yes/no, and 1/0.

lists/ contains user and runtime lists. The base ListBase creates the file on first use, ignores comments after #, appends entries with file locking, and formats comments with a timestamp.

Important lists:

Do not hardcode absolute paths to these files. Use Config->BasePath, Config->CachePath, and config values because an installation may live somewhere other than /antibot/.

  • whitelist_ip, blacklist_ip, graylist
  • whitelist_uri, blacklist_uri, captcha_uri
  • whitelist_useragent, blacklist_useragent, captcha_useragent
  • whitelist_referer, blacklist_referer, captcha_referer
  • whitelist_asn, blacklist_asn, captcha_asn
  • blacklist_fingerprint, blacklist_tor, indexbot_rules

Captcha, templates, and client files

Captcha does not set the marker directly. The API first returns captcha and stores a hidden flag in session. After the skin succeeds, the client calls the dynamic marker function; xhr.php checks the hidden value and only then calls Marker->set().

  • Template->showVerificationPage() returns templates/template.inc.php, sends no-cache/noindex headers, and can return a 404 header for the placeholder when main.header404 is enabled.
  • Template->showBlockPage() returns templates/template_block.inc.php with HTTP 403.
  • skins/checkbox.php, slider.php, slider_rotate.php, slider_zsay.php, and example.php are captcha variants. The skin is selected through main.captcha_type; xhr.php sanitizes the requested skin name before requiring the file.
  • js/api.js, fp.js, frame_rate.js, metrika.js, tags.js, and js/lang/* provide browser checks, fingerprint/FPS collection, localization, and Yandex Metrika integration.

Logs, marker, and updates

Logger writes to logs/antibot.log with date, RayID, IP, and message. DEBUG level adds JSON context. Rotation is triggered in xhr.php during checks and uses logs.max_size and logs.rotate.

Marker stores the marker in a cookie with the aw_ prefix by default. The alternative cookie.storage_type = awsession uses file session storage under cache/sessid/. Changing cookie.cookie_name resets visitor markers because RayIDSecret is derived from salt, IP, and User-Agent.

SysUpdate updates code from githubniko/antibot through the GitHub API and a branch zip archive when sysupdate.enabled = On. While removing the old version it preserves .git, .gitignore, lists/, logs/, cache/, *.ini, *.bak, *.backup, *.origin, and the update archive. Local edits in PHP, JS, templates, or skins can be overwritten by an update, so keep such changes in version control or a separate deployment process.

Safe extension and debugging

  • Add new settings through Config->init() first, so existing installations receive a safe default.
  • Preserve rule order: cheap allow/block checks should stay before DNS, ASN, external HTTP downloads, and browser checks.
  • For list-based rules, extend ListBase and override validation/comparison only when the data format differs.
  • Do not trust JavaScript data: isAllowed2() must validate presence and type for each field, as it already does for frameRate, fingerPrint, isBas, screenWidth, pixelRatio, isFrame, and location.
  • Behind proxies or Cloudflare, use HeaderProxy and the header_proxy section instead of reading REMOTE_ADDR directly.
  • Debug behavior through logs/antibot.log: look for RayID, IP, allow/block/captcha reasons, and list insertion messages.
  • Do not rename public API statuses (allow, captcha, block, fail, no_csrf) without changing js/api.js and skins together.
  • Before release, check PHP compatibility. The README states PHP 5.6.4+ support, so avoid syntax that breaks older installations.