The security environment discussed in this article is Linux + Apache + Mysql + PHP. Security issues beyond this scope are beyond the scope of this article
I. apache server security settings
1. run with a Nobody user
Generally, Apache is installed and run by the Root user. If the Apache Server process has the Root user privilege, it will pose a great threat to system security. ensure that the Apache Server process runs with the lowest possible permissions. By modifying the following options in the httpd. conf file, you can run Apache as a Nobody user to achieve relative security.
User nobody
Group #-1
2. ServerRoot directory permissions
To ensure proper and secure configuration, you must strictly control the access permissions of the Apache main directory so that non-superusers cannot modify the contents in the directory. The Apache Main Directory corresponds to the Server Root control item in the Apache Server configuration file httpd. conf. it should be:
Server Root/usr/local/apache
3. SSI configuration
In the configuration file "access. conf" or "httpd. conf", add the "except des no exec" option to the Options command to disable the execution function in Apache Server. This prevents you from directly executing the execution programs on the Apache server, resulting in the openness of the server system.
Options Includes Noexec
4. prevent users from modifying system settings
Make the following settings in the configuration file of the Apache server to prevent users from creating and modifying the. htaccess file, and prevent users from surpassing the defined system security features.
AllowOveride None
Options None
Allow from all
Then configure the specific directories separately.
5. change the default access features of the Apache server
Apache's default settings only ensure a certain degree of security. if the server can find the file through the normal ing rules, the client will obtain the file, such as http: // local host /~ Root/will allow users to access the entire file system. Add the following content to the server file:
Order deny, ellow
Deny from all
The default access to the file system is prohibited.
6. security considerations for CGI scripts
CGI scripts are a series of programs that can be run through Web servers. To ensure system security, ensure that the CGI author is credible. For CGI, it is best to restrict it to a specific directory, such as under cgi-bin for ease of management. In addition, ensure that the files in the CGI directory are not writable, avoid some deceptive program resident or obfuscation. if a CGI program module with good security can be provided as a reference, it may reduce unnecessary troubles and security risks; remove all non-business application scripts in the CGI directory to prevent abnormal information leakage.
7. SSL link encryption
These common measures can provide the Apache Server with a basic secure operating environment. Obviously, we need to further refine the implementation to develop a security configuration solution that conforms to the actual application.
II. PHP security settings
The server cannot prevent all security issues, such as program vulnerabilities, user input forms, and PHP file permissions.
You can also use some means to confuse hackers or those with ulterior motives.
1. program code vulnerability
The major weakness of many PHP programs is not the problem of the PHP language, but caused by the low security awareness of programmers. Therefore, you must always pay attention to the possible problems in each piece of code to find out the possible impact of incorrect data submission.
The code is as follows:
Unlink ($ evil_var );
Fwrite ($ fp, $ evil_var );
System ($ evil_var );
Exec ($ evil_var );
?>
Always pay attention to your code to ensure that all the variables submitted from the client are properly checked and then ask yourself the following questions:
Can this script only affect the expected files?
Can an abnormal data be used after it is submitted?
Can this script be used for unplanned purposes?
Can this script be combined with other scripts to do bad things?
Are all transactions fully recorded?
Ask yourself these questions when writing code. Otherwise, you may need to rewrite the code to increase security. If you pay attention to these problems, you may not be able to guarantee the security of the system, but at least you can improve the security.
You can also consider disabling register_globals, magic_quotes, or other settings that make programming more convenient but make the legitimacy of a variable, and the sources and values of the variable messy.
2. user input form problems
Verify any data entered by the user to ensure the security of PHP code.
Note 1: JS is generated only to improve the user experience, rather than the verification tool. This is because any visiting user may accidentally disable the execution of client scripts, thus skipping this layer of verification. Therefore, we must check the data on the PHP server program.
Note 2: Do not use the super variable $ _ SERVER ['http _ referer'] to check the data source address. a very small Cainiao hacker will use a tool to forge the data of this variable, use Md5, rand, and other functions as much as possible to generate a token. when verifying the source, verify that the token matches.
3. php file permissions
PHP is designed to access the file system at the user level, so it is entirely possible to write a piece of PHP code to read system files such as/etc/passwd, change the network connection and send a large number of print tasks. Therefore, make sure that PHP code is suitable for reading and writing files. See the following code to delete an object in your home directory. In this case, the file system is managed through the web interface. Therefore, Apache users have the right to delete files in the user directory.
The code is as follows:
$ Username = $ _ POST ['User _ submitted_name '];
$ Homedir = "/home/$ username ";
$ File_to_delete = "$ userfile ";
Unlink ("$ homedir/$ userfile ");
Echo "$ file_to_delete has been deleted! ";
?>
Since the username variable can be submitted through the user form, you can submit another user name and file name and delete the file. In this case, you must consider other authentication methods:
Only PHP web users have limited permissions.
Check all submitted variables.
The following describes how to verify and check more secure file names and variables:
The code is as follows:
$ Username = $ _ SERVER ['remote _ user'];
$ Homedir = "/home/$ username ";
If (! Ereg ('^ [^./] [^/] * $', $ userfile ))
Die ('Bad filename ');
If (! Ereg ('^ [^./] [^/] * $', $ username ))
Die ('bad username ');
?>
4. hide the PHP extension
In general, increasing security through hidden means is considered to be of little effect. But in some cases, it is worthwhile to add as much security as possible.
Some simple methods can help to hide PHP, which can make it more difficult for attackers to discover system vulnerabilities. Setting expose_php = off in the php. ini file can reduce the useful information they can obtain.
Another policy is to let the web server use PHP to parse different extensions. Whether using the. htaccess file or Apache configuration file, you can set a file extension that can mislead attackers:
# Make PHP look like other programming languages
AddType application/x-httpd-php. asp. py. pl
# Make PHP look like an unknown file type
AddType application/x-httpd-php. bop. foo. 133 t
# Make PHP code look like an HTML page
AddType application/x-httpd-php. htm. html
To make this method take effect, you must change the extension of the PHP file to the above extension. In this way, security is improved through Hiding, although the defense capability is low and there are some shortcomings.
III. Mysql database security settings
PHP itself cannot protect database security. The following section describes how to use a PHP script to perform basic database access and operations. Remember a simple principle: in-depth defense. The more database protection measures, the more difficult the attacker to obtain and use the information in the database. Correct design and application database can reduce the fear of attacks.
1. database design problems
Applications should never use the database owner or superuser account to connect to the database, because these accounts can perform any operations, such as modifying the database structure (such as deleting a table) or clear the content of the entire database. The following user settings are dangerous.
You should create different database accounts for each aspect of the program and grant extremely limited permissions to database objects. Assign only the permissions required to complete the functions of a user, so that the same user can complete the tasks of another user. In this way, even if attackers exploit a program vulnerability to gain database access permissions, they can only achieve the same impact scope as the program.
2. database connection problems
Setting up a connection to the SSL encryption technology can increase the communication security between the client and the server, or use SSH to encrypt connections between the client and the database. If these technologies are used, it is very difficult for attackers to monitor server communication or obtain database information.
3. database data encryption
SSL/SSH can protect the data exchanged between the client and the server, but SSL/SSH cannot protect the existing data in the database. SSL is just a protocol used to encrypt network data streams.
If attackers obtain a permit to directly access the database (bypassing the web server), sensitive data may be exposed or abused unless the database itself protects the information. Data encryption in databases is an effective way to reduce such risks, but only a few databases provide these encryption functions.
A simple solution to this problem is to create your own encryption mechanism and use it in a PHP program, the most common example is to store the password in the database with MD5 encryption instead of the original plaintext password.
The code is as follows:
$ Query = sprintf ("insert into users (name, pwd) VALUES ('% s',' % s ');",
Addslashes ($ username), md5 ($ password ));
$ Result = pg_query ($ connection, $ query );
$ Query = sprintf ("SELECT 1 FROM users WHERE name = '% s' AND pwd =' % s ';",
Addslashes ($ username), md5 ($ password ));
$ Result = pg_query ($ connection, $ query );
If (pg_num_rows ($ result)> 0 ){
Echo 'Welcome, $ username! ';
} Else {
Echo 'authentication failed for $ username .';
}
?>
4. SQL injection problems
Direct SQL command injection is a common technique used by attackers to create or modify existing SQL statements, so as to obtain hidden data or overwrite key values, even the purpose of executing database host operating system commands. This is achieved through applications that obtain user input and combine static parameters into SQL queries. The following are some examples.
The code is as follows:
$ Query = "SELECT id, name, inserted, size FROM products
WHERE size = '$ size'
Order by $ order LIMIT $ limit, $ offset ;";
$ Result = odbc_exec ($ conn, $ query );
?>
You can add another SELECT query based on the original query to obtain the password:
Union select '1', concat (uname | '-' | passwd) as name, '2017-01-01 ', '0' from usertable;
If the preceding statements (using 'and --) are added to any variable in $ query, this is troublesome.
These attacks are always based on code that lacks security awareness. Therefore, never trust external input data, especially from clients, including selection boxes, form hidden fields, and cookies. As in the first example above, even normal queries may cause disasters.
Never use a superuser or owner account to connect to a database. Use accounts with strictly limited permissions.
Check whether the input data has the expected data format. PHP has many functions that can be used to check input, from simple variable functions and character type functions (such as is_numeric (), ctype_digit ()) this can be done by using complex Perl-compatible regular expression functions.
If the program is waiting to enter a number, you can use is_numeric () to check it, or directly use settype () to convert its type, or use sprintf () to format it as a number.
A safer way to prevent SQL injection by page display:
The code is as follows:
Settype ($ offset, 'integer ');
$ Query = "SELECT id, name FROM products order by name LIMIT 20 OFFSET $ offset ;";
$ Query = sprintf ("SELECT id, name FROM products order by name LIMIT 20 OFFSET % d ;",
$ Offset );
?>