0

PHP、Appache、およびPHPMyAdminを使用して、かなり基本的なローカルデータベース駆動型のWebサイトをまとめました。このサイトでは、ユーザーはCAD詳細ファイルを2つの形式でアップロードできます。ファイルパスに加えて、ファイルの名前、関連するサービスグル​​ープ、および詳細IDをアップロードすることもできます。

アップロードページからファイルをアップロードする際の小さな問題を除いて、基本的にすべてがスムーズに機能しています。すべてがデータベースに正常に送信されますが、ファイルへのリンクに必要な円記号がありません。

ただし、データベース自体に移動して、ファイルパスに円記号を入力することはできます。

形:

<form method="post" action="add.php">
 <table border="0">


 <tr><td>Detail ID: </td><td><input type="number" name="id" /></td></tr>

 <tr><td>Detail Name: </td><td><input type="text" name="name" /></td></tr>

 <tr><td>Service Group: </td><td><input type="text" name="service" /></td></tr>

 <tr><td>PDF: </td><td><input type="file" name="pdf" enctype="multipart/form-data"/></td></tr>

 <tr><td>DWG: </td><td><input type="file" name="dwg"/></td></tr>

 <tr><td></td><td><input type="submit" value="Submit" />
    <input type="reset" value="Reset" /></td></tr>

 </table>
 </form>

PHP:

$con=mysql_connect("localhost","root","");
 /* Select the database */
 mysql_select_db("hrg_test");

 /* Store the values submitted by form in variable */
 $id=$_POST['id'];
 $name=$_POST['name'];
 $service=$_POST['service'];
 $pdf=$_POST['pdf'];
 $dwg=$_POST['dwg'];


 /* Write a query to insert details into database */
 $insert_detail=mysql_query("INSERT INTO hrg_test (id, name, service, pdf, dwg) VALUES ('$id',      '$name',     '$service',     '$pdf',     '$dwg')");

 if($insert_detail)
 { echo "Detail Succesfully Added! <br /><br /><a href='add.html'>Add Another Detail</a>"; }
 else
 { echo "Error".mysql_error(); }

 /* closing the if else statements */

 mysql_close($con);
 ?>

魔法の引用符とストリップスラッシュについて読んだことがありますが、それが問題である場合、それらをどのように結び付けるかはわかりません。多分私はそれについて間違った方法で行っているだけです。

どんな助けでも大歓迎です。

4

4 に答える 4

1

入力 POST 変数の割り当てごとにこれらを使用することで、これを機能させることができると思います。

$pdf=mysql_real_escape_string($_POST['pdf']);

でも。ここでの問題はもっと深いです。今のところ、ローカル スクリプトにすぎない可能性があります。私たちは皆そこにいました。驚くほど早く物事が変化し、リファクタリングする時間が常にあるとは限りません (上司はプロトタイプが大好きで、昨日完成したアプリを望んでいます)。または、誰かが (おそらくあなたでしょうか?) より公共の環境で使用するためにコードをコピーします。このスクリプトが「管理者専用」領域の背後にあったとしても、悪意のあるコーダー (または不満を持った管理者?) が管理システムにアクセスして、あらゆる種類の厄介なものをアップロードし、データベースに不快なことを行うことができます! 誰も信じない。

ここでは、いくつかの問題の概要と、努力の点でゼロ以下のコストで改善する方法について少し説明します。

  1. MySQL API。この拡張機能は、新しいコードの作成にはお勧めできません。代わりに、mysqli または PDO_MySQL のいずれか
  2. このコードは、データベース インジェクション攻撃に対して脆弱です。データをエスケープする必要があります。これは、データを安全にデータベースに挿入できるようにすることを意味します (たとえば、' 文字をエスケープします)。使用することもできますmysql_real_escape_string()が、これは依然としてセキュリティ ホールを残す可能性があり、逃げることを忘れる機会を与えてしまいます。しかし、PDO 拡張機能を選択した場合は、パラメーター化されたクエリを使用でき、すべての問題が魔法のように解決されます。
  3. ユーザーのアップロードを受け入れることは常に危険です。制限できるほど良いです。特定の種類のファイルのみを受け入れたいことがわかっている場合は、ファイルの種類を確認してください。可能であれば、HTTP 要求経由でアクセスできない場所にファイルを移動します。HTTP 経由でアクセスできるようにする必要がある場合は、ファイルの名前を簡単に推測できない名前に変更してみてください。おそらく、30 文字程度のランダムな文字列です。これは、悪意のあるコーダーが「bad_things.php」という名前のいたずらな PHP スクリプトをアップロードできず、単に「www.example.com/uploads/bad_things.php」にアクセスしてスクリプトをサーバーで実行することができないことを意味します。アップロードされたファイルをどこにも保存していないようですので、例は含めていません。そこには無限の例があります:これはかなり合理的に見えるものです

以下は、安全であるだけでなく、はるかに単純なコードの例です (さらに短く、それは重要ではありません)。


$dbh = new PDO('mysql:host=localhost;dbname=hrg_test', 'root', '');
$stmt = $dbh->prepare("INSERT INTO hrg_test (id, name, service, pdf, dwg) VALUES(?,?,?,?,?)");
$result = $stmt->execute(array($_POST['id'],$_POST['name'],$_POST['service'],$_POST['pdf'],$_POST['dwg']));

if($result){ 
    echo "Detail Succesfully Added! <br /><br /><a href='add.html'>Add Another Detail</a>"; 
}
else { 
    var_dump($stmt->errorInfo());
}
于 2012-12-03T21:55:45.713 に答える
0

これはローカルサイトにあるため、セキュリティの問題は無視します(誰もそれを読んで、それが明らかに意味するものを摂取することはありません)。mysqli や PDO などの新しいメソッドを検討する必要がありますが、値を mysql_real_escape_string() でラップしてみてください。それはスラッシュをエスケープし、問題がある場合はそれらを保存できるようにする必要があります。

余談ですが、閉鎖された企業イントラネットの開発も行っています。方法はわかっていても、アクセスできるのはスタッフだけなので、多くの場合、上司は不必要なセキュリティを放棄するように私に懇願します。

セキュリティ上の問題があることを指摘しても問題ありませんが、質問に答えることもできます... そうでない場合は、自分と他の人の時間を無駄にしているだけです.

于 2012-12-03T21:10:21.097 に答える
0

私の言いたいことは、セキュリティが重要ではないということではなく、SO のようなサイトのコードでセキュリティを批判する必要がないということだけです。実際、私は SO のようなサイトがそれを完全に禁止するのを見たいと思っています. セキュリティについて質問している場合は問題ありませんが、コード スニペットを投稿する場合 (おそらく、私の言いたいことの例を示すためだけに書いたものです)、「ここに 37 個のリンクがあります。セキュリティについて」から「データベースを pwned にするのを楽しんでください」、または誰かが残したい気の利いたコメント。

目的は、常に OP の質問に回答することです。誰かがセキュリティの原則に頭を悩ませているようなものです。彼らは、悪いコーダーが間違いを犯すのを防ぐためにインターネットをトロールする必要があると考えています。私は正直に言って、これは完全に見当違いのエネルギーだと思います。なぜなら、大多数の人々が「私は知っています。これは投稿のための単なる例です」と答えるからです。

言うまでもなく、あなたの例では...「もっと簡単ですか?」と言います。中かっこの行を含めて、スニペットは 11 行のコードであり、人々が学ぶべき構文を使用していますが、まだ慣れていない可能性があります。OP は 14 行のコードを投稿しました (そのうちの 5 行はポスト変数をローカルにしていましたが、これは不要で、9 行のコードに削減されました。「はるかに簡単」であるとはどういうことでしょうか? 私はここで悪魔の擁護者になるのは嫌いですが、 PDO/mysqli の方が単純であるというのは意見です。確かに優れていますが、単純であるというのは大したことではありません。

セキュリティが質問の焦点であったなら、あなたの答えは素晴らしいものだったでしょう...私はあなたがハイジャックをしたことを正直に考えます。

于 2012-12-04T20:49:37.823 に答える
0

注意すべきもう 1 つの点は、二重引用符の使用です。echo ステートメントで二重引用符 (") が使用されていることに気付きました。これにより、引用符内の文字列が前処理されます (変数が展開されるなど)。データを操作し、文字列内のパスを二重引用符で囲むと、バックスラッシュが次の文字をリテラルに変換し、バックスラッシュを非表示にします。

例えば:

$UploadPath = "New\Drawings";
$NewPath = "C:\UPLOADS\$UploadPath";

この場合、$NewPath は 'C:UPLOADSNewDrawings' に変換されます。これは、各バックスラッシュがその後の文字をリテラルにするためです。一重引用符 (') を使用すると、これを防ぐか、バックスラッシュを 2 つ使用できます。

于 2012-12-04T16:58:49.563 に答える