0

I am trying to get the current page url which require the use of $_SERVER["REQUEST_URI"].
The point is how do I need to sanitize the returned URL?
I tried to use sanitize_url( string $url, string[] $protocols = null ) on the $pageURL variable but this returned "https" only as a result.
Using sanitize_url on $_SERVER["REQUEST_URI"] directly made the website goes critical error.

What am I doing wrong here?
This is my current code "which is working" but not sanitized:

$pageURL = 'http';
if( isset($_SERVER["HTTPS"]) ) {
    if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
    $pageURL .= esc_html($_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].htmlspecialchars
    ($_SERVER["REQUEST_URI"]));
} else {
    $pageURL .= esc_html($_SERVER["SERVER_NAME"].htmlspecialchars($_SERVER["REQUEST_URI"]));
}



    $parse = parse_url($pageURL);
    
    
if($parse !== false)
{
    return esc_url($pageURL);
}
else{ __return_false();}

Context: This function will be called in the frontend using a short code to get the page URL

2
  • 1
    What's the context you're trying to get the page URL? Frontend? Backend? Commented Jun 8, 2022 at 22:15
  • Unrelated, but using __return_false(); like that isn't going to do anything. If you want to return false from your function you need to actually use return. That function is mainly intended as a callback, and isn't meant to be used like this. Commented Jun 9, 2022 at 1:50

2 Answers 2

0

Good on you for trying to do this properly - but... how about this?

global $wp;
echo esc_url( home_url( $wp->request ) );

EDIT: Versions of your above code have been written all over the internet - see this SO question with 000s of votes. rather UN-intuitively it's not a super simple thing to do as the client can set some of these themselves, so you're right to want to sanitize.

Sanitization is just the removal of anything you're not expecting in your string... You're expecting a URL - so only allow valid URL characters through. If you don't need to echo out query strings - well then you could also remove everything that's not in your page names or site structure. The point is - you decide - there isn't a function that just does sanitize_this() your job is to work out exactly what the limit is for allowing data through. Maybe one of these work? Look at what is permitted through and decide what's right in that use case.

Generally you should only need to sanitize once and escape once to avoid over complication and if you're encoding you don't want to double encode - you could actually be making your code less secure as other functions could be looking for strings such as '<script>' in "decoded" strings and only seeing %3Cscript%3E meanwhile your JavaScript decodes and outputs later on. You see what I mean?

My point above about using wp is that it's already there for you. Re-writing these functions is asking for mistakes, security implications and odd error conditions and dealing with common PHP issues using your own custom functions is naive at best and arrogant at worse - professionals have already done this for you - why do you want to do it again?

Regarding the critical issue you mention - sanitize_url( $_SERVER['REQUEST_URI'] ); is valid markup - sanitize_url() is a WordPress function and will need WordPress to have been loaded to work. Check your logs for the exact cause.

2
  • Thank you! The main point is how to sanitize $_SERVER["REQUEST_URI"] properly with out loosing parts of the URL?
    – ehab
    Commented Jun 9, 2022 at 19:55
  • @ehab - I've edited my answer to explain a little more - let me know if there's anything you're not clear on
    – Bysander
    Commented Jun 10, 2022 at 12:56
0

I have added a code with some details. You have to convert the URL into parts and then check it and sanitize it.

    // Parsing the URL
$parse = parse_url($pageURL);

// If the parsing was successful, sanitize and return the URL
if ($parse !== false) {
    // Split the URL into base and query parts. scheme=https/http, host=domain, path=/path/to/page
    //For example, if $pageURL is "https://example.com/path/to/page", after parsing, $parse['scheme'] would be "https", $parse['host'] would be "example.com", and $parse['path'] would be "/path/to/page". Therefore, the $base_url constructed would be "https://example.com/path/to/page".
    //If the URL has a query string (e.g., "https://example.com/page?query=value"), it would be appended to the base URL as well:
    
    $base_url = $parse['scheme'] . '://' . $parse['host'] . $parse['path'];
    
    //This code checks if there's a query string component in the parsed URL ($parse['query']). If it exists, it appends it with a leading ? to the $query_string variable. Otherwise, it remains an empty string.
    //So, after constructing $base_url and $query_string, you can concatenate them to get the complete sanitized URL.
    //if the URL has a query string like "https://example.com/page?query=value", then $parse['query'] would be "query=value", and $query_string would be "?query=value". If the URL doesn't have a query string, $query_string would remain an empty string "".
    $query_string = isset($parse['query']) ? '?' . $parse['query'] : '';

    // Sanitize the base URL and combine with the query string
    $sanitized_url = esc_url($base_url) . $query_string;
    
    return $sanitized_url;
} else {
    return __return_false();
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.