url not valid on wp_safe_remote_get

I develop an application using the woocommerce v3 API.

I want push an image by remote_url.

Read More

my url : http://tshirt-previewer.internal.teezily.com/media/W1siZiIsIjIwMTUvMTAvMjgvMTQvNTAvMzMvNGQ0NmVhYzAtYmVlNC00Y2IzLTlkN2QtZDM5ZmJlNzFmMWM5L0dJNjQwMDBfZnJvbnQucG5nIl0sWyJwIiwicHJldmlld3MiLDIwLCJyb3lhbCBibHVlIix7InBvc2l0aW9uX3giOjM2LCJwb3NpdGlvbl95IjoxLCJ3aWR0aCI6NjIsImhlaWdodCI6NjIsImRlc2lnbl91cmwiOiJodHRwczovL3RlZXppbHktcGx1cy5zMy5hbWF6b25hd3MuY29tL3VwbG9hZHMvZGVzaWduL3BpY3R1cmUvMzM3Ny9pbWFnZS0xMjAweDE2MDAuanBnIn1dXQ/GI64000_front.png?sha=989266d5133de145

But I can’t upload it to Woocommerce by the Product API update

I found in the code the issue the image is downloaded by wp_safe_remote_get from WordPress. But this methode think my URL is not safe.

Why is not safe ?
Can i add some whitlist system to avoid considere this URL like unsafe ?

Related posts

3 comments

  1. The WordPress code seems to do a same-host check on urls that are fetched using wp_safe_remote_get().

    Here’s the source: https://github.com/WordPress/WordPress/blob/c73a812109e1a64ecf21b6a198f949c58d1f2674/wp-includes/http.php

    The significant part is the wp_http_validate_url function, and in particular lines 524-530, which are here:

    $parsed_home = @parse_url( get_option( 'home' ) );
    if ( isset( $parsed_home['host'] ) ) { 
        $same_host = ( strtolower( $parsed_home['host'] ) === strtolower( $parsed_url['host'] ) || 'localhost' === strtolower( $parsed_url['host'] ) );
    } else {
        $same_host = false;
    }
    

    If $same_host is false, the method treats the url as not safe.

    There’s no whitelist that I can see. You’d probably need to edit the code to use wp_remote_get() if you want to avoid the problem.

    UPDATE: the preceding argument is wrong. The code returns the url even if the host is not the same as long as the port is normal.

  2. If the host of the URL contains one of the following symbols, the URL will be rejected: :#?[]

    Try removing ?sha=989266d5133de145 if without this image can be retrieved
    .

  3. I’ve been try to upload your image on live server, I use woocommerce v3 API approach, and all is working fine. Maybe you need to re-check your apps function, your server, firewall, increase your timeout http, etc, And the issue may come from image server.

    https://github.com/woothemes/woocommerce/blob/master/includes/api/class-wc-api-products.php#L2333

    protected function upload_image_from_url( $image_url, $upload_for = 'product_image' ) {
            $file_name  = basename( current( explode( '?', $image_url ) ) );
            $wp_filetype    = wp_check_filetype( $file_name, null );
            $parsed_url     = @parse_url( $image_url );
            // Check parsed URL.
            if ( ! $parsed_url || ! is_array( $parsed_url ) ) {
                throw new WC_API_Exception( 'woocommerce_api_invalid_' . $upload_for, sprintf( __( 'Invalid URL %s', 'woocommerce' ), $image_url ), 400 );
            }
            // Ensure url is valid.
            $image_url = str_replace( ' ', '%20', $image_url );
            // Get the file.
            $response = wp_safe_remote_get( $image_url, array(
                'timeout' => 10
            ) );
            if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
                throw new WC_API_Exception( 'woocommerce_api_invalid_remote_' . $upload_for, sprintf( __( 'Error getting remote image %s', 'woocommerce' ), $image_url ), 400 );
            }
    ...
    

    As your issue wp_safe_remote_get that you get from, we can tweaking those function in out just to test wp_safe_remote_get to upload image by url.

    and here the response header of your image by wp_safe_remote_get

    Array
    (
        [headers] => Array
            (
                [content-disposition] => filename="GI64000_front.png"
                [content-length] => 934080
                [content-type] => image/png
                [etag] => "6f19381f5b2ae0657f6e7945d7ca4bac05e3ad3a"
                [server] => nginx
                [expires] => Mon, 20 Mar 2017 19:20:54 GMT
                [last-modified] => Sun, 20 Mar 2016 19:20:54 GMT
                [connection] => close
                [date] => Wed, 23 Mar 2016 00:19:28 GMT
                [content-encoding] => gzip
            )
    
        [body] => �PNG
    ... I skip this part ...
    
    [response] => Array
            (
                [code] => 200
                [message] => OK
            )
    
        [cookies] => Array
            (
            )
    
        [filename] => 
    )
    

Comments are closed.