【问题标题】:Escaping Shell echos逃避壳牌回声
【发布时间】:2011-07-01 15:28:42
【问题描述】:

我试着做我的研究,有很多方法可以调用 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(&lt;br&gt;'s &lt;b&gt;'s 等),其中还包含一些 $_POST 变量。我使用 PHP 5.3,所以没有魔术引号。

我知道使用 echo 是一种可怕的方式,这就是我来 stackoverflow 的原因。我的目标是尽管他们向我抛出任何疯狂的角色,但电子邮件仍将通过。我知道 shell/bash 很挑剔——我认为它不仅仅是转义双引号。

我尝试使用 escapeshellcmd escapeshellarghtmlentities,它们都逃逸太多或弄乱了电子邮件中的 HTML。

【问题讨论】:

    标签: php shell escaping command exec


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      PHP 使用的是 Bourne shell (sh) 还是 Bash?无论哪种情况,使用printf 可能会更好:

      exec("printf '%s' '$Email' | msmtp --account=$Account $To");
      

      如果你使用的是 Bash,可以试试它的 printf 的引用功能:

      exec("printf '%q' '$Email' | msmtp --account=$Account $To");
      

      【讨论】:

      • 这似乎是过度引用,使\n 变成\\n 等等。
      • @BHare:第一个呢?
      猜你喜欢
      • 2016-07-14
      • 2022-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-14
      • 2011-06-05
      • 2011-03-10
      • 1970-01-01
      相关资源
      最近更新 更多