2012-09-30 16 views
17

मैं एक आवेदन POST एचटीएमएल 5 कैनवास डेटा है कि तब बेस 64 में encoded और सभी को दिखाई देता है के लिए अनुमति देता है कि निर्माण कर रहा हूँ। मैं एक वास्तविक .png फ़ाइल में डेटा पार्स करने और सर्वर पर संग्रहीत करने पर विचार कर रहा हूँ, लेकिन बेस 64 मार्ग मुझे एक डेटाबेस में छवियों की दुकान और अनुरोधों को कम करने की अनुमति देता है। छवियां अद्वितीय हैं, कुछ, और पृष्ठ अक्सर ताज़ा नहीं किया जाएगा।सत्यापित किया जा रहा base64 इनकोडिंग छवियों

jQuery का एक सा कैनवास डेटा data:image/png;base64,iVBORw... ले जाएगा, और एक PHP स्क्रिप्ट है कि यह तो जैसे लपेटता के साथ पास कर देता है: <img src="$data"></img>

हालांकि, सुरक्षा आधारशिला है और पासिंग को रोकने के लिए बेस 64 कैनवास डेटा को मान्य करने की जरूरत है POST अनुरोध में दुर्भावनापूर्ण डेटा। मेरे प्राथमिक चिंता का विषय <img> टैग में इंजेक्ट किया जा रहा है और पृष्ठ लोड पर अनुरोध किया जा रहा से बाहरी URL को रोकने के लिए है।

$data = (isset($_POST['canvas']) && is_string($_POST['canvas'])) ? $_POST['canvas'] : null; 
$base = str_replace('data:image/png;base64,', '', $data); 
$regx = '~^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$~' 

if ((substr($data, 0, 22)) !== 'data:image/png;base64,') 
{ 
    // Obviously fake, doesn't contain the expected first 22 characters. 
    return false; 
} 

if ((base64_encode(base64_decode($base64, true))) !== $base64) 
{ 
    // Decoding and re-encoding the data fails, something is wrong 
    return false; 
} 

if ((preg_match($regx, $base64)) !== 1) 
{ 
    // The data doesn't match the regular expression, discard 
    return false; 
} 

return true; 

मुझे यकीन है कि मेरे वर्तमान सेटअप काफी सुरक्षित <img> टैग में डाला जा रहा से बाहरी URL को रोकने के लिए है, और नहीं, क्या किया जा सकता है अगर बनाना चाहते:

मैं वर्तमान में इस तरह एक सेटअप छवि डेटा को आगे सत्यापित करने के लिए? ऐसा करने का

उत्तर

18

एक तरह से वास्तव में, बेस 64 डेटा से एक छवि फ़ाइल बनाने के लिए तो पीएचपी साथ छवि को ही यह सत्यापित किया जाएगा। ऐसा करने का एक आसान तरीका हो सकता है, लेकिन इस तरह से निश्चित रूप से काम करना चाहिए।

ध्यान रखें कि यह केवल वास्तव में PNG का लिए काम करता है, तो आप और अधिक फ़ाइल प्रकारों (GIF, JPG) की अनुमति के बारे में कुछ तर्क अगर आप की योजना बना रहे जोड़ने की आवश्यकता होगी।

<? 

$base64 = "[insert base64 code here]"; 
if (check_base64_image($base64)) { 
    print 'Image!'; 
} else { 
    print 'Not an image!'; 
} 

function check_base64_image($base64) { 
    $img = imagecreatefromstring(base64_decode($base64)); 
    if (!$img) { 
     return false; 
    } 

    imagepng($img, 'tmp.png'); 
    $info = getimagesize('tmp.png'); 

    unlink('tmp.png'); 

    if ($info[0] > 0 && $info[1] > 0 && $info['mime']) { 
     return true; 
    } 

    return false; 
} 

?> 
+0

यह महान काम किया! स्वीकार किए जाते हैं। 'imagepng' फेंक देगा 'आपूर्ति किया गया तर्क मान्य छवि संसाधन नहीं है' यदि छवि डेटा मान्य नहीं है, तो मैंने उस कार्य को 'if' कथन में लपेटने के लिए इसे विफल करने के लिए लपेट लिया है। – ssh2ksh

+0

आप 'imagecreatefrompng ($ बेस 64) का उपयोग कर सकते' अगर रिटर्न फाल्स, न कि चित्र – mghhgm

3
function RetrieveExtension($data){ 
    $imageContents = base64_decode($data); 

    // If its not base64 end processing and return false 
    if ($imageContents === false) { 
     return false; 
    } 

    $validExtensions = ['png', 'jpeg', 'jpg', 'gif']; 

    $tempFile = tmpfile(); 

    fwrite($tempFile, $imageContents); 

    $contentType = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $tempFile); 

    fclose($tempFile); 

    if (substr($contentType, 0, 5) !== 'image') { 
     return false; 
    } 

    $extension = ltrim($contentType, 'image/'); 

    if (!in_array(strtolower($extension), $validExtensions)) { 
     return false; 
    } 

    return $extension; 
} 
2

जब से मैं पर्याप्त अंक टिप्पणी करने की जरूरत नहीं है, मैं thewebguy के कोड का अद्यतन संस्करण पोस्टिंग कर रहा हूँ। यह उन लोगों के लिए है जो हेरोोकू जैसी सेवाओं पर होस्टिंग करते हैं जहां आप छवियों को स्टोर नहीं कर सकते हैं।

पेका (Pekka's answer)

इस कोड को समझती है कि आप से वर्ग और धारा आवरण लागू करने के लिए धारा आवरण उनका कहना है के लिए ऋण: PHP Example on Stream Wrapper

<? 

$base64 = "[insert base64 code here]"; 
if (check_base64_image($base64)) { 
    print 'Image!'; 
} else { 
    print 'Not an image!'; 
} 

function check_base64_image($base64) { 
    $img = imagecreatefromstring(base64_decode($base64)); 
    if (!$img) { 
     return false; 
    } 

    ob_start(); 
    if(!imagepng($img)) { 

     return false; 
    } 
    $imageTemp = ob_get_contents(); 
    ob_end_clean(); 

    // Set a temporary global variable so it can be used as placeholder 
    global $myImage; $myImage = ""; 

    $fp = fopen("var://myImage", "w"); 
    fwrite($fp, $imageTemp); 
    fclose($fp);  

    $info = getimagesize("var://myImage"); 
    unset($myvar); 
    unset($imageTemp); 

    if ($info[0] > 0 && $info[1] > 0 && $info['mime']) { 
     return true; 
    } 

    return false; 
} 

?> 

मुझे आशा है कि यह किसी को मदद मिलती है।

3

यदि आप PHP 5.4+ का उपयोग कर रहे हैं, तो मैंने उपरोक्त संशोधित किया है ताकि थोड़ा और संक्षिप्त हो।

function check_base64_image($data, $valid_mime) { 
    $img = imagecreatefromstring($data); 

    if (!$img) { 
     return false; 
    } 

    $size = getimagesizefromstring($data); 

    if (!$size || $size[0] == 0 || $size[1] == 0 || !$size['mime']) { 
     return false; 
    } 

    return true; 
} 
+3

यह पसंद का मतलब है। नोट्स के जोड़े ... ए) '$ valid_mime'argument अनावश्यक प्रतीत होता है, और बी) इसके लिए जीडी लाइब्रेरी को स्थापित करने की आवश्यकता है - उबंटू पर: 'sudo apt-get php5-gd && sudo service apache2 को पुनरारंभ करें' –

0
$str = 'your base64 code' ; 

if (base64_encode(base64_decode($str, true)) === $str && imagecreatefromstring(base64_decode($img))) { 
    echo 'Success! The String entered match base64_decode and is Image'; 
} 
+4

कृपया अपने समाधान की व्याख्या करें और इसे समझाएं, खासकर जब से सवाल 5 साल का है – Sentry

संबंधित मुद्दे