Beijing Three Programmers Information Technology Co. Ltd
General Principles for Writing High-Quality Code
2024-07-03
In software engineering, writing high-quality code requires adherence to some fundamental principles and best practices. These principles aim to improve code maintainability, readability, and extensibility while reducing errors and complexity. Below are the key principles summarized from the list of common coding problems:
1. Modular Design
Modular design involves dividing a software system into independent modules, each responsible for a specific function. Modular design helps to:
1. Reduce complexity, making the code easier to understand and maintain.
2. Enhance code reusability and extensibility.
3. Decrease coupling between modules, facilitating independent modification and testing.
Example:
Splitting a large class into multiple smaller classes, each responsible for a single responsibility, such as order processing, discount application, and stock updating.
2. Single Responsibility Principle (SRP)
The Single Responsibility Principle (SRP) states that each class or module should have only one reason to change, meaning it should only have one responsibility. This reduces dependencies and coupling between modules, enhancing system flexibility.
Example:
Avoid a class handling data validation, database operations, and user notifications simultaneously. Instead, separate these responsibilities into different classes.
3. Abstraction and Encapsulation
Abstraction and encapsulation are crucial concepts in object-oriented programming. Abstraction emphasizes exposing only necessary interfaces while hiding implementation details. Encapsulation involves bundling data and methods within a class, protecting the data from external interference.
Example:
Use interfaces and abstract classes to define common behaviors and hide implementation details within subclasses. Avoid direct manipulation of a class’s internal data from outside the class.
4. Keep Code Simple
Simple code is easier to understand and maintain. Avoid unnecessary complexity and overengineering, and write only the code needed for current requirements. Minimize long functions and parameter lists, breaking down code logic into smaller, more readable parts.
Example:
Break down a long function into multiple smaller functions, each performing a single task. Use classes to encapsulate multiple parameters, reducing the number of function parameters.
5. Code Reuse and Avoiding Repetition
Code reuse is vital for improving development efficiency and code quality. By creating reusable modules, functions, or classes, you can reduce code duplication and maintenance costs.
Example:
Extract repeated code logic into standalone functions or classes to avoid duplicating the same code in multiple places.
6. Robustness and Defensive Programming
Robustness means the code can effectively handle various exceptional situations. Defensive programming involves adding necessary checks and safeguards in the code to prevent potential errors and vulnerabilities.
Example:
Check indices and references for validity before accessing arrays or objects to avoid out-of-bounds and null pointer exceptions. Use locks and synchronization mechanisms to prevent concurrency issues.
7. Interface-Oriented Programming
Interface-oriented programming refers to writing code that depends on interfaces rather than concrete implementations. This increases system flexibility and extensibility, making it easier to replace and extend different implementations.
Example:
Define common methods for database operations using an interface, and let different database implementations handle their specific logic. This allows swapping different database implementations without modifying client code.
8. Focus on Performance and Resource Management
Pay attention to code performance and resource management, ensuring the system runs efficiently while using memory and other resources judiciously. Avoid memory leaks and performance bottlenecks.
Example:
Release resources promptly after database connections and file operations to avoid resource leaks. Conduct performance analysis and optimization to ensure efficient code execution in critical paths.
9. Testing and Debugging
Testing and debugging are essential for ensuring code quality. Through unit tests, integration tests, and system tests, you can ensure the code works as expected. Use debugging tools to locate and fix issues in the code.
Example:
Write unit tests to verify the functionality of each module. Use logging and debugging tools to track and analyze runtime behavior, quickly pinpointing problems.
Summary
Following principles of modular design, single responsibility, abstraction and encapsulation, simplicity, code reuse, robustness and defensive programming, interface-oriented programming, performance and resource management, and the importance of testing and debugging can significantly improve code quality and maintainability.
Security Coding using PHP -- Write Safe Code
5. Command Injection Attack
2024-01-30
Questions
Question 1: What is Command Injection Attack?
Question 2: Which functions of PHP may cause Command Injection Attack?
Question 3: How to prevent Command Injection Attack?
Units
1. What is Command Injection Attack
2. Functions of PHP related to Command Injection Attack
3. Examples of Command Injection Attack
4. How to prevent Command Injection Attack
1. What is Command Injection Attack
Command Injection Attack refer to that, because web applications don't do enough filters to submitted data, so attackers may form special characters, post them to PHP program, then execute external applications or internal commands. By thus, the attackers may get data or network resource illegal, or even execute other attacks. The Command Injection Attach is a common vulnerability of PHP, and many famous open source PHP applications are found with this vulnerability.
2. Functions of PHP related to Command Injection Attack
(1) system
Function 'system' may be used to execute an external program and return the executed result
The usage of the function is:
string system(string command, int &return_var)
Parameter 'command' is the command to be executed, parameter 'return_val' stores the executed status
(2) exec
Function 'exec' may be used to execute an external program
The usage of the function is:
string exec (string command, array &output, int &return_var)
Parameter 'command' is the command to be executed, parameter 'output' is every line of the executed result, and parameter 'return_val' stores the executed status
(3) passthru
Function 'passthru' may be use to execute a system command and return the original executed results, expecially binary outputs
The usage of the function is:
void passthru (string command, int &return_var)
Parameter 'command' is the system command to be executed, parameter 'return_val' stores the executed status
(4) shell_exec
Function 'shell_exec' may be use to execute shell commands and return the executed results in string format
The usage of the function is:
string shell_exec (string command)
Parameter 'command' is the shell command to be executed
(5) `` operator
`` is the same as 'shell_exec', execute shell commands and return the executed results in string format
The usage of the operator is:
``
Parameter 'command' is the shell command to be executed
(6) eval
Function 'eval' will use parameter as PHP code to execute. User may save PHP code in string format, then execute it by pass to 'eval'
The usage of the function is:
mixed eval(string $code_str)
Parameter 'code_str' is PHP code which will be executed, in string format
(7) preg_replace
Function 'preg_replace' execute a regural expression find and replace
The usage of the function is:
mixed preg_replace ( mixed , mixed , mixed )
Parameter 'pattern' is the search mode, mode 'e' may cause command injection attack
(8) str_replace
Function 'str_replace' may be use to replace strings
The usage of the function is:
mixed str_replace ( mixed $search , mixed $replace , mixed $subject)
Parameter 'search' is the string to be searched, parameter 'replace' is the string to be replaced, and parameter 'subject' is the string to be execute the replace
(9) call_user_func
Function 'call_user_func' use the first parameter as a function to execute, the rest parameters are treated as the parameters of the executed function
The usage of the function is:
mixed call_user_func ( callable $callback [, mixed $parameter [, mixed $... ]] )
Parameter 'callback' is the function to be executed
3. Examples of Command Injection Attack
3.1. Examples for functions that may execute system commands directly, such as 'system', 'exec', 'passthru', 'shell_exec', '``'
The parameters of such functions are all have a 'command'. The 'command' can execute system command directly. So the attacks of these functions are simily.
For example:
User pass in a directory name, then list files in the directory:
<?php
$dir = $_GET[“dir”]; //the directory name user passed in
system(“dir ” . $dir);
?>
When $dir is passed by user is: '|cat /etc/passwd', the actual executed command is as following:
system(“dir |cat /etc/passwd”), Thus the should be kept secret '/etc/passwd' is let out to the attacker
3.2. Examples for fuctions that may execute PHP function, such as 'eval', 'preg_replace', 'str_replace', 'call_user_func'
Such function are all can execute PHP statements and functions directly, so the attacks of these functions are simily.
For example:
Execute a statement input by the user:
<?php
$cmd = $_GET[“cmd”]; //the statement the user input
eval($cmd);
?>
When user input $cmd as phpinfo(), the actual executed statement is:
eval(phpinfo()), so many important informations of phpinfo are let out to the cracker
Another example, this is one line in a famous open source CMS:
@eval(file_get_contents('php://input'));
php://input is an inpu stream, user can use POST to get the original data. So the content of the execute may be controller by POST, then when we POST phpinfo() to it, it will execute phpinfo() directly. Thus the attack is executed successfully.
4. How to prevent Command Injection Attack
1. Do not execute external commands and applications as far as possible. When in need, use builtin PHP functions instead. For example, don't use 'shell("rm 1.txt") to remove a file, use 'unlink("1.txt") instead.
2. If you must to use an external commands or applications, make sure you know what's the passed in parameters actually means. Don't use $_GET, $_POST directly without any check, don't give the attacker any opportunity to attack your system.
For example:
<?php
$cmd = $_GET[“cmd”]; //the command the user passed in
eval($cmd);
?>
For this example, we can check where the cmd is in our allowed list before we execute 'eval($cmd)'. Only when the check is passed can we execute it.
<?php
$cmd = $_GET[“cmd”]; //the command the user passwe in
$allow_cmds = array(“getdate”); //command lists that are allowed to execute
if(in_array($cmd, $allow_cmds)){ //only in the command lists can we execute it
eval($cmd);
}
?>
3. If you must execute any thing passed by the user using $_GET or $_POST, you should use function 'escapeshellarg' to handle with the parameters. Function 'escapeshellarg' will add a single quote to the command, and will escape any existing single quotes. So the result may be passed to function 'shell' safely. For example:
<?php
$dir = $_GET[“dir”]; //the directory name user passed in
system(escapeshellarg(“dir ” . $dir));
?>
When passed by user is '|cat /etc/passwd', the actual command is:
system(escapeshellarg(“dir |cat /etc/passwd”)), thus, the PHP handler may deal with it correctly, and it won't let out the /etc/passwd file.
4. Use 'safe_mode_exec_dir' to set safe execute directory. Firstly, set 'safe_mode' in php.ini to On, then put all command files you want to execute into a directory, then set 'safe_mode_exec_dir' point to that directory. When execute external commands within PHP code, all external files must within the 'safe_mode_exec_dir' directory, or the execute will fail.
Follow us at WeChat to get more info