Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα,

 

είναι το δεύτερο project που κάνω σε php και βασικά είναι ένα helpdesk για βλάβες. Το πρόβλημα μου είναι το εξής:

 

Αρχίζει με μια login φόρμα όπου πρέπει αν δίνει κωδικό και username. Όλα υπέροχα με αυτό αλλά, μόλις δώσω τα σωστά με στέλνει σε ένα άλλο αρχείο php. Τώρα το πρόβλημα είναι ότι αν εγώ πατήσω κατευθείαν να μπώ στο δευτερο αρχείο τότε με αφήνει και δεν πρέπει αν γίνεται αυτό. Ουσιαστικά πηδάω την φόρμα και δεν υπάρχει τπτ. Προφανώς είναι τεράστια τρύπα ασφαλείας και θέλω να την φτιάξω. Μπορέι κάποιος να με βοηθήσει?

 

Γνωρίζω σχετικά τα βασικά με php απλά πείτε μου στο περίπου πως να δουλέψω! :) Σκέφτομαι κάτι για session_start() αλλα δεν ξέρω τι κάνει και που να το χρησιμοποιήσω.

 

ευχαριστώ πολυ παιδιά

Δημοσ.

>
if (!isset($_SESSION["username"]) || !isset($_SESSION["password"]))
{
  header('Location: index.php');
}

 

έχεις την καλοσύνη να μου το εξηγήσεις και με 2 λογάκια?

Δημοσ.

Όταν ο χρήστης του συστήματός σου εισάγει username και κωδικό, γίνεται επαλήθευση των στοιχείων του και εάν είναι σωστά, τα αποθηκεύεις σε δύο session μεταβλητές, έστω τις $_SESSION["username"] και $_SESSION["password"]. Ο κώδικας που σου έχω γράψει κάνει έλεγχο για το εάν οι δύο αυτές μεταβλητές έχουν τιμή. Εάν δεν έχουν, πράγμα το οποίο σημαίνει ότι ο χρήστης δεν έχει κάνει login, τότε τον κάνει redirect στο αρχείο index.php.

 

Εάν δεν δουλέψει με !isset, δοκίμασε με την isempty (χωρίς το !).

Δημοσ.

Έπιασα το νόημα σε ευχαριστώ!

 

Έχω υλοποιήσει τον μηχανισμό ωστόσο έχω ένα μικρό πρόβλημα.

 

index.php δίνω Username & password

τα πιάνει το

login.php

>
<?php
session_start();
$username = $_POST['username'];
$password = $_POST['password'];

if( empty($username) || empty($password) ){
	echo "You have to give both username & password! Redirecting to the form in 4 sec...";
	header('refresh:4;url=index.php');
	exit(1);
}else{
	$password = md5($password);
	include ('init.php');
	header('url=authentication.php');
	exit(0);
}
?>

 

init.php

><?php
error_reporting(0);

require('connect.php');
require('authenticate.php');
?>

 

authenticate.php

>	$sql = mysql_query(" SELECT * FROM users WHERE username='$username' AND password='$password' ");
$num_rows = mysql_num_rows($sql);
if( (mysql_result($sql, 0, 0) == $username) && (mysql_result($sql, 0, 1) == $password) ) {
	$_SESSION["username"] = $username;
	$_SESSION["password"] = $password;
	echo "User, ".$username." exists in database!";
	echo "You are now logged in!!!!!! Redirecting to the interface in 4 sec...";
	header('refresh:4;url=main.php');
	exit(0);
}else{
	echo "User not exists!";
	echo "Username or Password is incorrect! Please try again. Redirecting to the form in 4 sec...";
	header('refresh:4;url=index.php');
	exit(1);
}

 

τέλος το Main.php που είναι και το Interface έχει κάτι σαν

><html>
<head>
<?php
	//echo "---------------".$_SESSION["username"];
	if (!isset($_SESSION["username"]) || !isset($_SESSION["password"])) {
		echo "Permission Denied! Redirecting to the form in 4 sec...";
		header('refresh:4;url=index.php');
	}
?>
</head>
<body>
	<div id="content">
		<h2 align="center"> ΑΡΧΙΚΗ</h2> <hr> <br>

αλλα τα username & password δεν τα έχει κρατήσει για κάποιον λόγο

Δημοσ.

Δεν έχεις βάλει session_start στο main.php.

 

γενικοτερα βέβαια, χρειάζεται αρκετές διορθώσεις - η πιο τρανταχτή φυσικά ότι αποθηκεύεις τον κωδικό του χρήστη στο session

Δημοσ.

Αν το βάλω θα ξεκινήσει νέο session η θα είναι το παλιό και θα μπορώ να κάνω retrieve κάποιες τιμές που χρειάζομαι?

 

Το ξέρω πως θέλει διορθώσεις, αλλά μόνο με κώδικα μαθαίνεις...

Δημοσ.

Έχεις πάρα μα πάρα πολλά πράγματα που πρέπει να διορθώσεις.

 

login.php

>
<?php
session_start();
$username = $_POST['username'];
$password = $_POST['password'];

if( empty($username) || empty($password) ){
	echo "You have to give both username & password! Redirecting to the form in 4 sec...";
	header('refresh:4;url=index.php');
	exit(1);
}else{
	$password = md5($password);
	include ('init.php');
	header('url=authentication.php');
	exit(0);
}
?>

 

  1. Δεν μπορείς να στέλνεις content (π.χ. echo) και μετά να καλείς την header(). Αυτό έχει να κάνει με το πώς λειτουργεί το πρωτόκολλο HTTP. Αυτό που κάνεις τυχαίνει να λειτουργεί για "τυχαίους" λόγους και μπορεί να πάψει να λειτουργεί "ανά πάσα στιγμή".
  2. Redirect κάνεις δίνοντας header("Location: http://foo.com").
  3. Δεν έχει κανένα νόημα να κάνεις "προετοιμαστικά" πράγματα όπως include ('init.php') αν πρόκειται να κάνεις redirect στη συνέχεια.

 

init.php

><?php
error_reporting(0);

require('connect.php');
require('authenticate.php');
?>

 

Το error_reporting πρέπει να το έχεις όσο πιο ψηλά γίνεται, όχι να το κλείνεις!

 

authenticate.php

>	$sql = mysql_query(" SELECT * FROM users WHERE username='$username' AND password='$password' ");
$num_rows = mysql_num_rows($sql);
if( (mysql_result($sql, 0, 0) == $username) && (mysql_result($sql, 0, 1) == $password) ) {
	$_SESSION["username"] = $username;
	$_SESSION["password"] = $password;
	echo "User, ".$username." exists in database!";
	echo "You are now logged in!!!!!! Redirecting to the interface in 4 sec...";
	header('refresh:4;url=main.php');
	exit(0);
}else{
	echo "User not exists!";
	echo "Username or Password is incorrect! Please try again. Redirecting to the form in 4 sec...";
	header('refresh:4;url=index.php');
	exit(1);
}

 

  1. Είσαι τέλεια στημένος για SQL injection (google it), στην προκειμένη περίπτωση και πάλι για πολύ συγκεκριμένους λόγους δεν κινδυνεύεις από κάτι αλλά το πρόβλημα παραμένει.
  2. Ποτέ δεν αποθηκεύουμε plaintext passwords στη database!
  3. Όταν τρέχεις την PHP σαν module του web server δεν παίζει κανένα απολύτως ρόλο το τι κωδικό περνάς στην exit()
  4. Απέφευγε να έχεις αρχεία που μόλις γίνονται include εκτελείται κώδικας. Βάλε τον κώδικα που θέλεις σε μία ή περισσότερες functions και άσε τον κώδικα που σε κάνει include να τις καλέσει manually.

 

Αν το βάλω θα ξεκινήσει νέο session η θα είναι το παλιό και θα μπορώ να κάνω retrieve κάποιες τιμές που χρειάζομαι?

 

Το ξέρω πως θέλει διορθώσεις, αλλά μόνο με κώδικα μαθαίνεις...

 

Γιατί δεν το βάζεις να δεις; :)

 

Το session θα είναι το ίδιο, γιατί όταν καλείς πρώτη φορά την session_start() το session id αποθηκεύεται σε cookie στον browser. Κάθε επόμενη φορά (όσο ισχύει το cookie) η session_start βλέπει ότι υπάρχει ήδη και δεν δημιουργεί καινούριο.

Δημοσ.

><?php
       session_start();
       $username = $_POST['username'];
       $password = $_POST['password'];

       if( empty($username) || empty($password) ){
               echo "You have to give both username & password! Redirecting to the form in 4 sec...";
               header('refresh:4;url=index.php');
               exit(1);
       }else{
               $password = md5($password);
               include ('init.php');
               header('url=authentication.php');
               exit(0);
       }
?>

 

ααα, τόσο απλή είναι η χρήση του MD5? δηλαδή απλά του λες

>$password = md5($password);

Δημοσ.

Μια παρατήρηση κι από μένα,

 

νομίζω δεν υπάρχει λόγος ν'αποθηκεύεται και το password σε Session.Εγώ αν ταιριάζει το όνομα με τον κωδικό χρήστη αποθηκεύω το username σ'ένα session ή ακόμα καλύτερα φτιάχνω ένα session status

 

>$_SESSION['status'] = 'Logged_In';

 

και σε κάθε προστατευμένη σελίδα ελέγχω με

 

><?php
session_start();
include 'connection.php';

if ($_SESSION['status'] !='Logged_In') {
   header("Location:index.php");
   exit;
}

echo 'Hello '.$_SESSION['name'];

?>

Δημοσ.

ααα, τόσο απλή είναι η χρήση του MD5? δηλαδή απλά του λες

>$password = md5($password);

 

 

 

Σε σχέση με το άλλο thread που λες για την ευκολία των γλωσσών: τόσο απλή θα έπρεπε να είναι κιόλας. Το να χρειαστεί να κάνεις allocate buffers, initialize τα κέρατά σου και δεν ξέρω και γω τι άλλη γκασμαδο-δουλεία για να βγάλεις ένα md5 δε σε κάνει καλύτερο developer. Απλά μειώνει την παραγωγικότητά σου.

 

Αυτό που σε κάνει καλύτερo ή όχι είναι η κατανόηση που έχεις για τα πράγματα.

 

 

Δημοσ.

@defacer τα άλλαξα σχεδόν όλα. Η εφαρμογή θα είναι πίσω απο firewall και proxy και θα δουλεύει σε proxy οποτε δεν υπάρχει τεράστιο ζήτημα με ασφάλεια ωστόσο θέλω να μάθω.

 

  1. Είσαι τέλεια στημένος για SQL injection (google it), στην προκειμένη περίπτωση και πάλι για πολύ συγκεκριμένους λόγους δεν κινδυνεύεις από κάτι αλλά το πρόβλημα παραμένει.
  2. Ποτέ δεν αποθηκεύουμε plaintext passwords στη database!

 

Δεν κατάλαβα γιατί... Βασικά γνωρίζοντας κάποιος το session id πως συνδέεται? Απλή περίγραφή θα ήταν μια χαρά.

 

VARCHAR το είχα το password. Όχι? Τι προτείνεις να το βάλω?

 

Σε ευχαριστώ πολύ για την απάντησή σου :)

Δημοσ.

Όσον αφορά το 1ο σου ερώτημα για sql injection, ποστάρεις κάποια δεδομένα και δεν ελέγχεις τι σου πέρασε ο άλλος.

 

Επομένως, μπορώ πολύ εύκολα να σου τινάξω όλη την βάση στον αέρα!

 

Όσον αφορά τα plaintext passwords στη database, εάν κάποιος καταφέρει και έχει πρόσβαση στην βάση, πολύ απλά θα δει passwords. Βέβαια κατά την δική μου άποψη αυτό έρχεται 2ο και 3ο σε σχέση με το πως κατάφερε και είχε πρόσβαση στην βάση σου.

Δημοσ.

@defacer τα άλλαξα σχεδόν όλα. Η εφαρμογή θα είναι πίσω απο firewall και proxy και θα δουλεύει σε proxy οποτε δεν υπάρχει τεράστιο ζήτημα με ασφάλεια ωστόσο θέλω να μάθω.

 

  1. Είσαι τέλεια στημένος για SQL injection (google it), στην προκειμένη περίπτωση και πάλι για πολύ συγκεκριμένους λόγους δεν κινδυνεύεις από κάτι αλλά το πρόβλημα παραμένει.
  2. Ποτέ δεν αποθηκεύουμε plaintext passwords στη database!

Δες τον κώδικά σου:

 

>        $sql = mysql_query(" SELECT * FROM users WHERE username='$username' AND password='$password' ");
       $num_rows = mysql_num_rows($sql);
       if( (mysql_result($sql, 0, 0) == $username) && (mysql_result($sql, 0, 1) == $password) ) {

 

Δεν ξέρω γιατί επέλεξες να χρησιμοποιήσεις τη mysql_result για να ελέγξεις τα δεδομένα. Το έκανες επίτηδες; Φαντάζομαι έτσι το είδες κάπου και το μετέφερες.

 

Έρχομαι τώρα και σε ρωτάω: αφού το query θα επιστρέψει είτε 1 row είτε κανένα, γιατί να μην το αλλάξεις απλά σε

 

>        $sql = mysql_query(" SELECT * FROM users WHERE username='$username' AND password='$password' ");
       $num_rows = mysql_num_rows($sql);
       if( $num_rows ) {

 

Λογικό; Ναι. Αλλά έτσι βγαίνει στην επιφάνεια το SQL injection. Bάλε τον κώδικα όπως παραπάνω και μετά δώσε στη φόρμα όποιο password θέλεις (και κενό αν θες) και για username δώσε

 

>' OR 1 #

 

Θα δεις ότι θα κάνει login. Αυτό συμβαίνει γιατί έτσι που τα έχεις επιτρέπεις στο χρήστη (που μπορεί να είναι κακός) να βάλει δική του είσοδο μέσα στο query της SQL σου, πράγμα που μπορεί να αλλάξει τη συμπεριφορά του. Αυτό λέγεται SQL injection. Να σημειώσω ότι υπάρχουν και άλλοι τρόποι να γίνει injection, απλά εσύ είσαι τυχερός και στην περίπτωσή σου πολλά διαφορετικά άστρα έχουν συγκλίνει ούτως ώστε το συγκεκριμένο query να μην είναι τελικά "αξιοποιήσιμο" για injection απ' όσο ξέρω. Όπως καταλαβαίνεις όμως αν αγνοείς το τι παίζεται είναι θέμα χρόνου να κάνεις το λάθος.

 

Το θέμα είναι πολύ γνωστό και αν κάνεις google δε θα δυσκολευτείς να βρεις σχετικό υλικό. Σου προτείνω να κάνεις ακριβώς ο,τι λέει εδώ.

 

Για το password είναι περίπου αυτό που λέει ο uberalles (αλλά δε χρειάζεται να σου κλέψουν όλη τη db απαραίτητα για να σου πάρουν ένα password).

 

Διάβασε αν θέλεις αυτό και μετά αυτό. Υπάρχει επίσης πολύ υλικό για googling.

Δημοσ.

Δεν έχω παραθέσει όλο τον κώδικα. Στο Username έχω dropdown menu και δεν μπορεί να βάλει ότι θέλει αλλα και πάλι ίσως μπορέσει να κάνει διάφορα με add-ons του browser...

 

τεσπα σε ευχαριστώ πολυ για τις απαντήσεις :)

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...