-3

Via curl from url i getting some info and i need to check if it is an image.

$result = curl_exec($ch);

UPDATE: Content-type checking is not a good idea, because it can be faked.

user1564141
  • 5,911
  • 5
  • 21
  • 18

7 Answers7

3

I would personally use gd tools within PHP to check if its an image or not. You cannot trust that the source gives the right MIME within the header. More than once I have trusted the headers and been disappionted by the fact that the content was an image but was transferred (due to the way the url/server works) over another format.

Sammaye
  • 43,242
  • 7
  • 104
  • 146
  • Yap, you unly one who understood this question. – user1564141 Jul 31 '12 at 10:56
  • @user1564141 Indeed, also Alexander does, hes actually got a code sample for you. – Sammaye Jul 31 '12 at 10:57
  • Yes, but i working with curl and so i need to check its result. – user1564141 Jul 31 '12 at 11:04
  • @user1564141 Ah yea that has to take a URL which is annoying, you can use `imagecreatefromstring` http://php.net/manual/en/function.imagecreatefromstring.php as a replacement – Sammaye Jul 31 '12 at 11:07
  • @verisimilitude This is not a security issue. If you have security concerns about the content type header, you equally should have security concerns about the content itself. – Oswald Jul 31 '12 at 11:35
  • Ok. deleted my comment. above. – verisimilitude Jul 31 '12 at 12:51
  • @verisimilitude and @oswald This is a security issue. Content-type is not authoritive and can be manipulated by the user. Imagine an upload form which allows the grabbing of remote URLs (which many do). The user ups a server with a path of `g.png` which actually points to `g.php` but gives a content-type of `image/png` but it actually downloads a PHP script to your server. If you rely only on the content-type you will download that script and when previewing the image, potentially run it on your server and so the user could gain access to running PHP scripts on your server. – Sammaye Aug 01 '12 at 07:19
  • @Oswald and @verisimilitude `imagecreatefromstring` prevents this by validating the content you receive from the URL. If it cannot form an image from the content it will return false. As such you should ditch the URL. Of course you should use more complex validation but that is the first step to validating content from other servers. – Sammaye Aug 01 '12 at 07:22
  • @Sammaye The security issue is somewhere else: not taking adequate precautions that the webserver never executes the file. PHP code can be embedded into perfectly valid images. In this case, `imagecreatefromstring` would not fail and does not prevent anything. – Oswald Aug 01 '12 at 18:21
  • @Oswald Yes I know of the gif exploit that is why I said it was the first step. – Sammaye Aug 01 '12 at 18:43
2
function getContentType($url)
{
    $curl = curl_init();
    curl_setopt_array( $curl, array(
    CURLOPT_HEADER => true,
    CURLOPT_NOBODY => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_URL => $url ) );

    curl_exec( $curl ); //execute
    $contentType = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);  //get content type
    curl_close( $curl );

    return $contentType;
}

The above function will return you the type and then u can check for substring image in value returned

Uttara
  • 2,496
  • 3
  • 24
  • 35
  • 2
    that's a quite bad url encoding practice – Karoly Horvath Jul 31 '12 at 10:50
  • but what to do in case if an url is already encoded (i.e it contains %2B or %20) and it also includes chars like (" " and "+") which needs to be encoded. In that case using urlencode results in bad url i.e it will encode "%".. any idea what to do in that case – Uttara Jul 31 '12 at 10:58
  • @Uttara I believe urlencode works a lot like htmlentities to detect special characters within the URL that could pose a problem is left unsanistised. As such if the url is already encoded it will not encode it again. You are correct that complications could arise if you use a difficult URL but you will have to manually make cases and exceptions for those specific URLs. – Sammaye Jul 31 '12 at 11:24
0

I guess one way would be to read the HTTP-headers, especially the Content-type header, and evaluate whether it is an image or not.

This SO question discuss how to check http headers using curl.

Community
  • 1
  • 1
Christofer Eliasson
  • 32,939
  • 7
  • 74
  • 103
0

Use this to get the MIME type.

echo curl_getinfo($ch, CURLINFO_CONTENT_TYPE);

and use it against common image mime types viz. image/gif, image/png, etc.

verisimilitude
  • 5,077
  • 3
  • 30
  • 35
0
  1. Include the HTTP header in the output by setting CURLOPT_HEADER via curl_setopt.
  2. Parse the header, e.g using http_parse_headers.
  3. Check whether the content-type header field indicates an image type.

You might also want to set the request method to HEAD by setting CURLOPT_NOBODY if you are only interested in the content type.

Oswald
  • 31,254
  • 3
  • 43
  • 68
0
    $c = curl_init();

    curl_setopt( $c, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $c, CURLOPT_CUSTOMREQUEST, 'HEAD' );
    curl_setopt( $c, CURLOPT_HEADER, 1 );
    curl_setopt( $c, CURLOPT_NOBODY, true );
    curl_setopt( $c, CURLOPT_URL, 'your.url' );

    curl_exec($c);

    $content_type = curl_getinfo($c, CURLINFO_CONTENT_TYPE);

And check for allowed content-type.

-1

You can use getimagesize

<?php
    $i = getimagesize('http://static.adzerk.net/Advertisers/bd294ce7ff4c43b6aad4aa4169fb819b.jpg');
    print_r($i);

Output

Array
(
    [0] => 220
    [1] => 250
    [2] => 2
    [3] => width="220" height="250"
    [bits] => 8
    [channels] => 3
    [mime] => image/jpeg
)

In case its not image you'll get false

$i = getimagesize('http://stackoverflow.com');
var_dump($i);

Output:

bool(false)
Alexander Larikov
  • 2,328
  • 15
  • 15