Home Links
Home Page
Blocks try... catch... finally... in JScript 5.
Processing of events in language JavaScript
Job with Cookies on JavaScript
Processing of mistakes in PHP
Installation of the password on page
Erroneous methods of promotion of sites
Erroneous methods of promotion of sites
Keywords - the theory
Do not cling to searches!
Adjustment Firewall under ICQ
Adjustment Firewall under ICQ
Safety PHP+MYSQL+Apache
We use base MySQL
Creation of watermarks with help PHP
Twenty six ways of reception of the qualitative traffic on your site.
Unjustified use OOP
Simple way keshirovanija pages
PHP an example of parsing URL for « User Friendly URLs
 

Installation of the password on page

I have decided to describe ways to close the password a part of a site. A subject, actually, big, therefore on first time I shall be limited to authorization php+mysql.


The very first question which usually rises - how to close a directory with scripts of administration by the password. Thus it is not necessary any izyskov - one or several managers have same rights, and personnels vary seldom. Easiest in the given situation to use standard server authorization - to put files .htaccess and .htpasswd and to register in them the necessary parameters. About it it is already written much, therefore I of anything especially new shall not say.


I shall add two things. The first is where to put a file .htpasswd. In the experimental way I have found out, that if, for example, the way to the document with the message on a mistake (ErrorDocument) is written concerning system variable DocumentRoot. But the way to a file with passwords (UserFile) is written be relative ServerRoot. As far as I have understood, above ServerRoot to put .htpasswd it is impossible - ".. / " it is not perceived. All this is made that it was possible to place a file with passwords, for example, one level above root directory of a site that from a network of access to a file was not in general.


The second is that the script can learn{find out}, who it  opens also the password: variables $PHP_AUTH_USER and $PHP_AUTH_PW.


The main lack of this way - the server cannot block selection of the password (it after several unsuccessful attempts of an input{entrance} to the user is offered to wait for chasok-another, and during this time of the reference{manipulation} from his  IP-address are ignored). It is written in the official documentation on the Apache.


One more lack - necessity to copy files with passwords at removal{distance} of the user or introduction new. But if it occurs infrequently, it is quite enough this way, besides not necessary to hammer in a head a spelling of the mechanism of authorization.



Automation of authorization


It is necessary not only for simplification of job with a plenty of users and their big "tekuchkoj". If it is necessary to hold the additional information on users, or is necessary floppy differentiation of the rights, better to transfer authorization in base.


Each page of the closed territory connects a file with such code:



$result = mysql_query ("

SELECT * FROM person WHERE

login = ' ". preg_replace (" / [^ \w_-] / ", "", $PHP_AUTH_USER). " '

AND pass = ' ". md5 ($PHP_AUTH_PW.) "'");

if (@mysql_num_rows ($result)! =1) {

  header (" WWW-Authenticate: Basic realm = " User area " ");

  header (" HTTP/1.0 401 Unauthorized ");

  print (" enter the user part of a site, is necessary to enter a name and the password. ");

  exit ();

};


$user_row = mysql_fetch_array ($result);


In the first line from a login all symbols except for letters, figures, a dash and a symbol of underlining{emphasis} leave. Then the quantity{amount} of the received lines, and only is checked if it is one line, access is given. In other cases the user will see a window in a browser, offering{suggesting} to enter a login and the password. If the user has come successfully, in a file $user_row we have the information on him.


Certainly, the example which I have resulted, has a number{line} of essential lacks. Do not copy his  one - u-odin then to not fall victim to attempts of selection of the password, because

1. Protection against selection here no

2. If the table of users big, at selection of the password the malefactor, most likely, "will fill up" base


And last for today a way - storage of the ciphered data in kukakh.


There is a script for an input{entrance}, the others connect the code allowing only to continue action in closed area - if kuki will expire, or he will leave therefrom, it is necessary to come back to page for an input{entrance}.


The entrance script checks a login and the password and gives out two kuki. In the first - a login at once to identify the user (in base a field of a login, naturally, unique or even key). In the second kuke - khehsh from time of an input{entrance} and the password (for completeness of conspiracy I add letter "sh" by these lines - then khehsh to pick up it is almost impossible:).


All other programs connect a code which does{makes} the following. Interpellates in base - chooses a line with the received login. From this line takes a field "log_time" and the password and does{makes} of them, as well as it is described above, khehsh. Compares it  to that, that has received, and if they coincide, gives out new kuku khehsha, besides, from the password, time and the letter "sh" and interpellates in a database " UPDATE user SET log_time = '...' WHERE login = ' $ cookie_login ' ".



if (isset ($HTTP_COOKIE_VARS [$cookie_login]) ** isset ($HTTP_COOKIE_VARS [$cookie_code])) {


$login = $HTTP_COOKIE_VARS [$cookie_login];

$code = $HTTP_COOKIE_VARS [$cookie_code];


$result = mysql_query (" SELECT date_format (log_date, '%Y%m%d%H%i%s') as log_date1, pass, uid

FROM user WHERE email = ' $ login ' AND log_date> ' DATE_SUB (NOW (), INTERVAL 15 MINUTE) ' ");

if (! mysql_error () ** @mysql_num_rows ($result) == 1) {

  $log_time0 = time ();

  $log_time1 = date ("YmdHis", $log_time0);

  $log_time2 = date (" Y-m-d H:i:s ", $log_time0);

  $current_user = mysql_fetch_array ($result);

  if (md5 ($current_user ["pass."] $current_user ["log_date1."] $md5letter) == $code) {

    mysql_query (" UPDATE user SET log_date = ' $ log_time2 ' WHERE uid = ". $ current_user ["uid"]);

    setcookie ($cookie_code, md5 ($current_user ["pass"]. $log_time1. $ md5letter),

      time () +900, $site_path);

    $auth = true;

}

  else

    unset ($current_user);

};

};


Besides, here there is no protection against selection and attack to the server (by the way, here it is possible to write instead of letter "sh" the IP-address of the user - that, for example, the neighbour on office could not take a file with kukoj and to go from the computer).



The password on page. A part 2. Blocking of selection


When I have laid out this release last time, me zapinali on a place, a pier such blocking it is possible "to derail" the server also.


But all over again about blocking selection. Banality, but all. The password long ten symbols from letters latinicy and figures is many{a lot of;much} variants. If to select the password on 1000000 variants in a second, some thousand years are required. But as such abrakadabru to remember difficultly, we do{make} the password of intelligent words is more often. Several years ago appeared, that the majority of passwords can be picked up by means of the dictionary from 10000 words. In due time in a network the worm (a virus such) which climbed on juniksovym to servers has appeared, using them dyrki in protection, and selected passwords priveligirovanykh users with the help... The system spelling dictionary of a Unix. Anything to drag it was not necessary!


Each user while he has not entered a correct login and the password, is considered a spiteful hacker. With what we deal, when the user enters something incorrectly?

Forgetfulness (on it on decent sites is formochka " has forgotten the password " to send on vvedjonyj in system adjustments email this password)

Overindulgence (" for nefig ")

Selection of the password under the dictionary (the probability of successful selection is great, therefore to close it is necessary, especially, if a site of commercial character)

DoS-attack (to not overload the server, it is necessary to minimize actions which will be carried out with a script in that case)


I for a long time thought, how it is possible to call an overload on the server if the mechanism of protection costs{stands} on files. Appeared, it is simple (how much it will cost - other question). So, we admit{allow}, the server will not sustain, if the script will try to open 1000 times a second files on recording and to write to them the data. As after 5 unsuccessful attempts enter system the user will receive at once refusal in access (without any data recording in a file), it is necessary to find 200 unique IP with which on five times and to address. It is possible. We hang up in bannerokrutilke a html-banner with five tegami:


<img src = " http: // user:password@www.host.ru/secret/absent.gif " width=1 height=1>


The user instantly does{makes} five references{manipulations} the server five times writes to a file (by the way, in some browsers, probably, the window for input of a login and the password will jump out). It is possible to make html-page with five such pictures, and page to insert through iframe on a visited{an attended} site (through iframe - that on a field referer have not found. Hardly the support service khaljavnogo a hosting will be engaged in such things as digging in broad gullies - files in searches refererov). Those examples which I have resulted, certainly, are tense, but the fact of that is possible to use such lack of system, is proved. By the way, something similar already was.


But all I shall result this way - zrja wrote, whether that? It{he}, by the way, can be applied without special fear to the limited quantity{amount} of addresses (for example, for a local area network of firm), having put in a directory a file .htaccess such maintenance{contents}:


order deny, allow

deny from all

allow from xxx.xxx.xxx


And a code of the program:



$errors = 0;

$fn = " ignore / ". preg_replace (" [^d]. ", " ", $REMOTE_ADDR.". $HTTP_FORWARDED_FOR);


if (is_file ($fn)) {

  if (filectime ($fn) <time ()-3600)

    unlink ($fn);

  else

    $errors = fread (fopen ($fn, "r"), 2);

};


if ($errors> 5) {

  print (" Access is closed. Go in one hour. ");

  exit ();

};


// Here there is a connecting to the server of a DB. To not touch zrja if the user at once "have flogged".


$result = mysql_query (" SELECT * FROM user WHERE

  login = ' ". preg_replace (" / [^w_-] / "," ", $PHP_AUTH_USER). " ' AND

  pass = ' ". md5 ($PHP_AUTH_PW.) "'");

if (@mysql_num_rows ($result)! =1) {

  header (" WWW-Authenticate: Basic realm = " secret area " ");

  header (" HTTP/1.0 401 Unauthorized ");

  print (" Authorization required ");

  fwrite (fopen ($fn, "w"), ++ $errors);

  exit ();

};


$current_user = mysql_fetch_array ($result);

mysql_free_result ($result);


However, the sin to work with files if there is a base. A joke. For not past{?last} authorizations we create the table:


CREATE TABLE unauth (username VARCHAR (64) NOT NULL, pass VARCHAR (64) NOT NULL, ip VARCHAR (255), logintime TIMESTAMP)


And instead of the reference{manipulation} to files we work with base.


$errors = @mysql_result (mysql_query (" SELECT count (username) as falses FROM unauth WHERE

logintime> DATE_SUB (NOW (), INTERVAL 1 HOUR) AND ip = ' $ REMOTE_ADDR ' "), 0);

if (mysql_error ())

  die (mysql_error ());


if ($errors> 5) {

  print (" Access is closed. Go in one hour. ");

  exit ();

};

$result = mysql_query (" SELECT * FROM user WHERE

  login = ' ". preg_replace (" / [^w_-] / "," ", $PHP_AUTH_USER). " ' AND

  pass = ' ". md5 ($PHP_AUTH_PW.) "'");

if (@mysql_num_rows ($result)! =1) {

  header (" WWW-Authenticate: Basic realm = " secret area " ");

  header (" HTTP/1.0 401 Unauthorized ");

  print (" Authorization required ");

  mysql_query (" INSERT INTO unauth (username, pass, ip) VALUES

    ('$PHP_AUTH_USER', '$PHP_AUTH_PW', ' $REMOTE_ADDR $HTTP_X_FORWARDED_FOR ') ");

  exit ();

};


$current_user = mysql_fetch_array ($result);

mysql_free_result ($result);


Whether to store{keep} old recordings for statistics whether or not - business master's. If that, they can be deleted, carrying out before authorization search:


DELETE FROM unauth WHERE logintime <DATE_SUB (NOW (), INTERVAL 1 HOUR)


Such mechanism at the big loadings will work fastly and more reliably, than files - in base often the used data buferizujutsja and are processed directly in operative memory.



The password on page. A part 3. The password from base


There was at me in due time a problem: it is necessary to close administracionnuju a part of a site, but thus I cannot put a file .htpasswd above root directory of a site. Congenital suspiciousness did not allow to put a file with the password and a separate directory and to block access to her on http. Has decided to try to make protection as in phpMyAdmin: the login and the password with which the script incorporates to base are asked the user. In the analyzer of dens I have made so. Convenience of a method that the file can be put{folded} anywhere - any kuk, any directives of the server for a directory. At the same time, if the password in a database will exchange, it is not necessary to correct anything in a script.


I shall paint with a method on example MySQL. We write function, for example, mysql_die:



function mysql_die () {

  header (" HTTP/1.0 401 Unauthorized ");

  header (" WWW-authenticate: basic realm = "Statistics" ");

  print (" Access denied. User name and password required. ");

  exit ();

}


In the beginning of the program are specified a host of the server of a DB and if it is necessary, a name of base:


$db_host = "localhost";

$db_name = "somedatabase";


And for connection with base variables of the server undertake: $PHP_AUTH_USER and $PHP_AUTH_PW.


$db_connect = @mysql_connect ($db_host, $PHP_AUH_USER, $PHP_AUTH_PW)

or mysql_die ();


And all. Now about lacks. Certainly, with such protection it is possible to try to select the password (basically, it it is possible to attach blocking but then poterjatesja all beauty of a method). The password, as well as in a case protection by means of the server, is sent in an open kind. But for simple problems{tasks} such will quite fit.