PHP Python dizeleri kaçmak için en iyi yolu nedir?

5 Cevap php

Ben çıkış için daha özel bir python komut dosyası, örneğin, değişken atama ifadeleri, bir demet ihtiyacı bir PHP uygulama var.

subject_prefix = 'This String From User Input'
msg_footer = """This one too."""

Subject_prefix ark içeriği kullanıcı girişi almak için yazılmış olması gerekir; gibi, ben dizeleri içeriğini kaçmak gerekir. Aşağıdaki gibi bir şey yazmaya onu kesmek için gitmiyor; Biz en kısa sürede birisi ben farkında değilim, bir teklif veya yeni satır ya da başka bir şey tehlikeli olabilir kullanır gibi doldurulmuş konum:

echo "subject_prefix = '".$subject_prefix."'\n";

Yani. Herhangi bir fikir?

(Python uygulaması yeniden yazma zaman kısıtlamaları nedeniyle mümkün değildir:. P)

Edit, years later:

Bu (Python ile yazılmış) bir (PHP ile yazılmış) web uygulaması ve Mailman arasında entegrasyon oldu. Ben ikincisinin yüklemek değiştirmek değil, bu yüzden ben onun yapılandırmasını yönetmek için kendi dilinde konuşmak için bir yol ile gelip gerekli.

Bu aynı zamanda bir really kötü bir fikirdi.

5 Cevap

Do not PHP bu işlev yazmak deneyin. Kaçınılmaz Yanlış alacak ve uygulama kaçınılmaz bir keyfi uzaktan yürütme istismar olacaktır.

İlk olarak, aslında çözme ne problem düşünün. Ben sadece PHP Python veri almak için çalışıyoruz sanırım. Bir. Ini dosyası yerine bir. Py dosyası yazmak için deneyebilirsiniz. Python mükemmel ini sözdizimi ayrıştırıcı var, ConfigParser. Sen bariz yazabilirsiniz, ve (okuyun: ne zaman) eğer PHP ve ciddi hiçbir şey potansiyel yanlış, alıntı işlevi olur onu yanlış anlamayın.

Ayrıca bir XML dosyası yazabilirsiniz. Beni bile burada listelemek için PHP ve Python için çok sayıda XML ayrıştırıcıları ve yayıcılar vardır.

I really Bu bir terrible, terrible fikir olduğuna sizi ikna edemiyorsanız, o zaman en azından böyle bir şeyi yapmak için Python sahip önceden varolan işlevini kullanabilirsiniz: {[( 2)]}.

İşte sizin için bunu yapmak için bir Python komut dosyasını çalıştırmak kullanışlı bir PHP fonksiyonu var:

<?php

function py_escape($input) {
    $descriptorspec = array(
        0 => array("pipe", "r"),
        1 => array("pipe", "w")
        );
    $process = proc_open(
        "python -c 'import sys; sys.stdout.write(repr(sys.stdin.read()))'",
        $descriptorspec, $pipes);
    fwrite($pipes[0], $input);
    fclose($pipes[0]);
    $chunk_size = 8192;
    $escaped = fread($pipes[1], $chunk_size);
    if (strlen($escaped) == $chunk_size) {
        // This is important for security.
        die("That string's too big.\n");
    }
    proc_close($process);
    return $escaped;
}

// Example usage:
$x = "string \rfull \nof\t crappy stuff";
print py_escape($x);

chunk_size kontrol, giriş sırasıyla ("hello " + ("." * chunk_size)) ve '; os.system("do bad stuff") gibi görünüyorsun iki gerçekten uzun dizeler, olmak biter sayede bir saldırıyı önlemek için tasarlanmıştır. Şimdi, Python bir satırın ortasında tek tırnaklı dize sonunda izin vermez, çünkü o naif saldırı, tam olarak çalışmaz, ve system() çağrısında alıntılar kendilerini alıntı olacak, ama eğer Saldırgan doğru yere bir çizgi devamında ("\") almak ve os.system(map(chr, ...)) sonra koşacaklar bazı kod enjekte edebilir gibi bir şey kullanmak için yönetir.

Ben sadece tek bir parça okumak ve oldukça okumak ve birikmesine devam daha fazla çıkış, olsaydı Python kaynak dosyası hat uzunluğuna sınırları da vardır çünkü, vazgeçmek için seçti; bütün bildiğim için, o başka bir saldırı vektörü olabilir. Python bu nedenle bu alanda denetlenecek düşüktür sisteminizde keyfi kaynak kodu yazma keyfi insanlara karşı güvenli olması amaçlanmıştır değildir.

Ben bu önemsiz, örneğin bütün bu düşünmek zorunda olması bir veri değişim biçimi olarak python kaynak kodu kullanmak gerekir neden bir başka örnektir.

Ben ("" ") üçlü tırnakla kullanmak için, Python kullanan bir dize türü standardize ederek başlamak istiyorum. Bu giriş başıboş tırnak gelen sorunların olaylarını azaltmak gerekir. Hala kaçmak gerekir Tabii ki, ancak bir endişe vardır sorunların sayısını azaltmak gerekir.

Ben dizeleri kaçmak için ne yaptığını biraz ben kaymış ve yine çıktı alıyorsanız bağlam alma endişeleniyorum ne bağlı olacaktır. Eğer sorunlara neden tırnak hakkında sadece endişeli iseniz ben girdi kendisi hakkında endişeli, kötü niyetli olmak (ve kullanıcı girişi yüzden muhtemelen gerekir eğer, sadece diğer taraftan. Kontrol ve olaylar "" "ve onları kaçabilir ), sonra strip_tags () veya diğer benzer işlevleri gibi seçenekleri olmazdı.

Başka bir seçenek JSON dizesi olarak dizi veya nesne olarak veri ihracat ve yeni giriş işlemek için biraz python kodunu değiştirmek olabilir. JSON yoluyla kaçan% 100 kurşun olmasa da yine de kaçan rutinleri sahibi daha iyi olacaktır.

Ve JSON dize malformatted ise hataları işlemek mümkün olacak.

python-json 3.4: JSON kodlamak ve kodunu çözmek için Python için bir paket var

I python escaping kullandığı "ntriples" biçiminde bir dize kaçmak için bu kod gerekli.

The following function takes a utf-8 string and returns it escaped for python (or ntriples format). It may do odd things if given illegal utf-8 data. It doesn't understand about Unicode characters past xFFFF. It does not (currently) wrap the string in double quotes.

Uniord fonksiyon php.net bir açıklama geliyor.

    function python_string_escape( $string )
    {
            $string = preg_replace( "/\\\\/", "\\\\", $string ); # \\ (first to avoid string re-escaping)
            $string = preg_replace( "/\n/", "\\n", $string ); # \n
            $string = preg_replace( "/\r/", "\\r", $string ); # \r 
            $string = preg_replace( "/\t/", "\\t", $string ); # \t 
            $string = preg_replace( "/\"/", "\\\"", $string ); # \"
            $string = preg_replace(
                            "/([\x{00}-\x{1F}]|[\x{7F}-\x{FFFF}])/ue",
                            "sprintf(\"\\u%04X\",uniord(\"$1\"))",
                            $string );
            return $string;
    }

    function uniord($c) {
            $h = ord($c{0});
            if ($h <= 0x7F) {
                    return $h;
            } else if ($h < 0xC2) {
                    return false;
            } else if ($h <= 0xDF) {
                    return ($h & 0x1F) << 6 | (ord($c{1}) & 0x3F);
            } else if ($h <= 0xEF) {
                    return ($h & 0x0F) << 12 | (ord($c{1}) & 0x3F) << 6
                                             | (ord($c{2}) & 0x3F);
            } else if ($h <= 0xF4) {
                    return ($h & 0x0F) << 18 | (ord($c{1}) & 0x3F) << 12
                                             | (ord($c{2}) & 0x3F) << 6
                                             | (ord($c{3}) & 0x3F);
            } else {
                    return false;
            }
    }

Ben iki argüman alacak bir işlevi yazma öneririz: tırnak tipi tek tırnak ise kaçtı edilecek metin ve dizesi inç Sonra bir tırnak tipi, örneğin, işlev dize tek tırnak kaçış olacak ve (ters bölü?) kaçtı gereken herhangi bir diğer karakterler.

function escape_string($text, $type) {
    // Escape backslashes for all types of strings?
    $text = str_replace('\\', '\\\\', $text);

    switch($type) {
        case 'single':
            $text = str_replace("'", "\\'", $text);
            break;
        case 'double':
            $text = str_replace('"', '\\"', $text);
            break;
        // etc...
    }

    return $text;
}

Ben tek tırnaklı dizeleri sizin için tek tırnak kaçmak istediğiniz varsayarak yaşıyorum, ve çift tırnaklı dizeleri ile çift tırnak kaçmak istiyorum ...