Web Rules Engine
The Web Rules Engine is a User Portal-based service that enables you to self-serve site rules as an alternative to .htaccess rules. The service currently supports management of the following rule types: IP-based Allow/Deny rules, response headers, and rewrite rules.
NOTE
Looking for more simple redirects, like one page to another? See our Redirect Rules guide.
Overview
The Web Rules Engine (WREn) enables you to self-manage certain site traffic behaviors from the User Portal, such as:
- Disallowing IP or IP Range access to protect against malicious attacks and other negative site behavior
- Allowing IP or IP Range access for known good actors
- Preventing direct access to private files
- Restricting traffic from specific countries or regions
- Modifying cache-control headers and security headers
- Redirecting a page
- Rewriting a page URI
For those who previously leveraged .htaccess file rules to self-manage and control these behaviors, the Web Rules service can now be used instead via the User Portal.
Add Web Rule
To add access, header, and rewrite rules for any environment:
- From the Sites page, elect the environment name
- Click Web Rules in the secondary lefthand menu. (You may have to expand the Advanced dropdown section)
- Next, you can choose the Access rules tab, the Header rules tab, or the Rewrite rules tab to manage a specific type of rule.
- Then, click Add Rule
Web Rules functionality is enabled by default on all environments, but can be disabled (EX: when troubleshooting) by selecting Disable web rules.
NOTE
Web Rules (access, header, and rewrite rules) cannot be bulk imported at this time.
Add Relative Rule
Users with existing web rules have additional options for adding new rules in relation to existing rules. This can be useful when creating rules whose order is significant.
- Open the Web Rules page
- Locate an existing rule
- Click the 3 dot menu icon to the right
- Select an insert option:
- Insert rule above – Creates a rule above the selected. The new rule will be read first and have higher priority, i.e. an exception to a more broad rule placed below.
- Insert rule below – Creates a rule below the selected. The new rule will be read second.
Copy Web Rule
Web rules can be copied from one environment to another environment on the same account. Rules will be copied as-is and will include access, header, and rewrite rules. Duplicate rules on the destination environment will not be copied, so as to not cause any conflicts. Both source and destination should have their rules cleaned up prior to copying.
Bulk Copy Web Rules:
- From the Sites page, select the environment to copy web rules from
- Click Copy rules to target environments.
- Select the destination environment(s) to receive the rules
- Choose the order to insert the rules:
- Appending the rules will copy the source rules to the bottom of the target rule list, after any existing rules on the destination.
- Prepending the rules will copy the source rules to the top of the target rule list, before any existing rules on the destination.
- Learn more about Web Rule order here.
- Click Copy Rules
Copy a Single Rule
To copy a single rule to another environment or multiple environments:
- Locate the rule you’d like to copy
- Click the 3 dot menu icon to the right
- Select Copy to target environments
- Select the destination environment(s) to receive the rules
- Choose the insert order:
- Appending the rules will copy the source rules to the bottom of the target rule list.
- Prepending the rules will copy the source rules to the top of the target rule list.
- Learn more about Web Rule order here.
- Click Copy Rule
Edit Web Rule
- Open the Web Rules page
- Locate the rule you wish to edit
- Click the 3 dot menu icon to the right
- Select Edit Rule
- Make the necessary changes
- Click Edit Rule to revalidate and apply the update
Delete Web Rule
- Open the Web Rules page
- Locate the rule you wish to edit
- Click the 3 dot menu icon to the right
- Select Delete Rule
Delete Rule Across Multiple Environments
To delete a rule across multiple environments at once, select the menu next to the rule then click Delete from target environments.
A prompt will then display a list of the environments this rule is also applied to, and only rules that are an exact match will be detected. The list will show all environments your user has access to, across all WP Engine accounts. Select the environments you’d like to delete the rule from, then click Delete Rule.
Web Rule Order
The order Web Rules are placed in the list can be critical to how they function because many rules can have an impact each other. Web Rules are read from top to bottom, and rules that are read first take priority.
Another way to visualize this is that exceptions to the rule are listed first. For example, if you want to block an IP range but allow a single IP within that range, you will need two rules. The rule listed first will allow the IP address, and the rule listed second will block the IP range.
If a specific exception is allowed higher on the list, the priority will apply for all subsequent rules. In the following example, the bottom two rules deny several countries and a user agent. The rule at the top, allowing a specific IP, is read first and has the highest priority over any rules below it. Therefore, the topmost rule will allow this IP even if it is located in one of the blocked countries OR utilizing the blocked user agent.
With regard to rewrite rules, the first rule whose conditions are met for the request will take effect. If a URL is impacted by multiple rewrite rules, the topmost rule will trump the other rules that may apply to that specific URL. If a more general rewrite is placed first, this could impact lower rules down the road. Being specific with your RegEx and rule order can prevent unintended rewrites from occurring.
Rules can be rearranged, if needed, using the drag-and-drop functionality on the left. Adding a rule relative to another rule can make implementing new rules easier. It’s recommended to use the relative adding method when possible, rather than manually rearranging each rule later, to ensure the order is applied as intended.
Rules can have comments added to help prevent confusion and subsequent damage to the rule order over time. For example, the rule to allow a single IP must be above the rule blocking the country this IP is located in, as an exception. Adding notes can help keep this order clear as the rules list changes or grows:
Allow or Deny XML-RPC
XML-RPC is considered out-dated and is prone to both attack and spam. In most cases the WordPress® API can be used instead of XMP-RPC, however you may find some applications still require access to xmlrpc.php.1
XML-RPC can be set to allow or deny access via a simple toggle on the Web Rules page for each environment.
- Select Deny XML-RPC – recommended to block XML-RPC requests.
- Select Allow XML-RPC to allow XML-RPC requests.
NOTE
XML-RPC is blocked by default on WP Engine environments created after April 2022. We recommend confirming the current setting.
If you choose to allow XML-RPC, we recommend some additional custom access rules to keep it secure. By creating two custom access rules you will first limit the IPs that can access xmlrpc.php, then a second rule (placed directly below the first) will deny all others. For example:
First Rule – Grants limited access to xmlrpc.php
:
- Action: Allow
- IP: [IP(s) to allow]
- Conditions:
- Type: URI
- Operator: Regex matches (~)
- Value:
xmlrpc.php
Second Rule – Block all IPs not specified above:
- Action: Deny
- IP: All
- Conditions:
- Type: URI
- Operator: Regex matches (~)
- Value:
xmlrpc.php
Attach and-conditions
And-conditions are combined using the boolean “and” operator. This means that all conditions applied to the rule must be met for the rule to take effect.
Conditions are combined with operators to define how the condition should be met. The value is then defined manually to declare what condition specifically should be met.
Condition | Purpose |
---|---|
URI | URI to match in source. EX: /somepage |
QUERY_ARG | Query arg to match in source. EX: input_this do not preface with the query indicator ? |
REQUEST_METHOD | Request method of page. EX: POST |
HEADER | Header sent with request. EX: User-Agent |
GEOIP COUNTRY CODE | ISO Country code. Uses MaxMind database. EX: US |
IP | IP address of request. |
Operator | Purpose |
---|---|
Equal to (=) | Value matches exactly. |
Not equal to (!=) | Value must be excluded exactly. |
Regex matches (~) | Use RegEx to define a dynamic value which must be included. |
Negative regex matches (!~) | Use RegEx to define a dynamic value which must be excluded. |
Access Rules
Access rules can allow you to manage the flow of traffic to a website with certain restrictions. For example, access rules can be used to block an IP range. Access rules are read in cascading order, can be set for IP or IP ranges, and can have certain conditions applied.
- Open the Web Rules engine
- Select Access Rules
- Click Add Rule
- Enter the rule
- Click Add Rule to validate and save the new rule
- Once your web rules have been validated and applied, they will populate in the rule table
Access Rule Examples
Below are some examples of common rules you may use. Rules can be modified as necessary, for example switching deny and allow, or using an IP range versus a single IP.
Be cautious when denying access to critical pages (such as wp-admin
), as developers and external services can also lose access if not allowed.
- Deny an IP address:
- Action: Deny
- IP: [IP address to deny]
- Conditions: None are needed
- Deny a bot by way of its user agent:
- Action: Deny
- IP: All
- Conditions:
- Type: Header
- Name: User-Agent
- Operator: Regex matches (~)
- Value: [Name of the user agent] EX:
badbot
- Allow a single IP address access to wp-login and deny all other IPs access (It’s recommended to restrict wp-login instead in most cases where wp-admin should be restricted, so as to not cause potential issues.)
- First rule (should be placed above the second rule):
- Action: Allow
- IP: [IP address to allow]
- Conditions:
- Type: URI
- Operator: Regex matches (~)
- Value:
wp-login
- Second rule (should be placed below the first rule):
- Action: Deny
- IP: All
- Conditions:
- Type: URI
- Operator: Regex matches (~)
- Value:
wp-login
- First rule (should be placed above the second rule):
- Deny traffic from non-US GeoIPs:
- Action: Deny
- IP: All
- Conditions:
- Type: GeoIP Country Code
- Operator: Not equal to (!=)
- Country Codes: [‘US – United States’]
- Block specific countries from accessing a website:
- In this example, block China, India, and South Africa.
- Action: Deny
- Comment:
Block China, India, and South Africa
- Conditions:
- Type: GeoIP Country Code
- Operator: Equals (=)
- Value:
CN, IN, ZA
- Only allow traffic from specific countries, block all other countries:
- In this example, allow traffic from the United States (US), Canada (CA) and block all others.
- Action: Deny
- Comment:
Only allow US and Canada
- Conditions:
- Type: GeoIP Country Code
- Operator: Does Not Equal (!=)
- Value:
US, CA
- Block country, but allow a specific IP within that country:
- If you want to block an entire country then grant access to a specific IP within that country, you would create an Allow rule for the specific IP and place it before the broader country block. Be sure to name the rule with an identifiable phrase, as the order here is important.
- Block traffic based on referrer (such as spam referrers):
- In this example, block the spam referrer “baddomain.com”.
- Action: Deny
- Conditions:
- Type: Header
- Name: Referer
- While the word “referer” here is spelled incorrectly, this is the correct spelling for this particular usage. Learn more here.
- Operator: Regex matches (~)
- Value:
baddomain.com
IP and CIDR Standardization
The list of IPs and CIDRs for every access rule are sorted, CIDR blocks are standardized, and duplicates are removed. The standardized list is always equivalent to the original. It will not allow or block anything that wasn’t in the original list.
For example:
177.47.19.194/30, 177.47.19.198/30, 177.47.18.106/29, 200.219.195.250/30
Will be standardized to the equivalent:
177.47.18.104/29, 177.47.19.192/30, 177.47.19.196/30, 200.219.195.248/30
Header Rules
Using the Web Rules Engine, response headers can be set. This section can be used to add Nginx security headers or to modify cache behavior via cache control headers. Header rules function the same as access rules; they are read in cascading order and can be set/unset by header name.
- From the Sites page, select the environment name
- Click Web Rules (You may have to expand the Advanced dropdown section)
- Select Header Rules
- Click Add header rule
- Enter the rule, then click Save
For header rule conditions, see Attach and-conditions.
Header Rule Examples
- Set a header to allow all access control for 2xx status responses:
- Action: Set
- Name:
Access-Control-Allow-Origin
- Value:
*
- When: Only on successes
- Conditions: None are needed
- Unset Set-Cookie header for all responses:
- Action: Unset
- Name:
Set-Cookie
- When: All responses
- Conditions: None are needed
- Set Cache Control for URIs in /resources:
- Action: Set
- Name:
Cache-Control
- Value:
max-age=604800, public
- When: Only on successes
- Conditions:
- Type: URI
- Operator: Regex matches (~)
- Value:
/resources/
- Set HSTS header for 2 years, include subdomains, and preload:
- Action: Set
- Name:
Strict-Transport-Security
- Value:
max-age=63072000; includeSubDomains; preload
- When: Only on successes
- Conditions: None are needed
- Prevent indexing in the default *.wpengine.com URL
- Action: Set
- Name:
X-Robots-Tag
- Value:
noindex, nofollow
- When: All Responses
- Conditions:
- Type: Header
- Name:
Host
- Operator: Regex matches ~
- Value:
.wpengine.com$
- Set content-security-policy header – Policies should be tailored to each site, the example below should not be copied exactly. Report URI has a tool to help generate headers based on the provided parameters.
- Action: Set
- Name:
Content-Security-Policy
orContent-Security-Policy-Report-Only
may be used - Value:
[enter custom policy]
- When: Can be set as either, if the header should present on all responses or only 2XX
Restricted Headers
Certain headers are restricted from Web Rule functionality either because they conflict with platform features or are unsupported.
x-powered-by
server
date
x-orig-cache-control
nr-enabled
x-cache
x-cache-group
x-cacheable
X-pass-why
- Any header that includes
WPE
Rewrite Rules
Using the Web Rules Engine, rewrite rules can be added to Nginx. A rewrite can be used to change the URL requested by a client and route the client to a new location. Rewrite rules are read in cascading order. Conditions can be applied to a rule to limit when that rule is triggered. The first rewrite rule whose conditions are met is triggered. Note that the source of a rewrite rule acts as an implicit URI condition.
- From the Sites page, select the environment name
- Click Web Rules (You may have to expand the Advanced dropdown section)
- Select Rewrite Rules
- Click Add rewrite rule
- Enter the rule, then click Save
See Attach and-conditions here.
Rewrite Rule Fields
- Action: The rewrite action defines what type of rewrite to perform. Supported actions:
- Permanent redirect (301 status code): Permanent redirects respond to the client with the 301 status code and directs the request the location defined in the rule destination.
- Temporary redirect (302 status code): Temporary redirects respond to the client with the 302 status code and directs the request the location defined in the rule destination.
- Internal rewrite: The internal rewrite action responds with content from the rule destination without redirecting the client to another URI. For example, a request for
/page-1
may be rewritten internally to/page-2
, such that the contents of/page-2
are returned to the client without the client being aware the content is from/page-2
.
- Source: The rule source is a regular expression (RegEx) that must match the original request URI, including the query string, for the rewrite to happen. The rule source regex may contain named and numbered capture groups to be referenced in the rule destination.
- Destination: The rule destination defines the target URI for the rule. It may be a static URI, or it may include references to capture groups from the rule source. New query string arguments can be added in the rule destination. Additionally, original query string arguments may be preserved via the “Keep or Discard Original Query String” option.
- Keep or Discard Original Query String: For each rewrite rule, you may declare whether to keep or discard the original query string of the request. Keeping the query string is the default behavior. If the rule destination has a query string and the rule preserves the original query string, original query string arguments will be appended to the rule destination.
Rewrite Rule Examples
- Simple 301 redirect
- Action: Permanent
- Source:
/oldpage/
- Destination:
/newpage/
- Original Query String: Keep
- Conditions: None are needed
- Rewrite only if user agent matches
- Action: Internal
- Source:
^/index.html
- Destination:
bot.html
- Original Query String: Discard
- Conditions:
- Type: Header
- Name:
User-Agent
- Operator: Equals (=)
- Value: [Enter user agent] EX:
badbot
- Redirect based on country code
- This example will redirect all traffic to a URL based on the requester’s country (United States in this example). This can be modified to include or exclude countries based on the conditions set. Web Rules references MaxMind’s ISO country code database.
- Action: Permanent
- Source:
^/someurl
- Destination:
https://newurl.com/
- Original Query String: Discard
- Conditions:
- Type: GeoIP Country Code
- Operator: Equal to (=)
- Country Codes: US
Capture Group Examples
Rewrite rules’ source and destination parameters support named and numbered regular expression capture groups.
Capture groups allow you to contain and use multiple characters as a single unit, i.e. a variable. When capturing a group from the source, it can then be easily appended into a specific location of the destination. A capture group is created by surrounding the target characters in parentheses. Because the content contained by the capture group will typically vary, RegEx should be used to capture the range expected phrases. For a review, see our RegEx guide and see some helpful RegEx resources.
- Redirect with a capture group
- Action: Permanent
- Source:
(.*)
- Destination:
https://www.example.com/$1
- Original query string: Discard (this is already contained in the capture group)
- Conditions: None are needed
- Restructure URL with capture group
- Action: Permanent
- Source:
/oldpage-(.*)/
- Destination:
/newpage-$1/
- Numbered capture groups
- By default, capture groups are referenced in numerical order. The first group is 1, the second 2, and so on. This can be used to rearrange information in the destination URL.
- Source:
/oldpage-(d+)/(.*)
- Destination:
/newpage/$1/$2
- Source:
- Named capture group
- This capture group is assigned a name. This allows for better readability and documentation. A named capture group is denoted using
?P<capturegroupname>
followed by any relevant RegEx that should be used for that capture group.- Source:
/oldpage-(?P<number>d+)/
- Destination:
/newpage/$number/
- Source:
- Concatenating characters to capture groups
- If static characters should be concatenated with contents of a capture group, wrap the capture group reference in curly braces “{}”.
- Source:
/oldpage-(d+)v1
- Destination:
/newpage-${1}v2
- Source: