Wiki source code of Spam Detection When Saving a Page
Last modified by Vincent Massol on 2026/08/14 19:08
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | Spam Checking is not a scheduled scan but a veto on the save itself: the application listens to the events XWiki fires just before a page is created or updated, and cancels the save when the page looks like spam, so that spam never reaches the wiki at all. | ||
| 2 | |||
| 3 | What it inspects is not the content field but the whole document serialised to XML. The title, the page name, the xobjects and the class definition are matched too, which is what catches spam hidden in a comment object or in a page name rather than in the visible text. | ||
| 4 | |||
| 5 | A save is refused in two cases: the serialised document matches one of the patterns of ##AntiSpam.Keywords##, or the IP address of the request is listed on ##AntiSpam.IPAddresses##, which is how an account that has already been caught is stopped from contributing again. The second case has one deliberate exception: the guest user is refused on a keyword match but never on its address alone, because XWiki saves some documents as guest at startup and banning that address would break the wiki. | ||
| 6 | |||
| 7 | Two kinds of page are never inspected: pages in the ##AntiSpam## space, and pages in the spaces listed on ##AntiSpam.Excludes##. Clearing the "Is Spam Checking Active?" setting stops the inspection entirely. | ||
| 8 | |||
| 9 | When a page is refused, four things are recorded and the save is cancelled: | ||
| 10 | |||
| 11 | * the account is disabled, so that it cannot log in again; | ||
| 12 | * its reference is appended to ##AntiSpam.DisabledUsers##; | ||
| 13 | * the IP address of the request is appended to ##AntiSpam.IPAddresses##; | ||
| 14 | * the matched keywords, the author and the page are appended to ##AntiSpam.Logs##. | ||
| 15 | |||
| 16 | None of the first three happen to a [[protected user>>doc:documentation.extensions.admin.antispam.protected-users.WebHome]]: the save is still refused, but the account survives untouched. | ||
| 17 | |||
| 18 | What the author sees is XWiki's own error page, with the reason under "Detailed information" rather than in a message written for the occasion: | ||
| 19 | |||
| 20 | {{image reference="save-cancelled.png" size="extra" alt="XWiki's generic Notice error page after a save was cancelled, with the reason shown under Detailed information"/}} | ||
| 21 | |||
| 22 | The reason itself depends on who is reading it. A protected user is told what matched, so that a false positive can be diagnosed: | ||
| 23 | |||
| 24 | {{code language="none"}} | ||
| 25 | The update of [xwiki:Sandbox.SpamCheckDemo] by user [xwiki:XWiki.Admin] has been cancelled since it contains spam. Found spam: [[cheap viagra = [...<content>Get cheap viagra online today...]]] | ||
| 26 | {{/code}} | ||
| 27 | |||
| 28 | Anyone else gets a message that names nothing, so that a spammer cannot use it to work out which words to avoid: | ||
| 29 | |||
| 30 | {{code language="none"}} | ||
| 31 | The update of [xwiki:Sandbox.SpamCheckDemo] has been cancelled since it contains spam. | ||
| 32 | {{/code}} | ||
| 33 | |||
| 34 | The address that gets banned is read from the ##X-Forwarded-For## header when the request carries one, and from the request itself otherwise. Which entry of that header holds the real client depends on how many proxies sit in front of the wiki, which cannot be guessed, so it is a setting rather than a default: see [[AntiSpam Configuration>>doc:documentation.extensions.admin.antispam.configuration.WebHome]]. |