如何处理字符串以使URL和文件名安全吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (35)

我试图想出一个功能,对某些字符串进行消毒处理,以便它们可以安全地在URL中使用(比如post slug),并且可以安全地用作文件名。例如,当有人上传文件时,我想确保从名称中删除所有危险字符。

到目前为止,我已经提出了以下函数,我希望能够解决这个问题,并允许使用外部UTF-8数据。

/**
 * Convert a string to the file/URL safe "slug" form
 *
 * @param string $string the string to clean
 * @param bool $is_filename TRUE will allow additional filename characters
 * @return string
 */
function sanitize($string = '', $is_filename = FALSE)
{
 // Replace all weird characters with dashes
 $string = preg_replace('/[^\w\-'. ($is_filename ? '~_\.' : ''). ']+/u', '-', $string);

 // Only allow one dash separator at a time (and make string lowercase)
 return mb_strtolower(preg_replace('/--+/u', '-', $string), 'UTF-8');
}

有没有人有任何棘手的示例数据,我可以对此运行 - 或知道更好的方法来保护我们的应用程序不受恶名的影响?

提问于
用户回答回答于

对你的解决方案的一些观察

  1. 'u'在模式结尾意味着该模式,而不是它匹配的文本将被解释为UTF-8(我认为你假设后者?)。
  2. \ w匹配下划线字符。你明确地将它包含在文件中,这会导致你不希望它们在URL中被使用,但是在你有URL的代码中将被允许包含一个下划线。
  3. 包含“外国UTF-8”似乎是由地区决定的。目前还不清楚这是否是服务器或客户端的语言环境。从PHP文档:

“单词”字符是任何字母或数字或下划线字符,即任何可以成为Perl“单词”一部分的字符。字母和数字的定义由PCRE的字符表控制,并且如果发生特定于语言环境的匹配,则可能会有所不同。例如,在“fr”(法语)语言环境中,一些大于128的字符代码用于重音字母,并且这些符号由\ w匹配。

创建slu。

你可能不应该在你的帖子中包含重音等字符,因为从技术上讲,它们应该被百分比编码(每个URL编码规则),所以你会看到丑陋的URL。

所以,如果我是你,在压缩之后,我会将任何'特殊'字符转换为它们的等效字符(例如é - > e),并用' - '替换非[az]字符,限制为运行单个' - '正如你所做的那样。这里有一个转换特殊字符的实现:https//web.archive.org/web/20130208144021/http : //neo22s.com/slug

OWASP拥有其企业安全API的PHP实现,其中包括在应用程序中安全编码和解码输入和输出的方法。

编码器接口提供:

canonicalize (string $input, [bool $strict = true])
decodeFromBase64 (string $input)
decodeFromURL (string $input)
encodeForBase64 (string $input, [bool $wrap = false])
encodeForCSS (string $input)
encodeForHTML (string $input)
encodeForHTMLAttribute (string $input)
encodeForJavaScript (string $input)
encodeForOS (Codec $codec, string $input)
encodeForSQL (Codec $codec, string $input)
encodeForURL (string $input)
encodeForVBScript (string $input)
encodeForXML (string $input)
encodeForXMLAttribute (string $input)
encodeForXPath (string $input)

https://github.com/OWASP/PHP-ESAPI https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API

用户回答回答于

/**
 * Function: sanitize
 * Returns a sanitized string, typically for URLs.
 *
 * Parameters:
 *     $string - The string to sanitize.
 *     $force_lowercase - Force the string to lowercase?
 *     $anal - If set to *true*, will remove all non-alphanumeric characters.
 */
function sanitize($string, $force_lowercase = true, $anal = false) {
    $strip = array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]",
                   "}", "\\", "|", ";", ":", "\"", "'", "‘", "’", "“", "”", "–", "—",
                   "—", "–", ",", "<", ".", ">", "/", "?");
    $clean = trim(str_replace($strip, "", strip_tags($string)));
    $clean = preg_replace('/\s+/', "-", $clean);
    $clean = ($anal) ? preg_replace("/[^a-zA-Z0-9]/", "", $clean) : $clean ;
    return ($force_lowercase) ?
        (function_exists('mb_strtolower')) ?
            mb_strtolower($clean, 'UTF-8') :
            strtolower($clean) :
        $clean;
}

而这个在WordPress代码

/**
 * Sanitizes a filename replacing whitespace with dashes
 *
 * Removes special characters that are illegal in filenames on certain
 * operating systems and special characters requiring special escaping
 * to manipulate at the command line. Replaces spaces and consecutive
 * dashes with a single dash. Trim period, dash and underscore from beginning
 * and end of filename.
 *
 * @since 2.1.0
 *
 * @param string $filename The filename to be sanitized
 * @return string The sanitized filename
 */
function sanitize_file_name( $filename ) {
    $filename_raw = $filename;
    $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}");
    $special_chars = apply_filters('sanitize_file_name_chars', $special_chars, $filename_raw);
    $filename = str_replace($special_chars, '', $filename);
    $filename = preg_replace('/[\s-]+/', '-', $filename);
    $filename = trim($filename, '.-_');
    return apply_filters('sanitize_file_name', $filename, $filename_raw);
}

扫码关注云+社区