1. ホーム
  2. php

[解決済み] 文字列をサニタイズして、URLやファイル名を安全にする?

2022-05-25 02:58:47

質問

私は、特定の文字列をサニタイズして、URL (投稿スラッグ) で使用しても安全で、ファイル名として使用しても安全なようにする関数を考え出そうとしています。たとえば、誰かがファイルをアップロードするとき、名前からすべての危険な文字を削除することを確認したいのです。

今のところ、私はこの問題を解決し、外国の 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');
}

誰かこれに対して実行できるトリッキーなサンプルデータを持っていませんか? - あるいは、アプリを悪い名前から保護するもっと良い方法を知っていますか?

is-filename は vim の一時ファイルのようないくつかの追加文字を許可します。

update: 有効な使い道が思いつかなかったので、星印の文字を削除しました。

どのように解決するのですか?

あなたの解決策について、いくつか意見を聞かせてください。

  1. パターンの末尾にある 'u' は パターン を意味し、マッチするテキストは UTF-8 として解釈されることを意味します (後者を想定しているのでしょうか?)。
  2. \はアンダースコア文字にマッチします。ファイルに対して特別にそれを含んでいるので、URL にそれらを望まないという仮定につながりますが、あなたが持っているコードでは、URL はアンダースコアを含むことが許可されます。
  3. foreign UTF-8" を含めることは、ロケールに依存するようです。これがサーバーのロケールなのか、クライアントのロケールなのかは明らかではありません。PHP のドキュメントから。

word" 文字とは、文字、数字、アンダースコア、つまり Perl の "word" の一部となり得る文字のことです。文字と数字の定義は PCRE の文字テーブルによって制御され、ロケール固有のマッチングが行われる場合は異なる場合があります。例えば、"fr" (フランス語) ロケールでは、アクセント付きの文字に 128 より大きな文字コードが使用され、これらは \w によってマッチングされます。

スラッグの作成

投稿のスラッグにアクセント記号付きの文字などを含めるべきではありません。技術的には、パーセントエンコード(URL エンコードの規則による)されるべきなので、見苦しい URL になってしまうからです。

私だったら、小文字にした後、「特殊」文字を同等の文字に変換し (例: é -> e)、「a-z」以外の文字を「-」に置き換え、あなたが行ったように「-」を 1 つだけ使用することに制限します。特殊文字を変換する実装はこちらにあります。 https://web.archive.org/web/20130208144021/http://neo22s.com/slug

一般的な除菌

OWASPはEnterprise Security APIをPHPで実装しており、アプリケーションの入出力を安全にエンコード、デコードするためのメソッドなどが含まれています。

Encoder インターフェースは、以下のものを提供します。

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