0

重複の可能性:
PHP によって既に送信されたヘッダー

以下のコードでは、どういうわけか、どのヘッダーも指定された場所にリダイレクトされていません..理由はわかりません...ヘッダーが呼び出される前に、出力を送信またはエコーしていません。また、ヘッダーの誤動作につながる可能性のある偶発的な「空白」もありません()。ob_start() も試してみましたがだめでした。また、すべてのファイルは単一のフォルダー、つまり WAMP の「www」フォルダーにあります。

このコードは、新規ユーザーの登録に使用されるフォームを処理します.....POST メソッドが使用されます

$user= "root" ;
$host= "localhost" ;
$password= "" ;

$database= "online_examination" ;
$fn=$_POST['fn'] ;    // firstname
$ln=$_POST['ln'] ;    // lastname
$un=$_POST['un'] ;  // username
$pass=$_POST['pw'] ;  // password

$connection= mysql_connect($host,$user,$password) ;
$db= mysql_select_db($database,$connection);
$query=" SELECT username FROM user_info " ;
$result=mysql_query ($query,$connection) ;

for ($i=0 ; $i<mysql_num_rows($result) ; $i++ )
{
    $uname=mysql_result($result,$i,"username") ;

    if ($un==$uname)
       {
           header ("Location : /username_exists.php") ;
           exit;
       }
}

$query=" SELECT password FROM user_info " ;
$result=mysql_query ($query,$connection) ; 

for ($i=0 ; $i<mysql_num_rows($result) ; $i++ )
{
     $pword=mysql_result($result,$i,"password") ;
     if ($pass==$pword)
       {
            header ("Location : /password_exists.php") ;
            exit;
       }
}

$query=" INSERT INTO user_info (firstname,lastname,username,password) VALUES
('$fn','$ln','$un','$pass') " ;

mysql_query ($query,$connection)

header ("Location : /successfully_registered.php") ;
4

3 に答える 3

0

このコードはセキュリティホールと論理エラーでいっぱいですが、私はできる限りそれを書き直そうとしました。

$user = 'root';
$host = 'localhost';
$password = '';
$database = 'online_examination';

// Attempt to connect to MySQL
if( !( $connection = mysql_connect( $host , $user , $password ) ) ){
  die( 'Failed to connect to server' );
}elseif( !( $db = mysql_select_db( $database , $connection ) ) ){
  die( 'Failed to connect to database' );
}

// Default values for Form Submitted Fields
$fn = $ln = $un = $pass = false;
// Check if Form Submitted
if( $_POST ){
  // For each value, perform some basic validation before trusting them
  if( isset( $_POST['fn'] ) && $_POST['fn']!='' )
    $fn = $_POST['fn'] ;    // firstname
  if( isset( $_POST['ln'] ) && $_POST['ln']!='' )
    $ln = $_POST['ln'] ;    // lastname
  if( isset( $_POST['un'] ) && $_POST['un']!='' )
    $un = $_POST['un'] ;  // username
  if( isset( $_POST['pw'] ) && $_POST['pw']!='' )
    $pass = $_POST['pw'] ;  // password
}

// If a Username was submitted
if( !$fn || !$ln || !$un || !$pw ){

  // One or more of the fields were empty or not submitted.
  // Show the form again (maybe with an error message)

}else{

  // Perform a Query looking for any instances where the same username is already in use
  $query = 'SELECT COUNT(*) AS matches FROM user_info WHERE username="'.mysql_real_escape_string( $un ).'"';
  $result = @mysql_query( $query , $connection ) ;
  if( !$result ){
    die( 'Query for Usernames Failed' );
  }
  $row = mysql_fetch_array( $result )
  if( $row['matches']!=0 ){
    // The Username is already in use
    if( !headers_sent() ){
      header( 'Location: /username_exists.php' );
    }else{
      echo 'Username already in use - <a href="/username_exists.php">Click here</a>';
    }
    die();
  }

  // If we have gotten to this point, the username is OK to use
  $sqlTpl = 'INSERT INTO user_info ( firstname , lastname , username , password ) VALUES ( "%s" ,  "%s" ,  "%s" , "%s" )';
  $sqlStr = sprintf( $sqlTpl ,
    mysql_real_escape_string( $fn ) ,
    mysql_real_escape_string( $ln ) ,
    mysql_real_escape_string( $un ) ,
    mysql_real_escape_string( $pw ) );
  $result = mysql_query( $sqlStr , $connection );
  if( $result ){
    if( !headers_sent() ){
      header( 'Location: /successfully_registered.php' );
    }else{
      echo 'Successfully registered - <a href="/successfully_registered.php">Click here</a>';
    }
    die();
  }else{
    // Something went wrong
  }
}

ヒップからのいくつかのポイント:

  • 返されたすべての行をループして個別に照合することは、値が存在するかどうかを確認するためのわかりにくい方法です。SQLは、そのようなことを行うのにはるかに優れています-それを読んでください。
  • パスワードがすでに使用されているかどうかを確認するためのチェックを実行しても意味がありません。StackOverflowの1人か2人が同じパスワードを持っていると思いますが、「誰かがすでにパスワードとして「abc123」を持っています。別の人を選んでください」というメッセージは表示されませんでした。どちらかといえば、その種のメッセージはセキュリティ対策ではなくセキュリティリスクです。
  • 入力を信用しないでください。POSTの提出があると仮定すると、災害のレシピになります。
  • したがって、取得した入力を検証していません。
  • さらに、データベースクエリ内で使用するためにエスケープしないでください。「リトルボビーテーブル」のためのグーグル。
  • パスワードを保存する場合は、プレーンテキストでパスワードを保存しないでください。それらはハッシュされ、ソルトされるべきです。(繰り返しますが、Googleはあなたの友達です。)
  • ヘッダーを変更できると仮定することは、注意して行う必要があります。で確認するheaders_sent()ことをお勧めします。
  • 進行中は常にエラーをテストしてください。開始時に小さなエラーが発生し、それを検出して後続のアクションを中止することは、小さなミスを雪だるま式にさせるよりも優れています。

ユーザー登録を処理する既存のチュートリアルやPHPクラスのいくつかをチェックしてください。それらの多くは優れたアイデアを持っており、車輪の再発明ではなく、ソリューションに組み込む必要があります。

于 2012-06-26T03:08:58.763 に答える
-1
$connection= mysql_connect($host,$user,$password); 
$db= mysql_select_db($database,$connection);

おそらくphpエラーが原因で失敗しています。セミコロンがありませんでした。

error_reporting(E_ALL); を試してください。上部でエラーを再確認します。

于 2012-06-25T19:43:43.397 に答える
-1

また、<?phpタグの外側に空白がないことを確認してください。これにより、テキストがブラウザに送信され、出力バッファリングがオンになっていない限り、「ヘッダーは既に送信されました」というエラーが発生します。また、非常に安全でない SQL 処理があります。どの変数も、SQL インジェクションを成功させるために悪用される可能性があります。

于 2012-06-25T19:23:45.233 に答える