ユーザーは信頼できません。信頼できないユーザーの入力は決して信用しないでください。わかりました。ただし、入力をサニタイズするのに最適な時期はいつかと思います。たとえば、ユーザー入力をやみくもに保存し、アクセス/使用されるたびにサニタイズしますか?それとも、入力をすぐにサニタイズしてから、この「クリーンな」バージョンを保存しますか? これらに加えて、私が考えていない他のアプローチもいくつかあるかもしれません。私は最初の方法にもっと傾いています。なぜなら、ユーザー入力から得られたデータにはまだ慎重にアプローチする必要があり、「クリーンアップされた」データが知らないうちに、または偶然に危険である可能性があるからです。いずれにせよ、人々はどの方法が最善だと考えていますか? また、その理由は何ですか?
14 に答える
つまり、ユーザーが無効なデータを入力しようとしたときにサニタイズが行われます。年齢用の TextBox があり、数字以外を入力する場合は、文字のキーを押しません。
次に、データを読み取っているもの (多くの場合サーバー) が何であれ、データを読み取るときにサニティ チェックを行います。これは、より決定的なユーザー (手動でファイルを編集したり、パケットを変更したりするなど) が原因で何もスリップしていないことを確認するためです。 !)
編集:全体として、早めにサニタイズし、データを見失ったときはいつでもサニタイズしてください(例:ファイル保存 - >ファイルを開く)
I sanitize my user data much like Radu...
First client-side using both regex's and taking control over allowable characters input into given form fields using javascript or jQuery tied to events, such as onChange or OnBlur, which removes any disallowed input before it can even be submitted. Realize however, that this really only has the effect of letting those users in the know, that the data is going to be checked server-side as well. It's more a warning than any actual protection.
Second, and I rarely see this done these days anymore, that the first check being done server-side is to check the location of where the form is being submitted from. By only allowing form submission from a page that you have designated as a valid location, you can kill the script BEFORE you have even read in any data. Granted, that in itself is insufficient, as a good hacker with their own server can 'spoof' both the domain and the IP address to make it appear to your script that it is coming from a valid form location.
Next, and I shouldn't even have to say this, but always, and I mean ALWAYS, run your scripts in taint mode. This forces you to not get lazy, and to be diligent about step number 4.
Sanitize the user data as soon as possible using well-formed regexes appropriate to the data that is expected from any given field on the form. Don't take shortcuts like the infamous 'magic horn of the unicorn' to blow through your taint checks... or you may as well just turn off taint checking in the first place for all the good it will do for your security. That's like giving a psychopath a sharp knife, bearing your throat, and saying 'You really won't hurt me with that will you".
And here is where I differ than most others in this fourth step, as I only sanitize the user data that I am going to actually USE in a way that may present a security risk, such as any system calls, assignments to other variables, or any writing to store data. If I am only using the data input by a user to make a comparison to data I have stored on the system myself (therefore knowing that data of my own is safe), then I don't bother to sanitize the user data, as I am never going to us it a way that presents itself as a security problem. For instance, take a username input as an example. I use the username input by the user only to check it against a match in my database, and if true, after that I use the data from the database to perform all other functions I might call for it in the script, knowing it is safe, and never use the users data again after that.
Last, is to filter out all the attempted auto-submits by robots these days, with a 'human authentication' system, such as Captcha. This is important enough these days that I took the time to write my own 'human authentication' schema that uses photos and an input for the 'human' to enter what they see in the picture. I did this because I've found that Captcha type systems really annoy users (you can tell by their squinted-up eyes from trying to decipher the distorted letters... usually over and over again). This is especially important for scripts that use either SendMail or SMTP for email, as these are favorites for your hungry spam-bots.
To wrap it up in a nutshell, I'll explain it as I do to my wife... your server is like a popular nightclub, and the more bouncers you have, the less trouble you are likely to have in the nightclub. I have two bouncers outside the door (client-side validation and human authentication), one bouncer right inside the door (checking for valid form submission location... 'Is that really you on this ID'), and several more bouncers in close proximity to the door (running taint mode and using good regexes to check the user data).
I know this is an older post, but I felt it important enough for anyone that may read it after my visit here to realize their is no 'magic bullet' when it comes to security, and it takes all these working in conjuction with one another to make your user-provided data secure. Just using one or two of these methods alone is practically worthless, as their power only exists when they all team together.
Or in summary, as my Mum would often say... 'Better safe than sorry".
UPDATE:
One more thing I am doing these days, is Base64 encoding all my data, and then encrypting the Base64 data that will reside on my SQL Databases. It takes about a third more total bytes to store it this way, but the security benefits outweigh the extra size of the data in my opinion.
それはあなたがどんな種類の消毒をしているのかによります。
SQLインジェクションから保護するために、データ自体には何もしないでください。プリペアドステートメントを使用するだけで、ユーザーが入力したデータをいじったり、ロジックに悪影響を及ぼしたりすることを心配する必要はありません。すべてがリクエストからの文字列であるため、数字が数字で日付が日付であることを確認するために、少しサニタイズする必要がありますが、ブロックキーワードなどを行うためのチェックは行わないでください。
XSS攻撃から保護するために、データを保存する前にデータを修正する方がおそらく簡単でしょう。ただし、他の人が述べたように、ユーザーが入力した内容を正確にコピーしておくと便利な場合があります。これを変更すると、永久に失われるためです。準備されたクエリを使用してSQLインジェクションに巻き込まれないようにする方法で、アプリケーションがサニタイズされたHTMLのみを出力することを保証する絶対確実な方法がないのはほとんど残念です。
最も重要なことは、逃げるときは常に一貫性を保つことです。誤って二重に消毒することは不自由であり、消毒しないことは危険です。
SQL の場合は、値を自動的にエスケープするバインド変数がデータベース アクセス ライブラリでサポートされていることを確認してください。ユーザー入力を手動で SQL 文字列に連結する人は、よく知っているはずです。
HTML の場合、可能な限り最後の瞬間にエスケープすることを好みます。ユーザー入力を破棄すると、元に戻すことはできません。ユーザーが間違いを犯した場合は、後で編集して修正できます。元の入力を破棄すると、それは永久に失われます。
私の意見は、可能な限りクライアント側とサーバー側でユーザー入力をサニタイズすることです。私はこのようにやっています
- (クライアント側)、ユーザーがフィールドに特定のキーのみを入力できるようにします。
- (クライアント側)、ユーザーが onblur を使用して次のフィールドに移動したときに、入力した入力を正規表現に対してテストし、何か問題がある場合はユーザーに通知します。
- (サーバー側)、入力を再度テストします。フィールドが INTEGER である必要がある場合はそれをチェックします (PHP では is_numeric() を使用できます)。フィールドの形式がよく知られている場合は、正規表現に対してチェックし、その他すべて (テキスト コメントなど)、それらを逃れるだけです。不審な点がある場合は、スクリプトの実行を停止し、ユーザーが入力したデータが無効であるという通知をユーザーに返します。
本当に攻撃の可能性があると思われるものがある場合、スクリプトは私にメールと SMS を送信するので、できるだけ早く確認して防止することができます。すべてのユーザー入力を記録しているログを確認するだけで済みます。入力を受け入れるか拒否する前にスクリプトが行った手順。
解析しようとする前に、早い方が良いです。後で出力するもの、または特に他のコンポーネント (シェル、SQL など) に渡すものはすべてサニタイズする必要があります。
ただし、行き過ぎないでください。たとえば、パスワードは保存する前にハッシュされます (そうですか?)。ハッシュ関数は、任意のバイナリ データを受け入れることができます。また、パスワードを印刷することはありません (そうですか?)。したがって、パスワードを解析したり、サニタイズしたりしないでください。
また、信頼できるプロセスからサニタイズを行っていることを確認してください - JavaScript/クライアント側のものは、役に立たないセキュリティ/整合性よりも悪いです. (ただし、早期に失敗する方がユーザー エクスペリエンスが向上する場合があります。両方の場所で実行してください。)
Perl には、正規表現でチェックされるまで、すべてのユーザー入力を「汚染された」と見なす taint オプションがあります。汚染されたデータを使用して渡すことはできますが、汚染がなくなるまで、接触するすべてのデータを汚染します。たとえば、ユーザー入力が別の文字列に追加された場合、新しい文字列も汚染されます。基本的に、汚染された値を含む式は、汚染された結果を出力します。
汚染されたデータは自由に放り投げることができますが (データを汚染しながら)、外部の世界に影響を与えるコマンドによって使用されるとすぐに、perl スクリプトは失敗します。したがって、汚染されたデータを使用してファイルを作成したり、シェル コマンドを作成したり、作業ディレクトリを変更したりすると、Perl はセキュリティ エラーで失敗します。
「汚染」のようなものがある言語は他に知りませんが、それを使用することは非常に目を見張るものがあります。すぐに汚染を取り除かないと、汚染されたデータがすぐに拡散してしまうのは驚くべきことです。ユーザーデータに基づいて変数を設定したり、ファイルを開いたりするなど、プログラマーにとって自然で通常のことは、汚染がオンになっていると危険でリスクがあるように見えます。したがって、物事を成し遂げるための最善の戦略は、外部からデータを取得したらすぐに汚染を除去することです。
バグやセキュリティ ホールが広がりすぎないように、ユーザー データをすぐに検証することは、他の言語でも最善の方法だと思います。また、潜在的なセキュリティ ホールが 1 か所にある場合は、コードのセキュリティ ホールの監査が容易になるはずです。また、どのデータが後でどのような目的で使用されるかを予測することはできません。
保存する前にデータを消去してください。一般に、最初に入力をクリーンアップせずに SQL アクションを実行するべきではありません。SQL インジェクション攻撃を受けたくありません。
私はこれらの基本的なルールに従っています。
- POST による INSERT、UPDATE、DELETE などの SQL アクションの変更のみを行います。決してGETしないでください。
- すべてをエスケープします。
- ユーザー入力が何かであると予想している場合は、それがその何かであることを確認してください。たとえば、番号を要求している場合は、それが番号であることを確認してください。検証を使用します。
- フィルターを使用します。不要な文字をクリーンアップします。
ユーザーは悪だ!
常にというわけではありませんが、私のアプローチは、常にすぐにサナタイズして、バックエンドの近くに危険なものがないことを確認することです.
追加の利点は、入力の時点でサニタイズすると、ユーザーにフィードバックを提供できることです。
すべてのユーザーが悪意を持っていると仮定します。できるだけ早くすべての入力をサニタイズします。完全停止。
データを処理する直前にデータをサニタイズします。First name フィールドと Last name フィールドを取得して、データベースに挿入される 3 番目のフィールドに連結する必要がある場合があります。連結を行う前に入力をサニタイズして、処理エラーや挿入エラーが発生しないようにします。早いほど良い。フロント エンド (Web セットアップ) で Javascript を使用することも理想的です。
恐ろしいのは、データベースから出てくるデータのサニタイズも開始したい場合があることです。最近急増している ASPRox SQL インジェクション攻撃は、特定のデータベース内のすべてのデータベース テーブルに感染するため、二重に致命的です。同じデータベースで複数のアカウントがホストされている場所にデータベースがホストされている場合、他の誰かのミスによりデータが破損しますが、最初の過失がないため、訪問者にマルウェアをホストするランクに参加しました. .
確かに、これには前もって多くの作業が必要になりますが、データが重要な場合は、投資する価値があります。
ユーザー入力は、アプリケーションの下位レイヤーに入れる前に、常に悪意のあるものとして扱う必要があります。常にサニタイズ入力をできるだけ早く処理し、悪意をチェックする前に何らかの理由でデータベースに保存しないでください。
すぐに掃除することには2つの利点があることがわかりました。1 つは、それに対して検証し、ユーザーにフィードバックを提供できることです。2 つ目は、他の場所でデータを消費することを心配する必要がないことです。