逃离壳回声

时间:2011-02-21 23:32:23

标签: php shell escaping command exec

我尝试进行我的研究,只有很多方法可以调用shell命令,还有更多方法来删除有害字符,我将以stackoverflow的形式获取专家的最佳建议。

我希望找到像我见过的其他语言,所以发送命令的参数实际上是通过一个函数传递的,比如:

do_command(“ls”,“ - l”,$ Directory);

它将为您处理$ Directory变量中的任何有害内容。我还没有用PHP发现这个。

这是我正在使用的代码:

<?php
    session_start();

    $AdminEmail = "random_email@gmail.com";
    $CatalogEmails = array("");
    $QuoteEmails = array("");
    $PartsEmails = array("");

    $Subject = $_SESSION['Email_Subject'];
    $Body = $_SESSION['Email_Body'];
    $Headers = $_SESSION['Email_Headers'];
    $Type = $_SESSION['Type'];

    msmtp($AdminEmail, $Subject, $Body, $Headers, "meyers");

    if ($Type == "Catalog") {
        foreach ($CatalogEmails as $AdditionalEmail) {
            msmtp($AdditionalEmail, $Subject, $Body, $Headers, "meyers");
        }
    } else if ($Type == "Quote") {
        foreach ($QuoteEmails as $AdditionalEmail) {
            msmtp($AdditionalEmail, $Subject, $Body, $Headers, "meyers");
        }
    } else if ($Type == "Parts") {
        foreach ($PartsEmails as $AdditionalEmail) {
            msmtp($AdditionalEmail, $Subject, $Body, $Headers, "meyers");
        }
    }

    function msmtp($To, $Subject, $Body, $Headers, $Account) {
        $Email = "To: $To\nSubject: $Subject\n$Headers\n\n$Body\n";
        exec("echo \"$Email\" | msmtp --account=$Account $To");
    }

    session_destroy();
?>

我知道有一个内置的PHP邮件功能几乎可以解决这个问题,但是我正在运行多个SMTP服务器而msmtp是我使用的程序,它根据“帐户”发送电子邮件“电子邮件将在以下发送。在这种情况下,它将是“meyers”帐户。

所有会话变量都包含HTML(<br>的{​​{1}}等),其中也包含一些<b>个变量。我使用PHP 5.3所以没有神奇的引用。

我知道使用echo是一种可怕的方式,这就是我要进行stackoverflow的原因。我的目标是,尽管他们向我投掷任何疯狂的角色,但电子邮件仍将通过。我知道shell / bash是挑剔的 - 我认为它不仅仅是逃避双引号。

我尝试使用$_POST escapeshellcmdescapeshellarg,他们都逃脱了太多或弄乱了电子邮件中的HTML。

2 个答案:

答案 0 :(得分:2)

将电子邮件内容写入文件,然后将文件内容重定向为msmtp命令的输入。

file_put_contents($tempfile,$Email);
exec("msmtp --account=$Account $To < $tempfile");

答案 1 :(得分:1)

PHP是使用Bourne shell(sh)还是Bash?在任何一种情况下,如果您使用printf

可能会更好
exec("printf '%s' '$Email' | msmtp --account=$Account $To");

如果您使用的是Bash,则可以尝试其printf

的引用功能
exec("printf '%q' '$Email' | msmtp --account=$Account $To");