How to Modify GET and POST Requests with WordPress
I’ve written before about protecting against malicious POST requests using Apache/.htaccess. In this tutorial, we’ll look at how to modify GET and POST requests using PHP and some core WordPress functionality (with no .htaccess
required).
Normally you would want to manipulate URI requests at the server level, but that’s not always possible (like on shared hosting). So in those cases where you want to modify GET, POST, or other types of requests on a WordPress site, check out the following technique.
Modify POST Requests with WordPress
Here is an example showing how to modify POST requests using PHP and some built-in WordPress functionality. This code could be added via theme template functions.php
, or added via plugin.
/*
Modify POST Requests
@ https://m0n.co/wp-requests
*/
function shapeSpace_modify_requests() {
if (isset($_SERVER['REQUEST_METHOD'])) {
$method = $_SERVER['REQUEST_METHOD'];
// GET requests
if (strtoupper($method) === 'GET') {
if (isset($_GET)) {
// modify GET request
}
}
// POST requests
elseif (strtoupper($method) === 'POST') {
if (isset($_POST)) {
// modify POST request
}
}
}
}
add_action('parse_request', 'shapeSpace_modify_requests', 1);
The main thing to understand about this technique, is that we are using the parse_request action hook. As explained in the WP Codex, parse_request
is ideal for modifying URI requests because it:
Allows manipulation of HTTP request handling
By hooking our function shapeSpace_modify_requests()
into parse_request
, we have full access to all GET and POST variables, plus all server information, IP address, referrer, user agent, and anything else that you may want to utilize or modify.
Inside of the shapeSpace_modify_requests()
function, we are using basic PHP functions to check the request method and the $_GET
and $_POST
variables. As you can see by looking at the code, it is all pretty much self-explanatory. To get a better idea, check out the examples below.
parse_request
hook by lowering it from 1
to 0
.Examples
Here are a couple of examples to give you a better idea of how it works. The first shows how you would go about securing POST requests on your site. The second example shows how to send an email alert for each POST request. Of course, these examples are easily modified to target GET requests instead.
Example: Secure POST requests
In this example, we restrict POST requests so they only are allowed from the site itself. So example.com
can submit POST requests for comments, contact forms, or whatever. But any POST requests from other locations will be denied.
/*
Secure POST Requests
@ https://m0n.co/wp-requests
*/
function shapeSpace_secure_post_requests() {
if (isset($_SERVER['REQUEST_METHOD'])) {
$method = $_SERVER['REQUEST_METHOD'];
if (strtoupper($method) === 'POST') {
$host = @gethostbyaddr($address);
if ($host !== 'example.com') {
status_header(403);
exit;
}
}
}
}
add_action('parse_request', 'shapeSpace_secure_post_requests', 1);
Again, this should be mostly self-explanatory by examining the code should say better than my sloppy English. But in a nutshell, the code checks if the request method is POST. If so, it checks if the host name matches the name of your site. If it does not match, a 403 “Forbidden” status is sent in response.
.htaccess
, check out my tutorial on securing POST requests for WordPress.Example: Send POST Alerts
For this example, we hook into parse_request
with a function that sends an email alert for each POST request. This technique demonstrates how to get other $_SERVER
variables, like IP Address, Request URI, and Referrer.
/*
Send POST Alerts
@ https://m0n.co/wp-requests
*/
function shapeSpace_send_post_alerts() {
if (isset($_SERVER['REQUEST_METHOD'])) {
$method = $_SERVER['REQUEST_METHOD'];
if (strtoupper($method) === 'POST') {
$email = get_bloginfo('admin_email');
$request = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';
$address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
$referrer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
$message = esc_html($address) . "\n" . esc_html($request) . "\n" . esc_html($referrer);
mail($email, 'POST Alert', $message);
}
}
}
add_action('parse_request', 'shapeSpace_send_post_alerts', 1);
Again the code in this example is kept super simple, so reading the code probably will explain everything clearly. In plain English, we hook into parse_request
and check the request method. If it is a POST request, then we grab server variables for the Request URI, IP Address, and Referrer URL. We then send the variable information as email alert message.
Notes for Example #2
In the previous example, we use the $_SERVER['REMOTE_ADDR']
variable to get the IP Address for the request. While this works fine most of the time, there are cases where it may be inaccurate (like when the request is made via proxy server or similar). So for more accurate results, here is a tutorial at WP-Mix that explains how to get the actual IP address.
Another note: If you want to add more request details to the alert, like for Host Name, User Agent, and so forth, check out my post on WordPress 404 email alerts. There you can find numerous variables that may be included.
Take-Home Message
To modify GET and POST requests with WordPress, hook your function into the parse_request
action hook. Then use $_SERVER['REQUEST_METHOD']
to check the type of request, as well as other variables like $_GET
, $_POST
, $_SERVER
, and so forth. The old cliche applies here: the possibilities are endless :)
3 responses to “How to Modify GET and POST Requests with WordPress”
Very nice little tutorial!
Also could a be a great way to catch those miscreants in the act with some of their tricks.
One thing that has been bothering me for sometime in concerns with one of WordPress’s latest little “changes”:
It seems they insist on adding the header field called “Link:” and populating it with a “Link rel”-like value, which includes the “angle-brackets” into the response header. I have tried a multitude of ways to simply delete it from the response headers before sending the final output to the user agent. – This worked well when I was still using “mod_php” in my development machine by simply “unsetting” it within the .htaccess file.
However,
I am switching my servers over to using PHP-FPM, instead of MOD_PHP, to add some more security to my sites, and the .htaccess trick, as well as any PHP tricks are failing miserably to remove the unwanted response header ( “Link: . . . “).
So, I do not know if you have ever played with PHP-FPM (on Apache2 OR Nginx) yet. I do know that using the MOD-PROXY-FCGI is necessary to use PHP-FPM. Therefore, I am at my wit’s end on this little problem?
Anyway,
Again, a great and informative article, and thanks for the great “how-to’s”.
– Jim S.
Thanks Jim! Always good to hear from you :)
I realize this is a bit off the current subject, but I believe I have found my needed solution.
It seems that starting with WordPress 5.2 +, I have to use TWO (2) “remove_action()” statements in my theme’s “functions” file.
In order to remove the "Link: . . ." header field completely. It took me a while to find the declarations for adding them in the "default-filters.php" file within ./wp-includes .
So,
I hope this helps others, who may have been looking for, into solving this issue! I never was big on "bloat" (in HTML, nor the Headers), as this was why I moved all my computing to Linux and other open-source.
- Jim S.