Skip to content

Latest commit

 

History

History
92 lines (69 loc) · 5.29 KB

allowlist.md

File metadata and controls

92 lines (69 loc) · 5.29 KB

Allowlist

An allowlist records findings that a person has checked and accepted. Use it for things that are legitimate on your site but match a rule, such as a must-use plugin added by your host.

Pass the file with --allowlist to scan or sweep:

wp-malware-scan scan --sql shop.sql --files public_html --allowlist allow.json

In a sweep, one allowlist applies to every site. Choose locations that mean the same thing on each site, or sweep sites that need different lists separately.

File format

The file is JSON, UTF-8, with one key, allow, which holds a list of entries:

{
  "allow": [
    {
      "rule": "FS-MU-110",
      "location": "wp-content/mu-plugins/loader.php",
      "reason": "Cache loader from the hosting provider, checked against its documentation"
    },
    {
      "rule": "DB-OPT-013",
      "location": "options: example_cache_*",
      "reason": "Option names written by the example cache plugin, checked in its source"
    }
  ]
}

Each entry has exactly three keys:

  • rule is a rule id from rules.md.
  • location is the location of the finding, as the report prints it after "Where:". It must match exactly. It may end with * to match every location that starts with the text before it. A location of * alone would accept every finding of the rule, so it is refused for rules of CRIT or HIGH severity: name a path or a prefix. The report prints every location with forward slashes, for files and for the database alike, so backslashes in an entry are read as forward slashes in both.
  • reason is required and must not be empty. Say why the finding is acceptable and how you checked. It is shown in the report. Control characters and invisible format characters in it are replaced and it is cut at 300 characters. A reason that has nothing left after that is refused.

Unknown keys, a missing key, an unknown rule id, an empty location or a lone * for a CRIT or HIGH rule make the tool refuse the file and exit with 64 before it scans anything. The file can be at most 1,000,000 bytes and 5,000 entries.

What happens to an allowlisted finding

It stays in every report, in its own "Allowlisted" section with its reason, and it is left out of the verdict and out of the finding counts. The verdict reason says how many were left out, by severity, for example "1 allowlisted finding (HIGH 1) was left out of the verdict". This is the text report for the example site from the README with the must-use plugin above allowlisted. The verdict is still INFECTED, because of the PHP file in the uploads folder, and the plugin moves to its own section:

Allowlisted (1)
---------------
These were accepted by a reviewer and are left out of the verdict.
  FS-MU-110  Must-use plugin present
      Where: wp-content/mu-plugins/loader.php
      Reason: Cache loader from the hosting provider, checked against its
             documentation

Rules that cannot be allowlisted

A rule that escalates to FULLY-COMPROMISED cannot be allowlisted. These rules match things with almost no legitimate use, such as a known backdoor option name or dangerous code planted after the settings include in wp-config.php. The tool refuses a file that names one and exits with 64:

wp-malware-scan: error: allowlist: entry 1 names FS-SIG-120, which cannot be allowlisted: a single finding from it means the site is fully compromised

The escalating rules are marked in rules.md. A finding from one is never marked as allowlisted, and it always counts toward the verdict.

Example: statements at the end of wp-config.php

Some host images, and some site owners, add statements to wp-config.php after the line that loads wp-settings.php. When none of them uses a dangerous capability the scan reports FS-CFG-142 (HIGH, not escalating). Read the lines once, and if they are yours or your host's, allow the exact location:

{
  "allow": [
    {
      "rule": "FS-CFG-142",
      "location": "wp-config.php",
      "reason": "Pingback filters added by the hosting image after the settings include, reviewed once"
    }
  ]
}

The entry covers FS-CFG-142 and nothing else. If code that uses one of the dangerous tokens listed in the README limitations is later added after the include, the finding becomes FS-CFG-140, which cannot be allowlisted. Code that uses none of those tokens is not told apart: an allowlisted FS-CFG-142 also hides any later addition of that kind, because the entry matches the file and not its content. Read wp-config.php again after any change to it, and remove the entry when you no longer trust the lines it covers.

Good practice

  • Check before you allow. Open the file or read the option. Do not allow something because it is common.
  • Be exact. Prefer a full location to a prefix with *. For a MED, LOW or INFO rule a lone * is allowed, but it accepts every present and future finding of that rule. A prefix also accepts anything an attacker later puts under it.
  • Write a reason you can check later. Name the source and the date.
  • Review the list. A finding you accepted a year ago may not be what is there now. Remove entries when you remove the thing they cover, and look at the list again after any incident.
  • Keep it with the site's records, not inside the scanned files folder.