转义Shell回显

4

我试着进行了研究,但是有很多方法可以调用shell命令,还有更多的方法可以去除有害字符,所以我来到stackoverflow寻求专家最好的建议。

我希望能找到类似其他语言的方式,将参数传递给命令时实际上通过函数传递,例如:

do_command("ls", "-l", $目录);

它会为您处理$目录变量中的任何有害内容。不过我在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><b>等),其中还有一些$_POST变量。我使用的是PHP 5.3,所以没有魔术引号。

我知道使用echo是可怕的方式,这就是为什么我来到stackoverflow的原因。我的目标是确保邮件能够通过,无论他们向我扔什么样的字符。我知道shell/bash很挑剔——我认为它不仅仅是转义双引号。

我尝试使用escapeshellcmdescapeshellarghtmlentities,它们都会转义太多或破坏邮件中的HTML。

2个回答

2
将电子邮件的内容写入文件,然后将文件内容重定向为msmtp命令的输入。
file_put_contents($tempfile,$Email);
exec("msmtp --account=$Account $To < $tempfile");

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");

似乎过于引用,导致\n变成了\\n等等。 - ParoX
@BHare:第一个怎么样? - Dennis Williamson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接