Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions buggy_script.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,47 @@ def calculate_discount(price, discount)

# 2. 陷阱:使用可变对象(列表)作为默认参数
def add_item_to_cart(item, cart=[]):
"""
Append an item to a shopping cart list.

Parameters:
item: The item to add to the cart.
cart (list): List to which the item will be appended. If omitted, a module-level default list is reused, so successive calls without an explicit cart share the same list.

Returns:
list: The cart after the item has been appended.
"""
cart.append(item)
return cart

class User:
# 3. 拼写错误:初始化方法写成了 _init_ 而不是 __init__
def _init_(self, name, age):
"""
Initialize the user's name and age.

Parameters:
name (str): The user's name.
age (int): The user's age in years.
"""
self.name = name
self.age = age

def greet(self):
# 4. 类型错误:尝试将字符串和整数直接连接
"""
Prints a greeting that includes the user's name and age.

Expects self.name and self.age to be strings; concatenation with non-string types will raise a TypeError.
"""
print("Hello, I am " + self.name + " and I am " + self.age + " years old.")

def main():
"""
Run a short shop demo that prints messages and performs several example computations and loops.

This function prints a welcome message, computes a numeric expression, evaluates a conditional branch, iterates over a list of items, and computes an average. When executed as written it performs console output and may raise runtime errors such as IndexError (accessing an out-of-range list index) and ZeroDivisionError (division by zero).
"""
print("Welcome to the shop!")

# 5. 逻辑错误:运算符误用 (^ 在 Python 中是异或,不是幂运算)
Expand Down
49 changes: 35 additions & 14 deletions test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,16 @@ import (

var globalVar int // 未使用的全局变量

// 过长的函数(圈复杂度高)
// processData validates the input string and processes its comma-separated parts.
//
// For an empty input it returns an error with message "empty data"; for input
// longer than 100 bytes it returns an error with message "data too long".
// The input `data` is treated as a comma-separated list of parts. For each
// even-indexed part (0-based) it truncates the part to 10 characters if longer
// than 10, and prints "found test" if the part equals "test". For each
// odd-indexed part it prints "a", "b", "c", or "d" when the part is "a", "b",
// "c", or "d" respectively, and prints "default" for any other value. On
// successful processing it returns nil.
func processData(data string) error {
if data == "" {
return fmt.Errorf("empty data")
Expand Down Expand Up @@ -48,13 +57,14 @@ func processData(data string) error {
return nil
}

// 未处理的错误
// readFile reads the contents of the named file and returns them as a string.
// If the file cannot be read, it returns the empty string.
func readFile(filename string) string {
data, _ := ioutil.ReadFile(filename) // 错误未处理
return string(data)
}

// 拼写错误的参数名
// printMessage prints the provided message to standard output.
func printMessage(mesage string) { // 参数名拼写错误
fmt.Println(mesage)
}
Expand All @@ -68,11 +78,14 @@ func (e *myError) Error() string {
return e.msg
}

// createError returns an error whose message is "error".
func createError() error {
return &myError{msg: "error"} // 返回未导出的类型
}

// 冗余的代码
// redundantCode demonstrates several redundant or suboptimal code patterns:
// redundant type declaration for a local string, separate declaration and assignment
// for an integer, and an always-true conditional block.
func redundantCode() {
var s string = "hello" // 冗余的类型声明
fmt.Println(s)
Expand All @@ -86,37 +99,40 @@ func redundantCode() {
}
}

// 使用不安全操作
// unsafeOperation demonstrates obtaining an unsafe.Pointer to a local integer and printing that pointer.
func unsafeOperation() {
var x int = 42
ptr := unsafe.Pointer(&x)
fmt.Printf("Pointer: %v\n", ptr)
}

// 未使用的参数
// unusedParameter ignores the provided string parameter and always returns 42.
func unusedParameter(unused string) int { // 未使用的参数
return 42
}

// 魔法数字
// calculate returns the number of seconds in 100 days.
// The value is 100 * 24 * 60 * 60.
func calculate() int {
return 100 * 24 * 60 * 60 // 魔法数字
}

// 冗长的函数调用链
// longChain prints "HELLO GOLANG" after replacing "world" with "golang", trimming spaces, and converting the result to upper case.
func longChain() {
fmt.Println(strings.ToUpper(strings.TrimSpace(strings.Replace("hello world", "world", "golang", -1))))
}

// 空的错误检查
// emptyErrorCheck calls processData with the literal "test" and intentionally discards any returned error.
// It performs no action when processData returns a non-nil error.
func emptyErrorCheck() {
err := processData("test")
if err != nil { // 空的错误检查
// 什么也不做
}
}

// defer 在循环中
// deferInLoop creates ten files named test0.txt through test9.txt and writes "test" to each.
// Each file's Close is deferred, so all files remain open until deferInLoop returns.
func deferInLoop() {
for i := 0; i < 10; i++ {
file, _ := os.Create(fmt.Sprintf("test%d.txt", i))
Expand All @@ -128,23 +144,28 @@ func deferInLoop() {
// 可能的竞态条件
var counter int

// incrementCounter increments the package-level counter variable.
// It adds one to the global counter and is not safe for concurrent use.
func incrementCounter() {
counter++ // 非原子操作
}

// 使用 time.Sleep 而不是 context
// waitForCondition pauses execution for five seconds and then prints "done waiting".
// It performs a fixed-duration wait and does not observe contexts or support cancellation.
func waitForCondition() {
time.Sleep(5 * time.Second) // 应该使用context
fmt.Println("done waiting")
}

// 过长的行
// veryLongFunctionNameWithManyParameters performs a placeholder operation using multiple parameters.
// It always returns the string "result" and a nil error.
func veryLongFunctionNameWithManyParameters(param1 string, param2 int, param3 bool, param4 float64, param5 []string) (result string, err error) {
// 这是一个非常长的行,超过了通常的代码风格指南建议的80或120字符限制,应该被分解成多行以提高可读性。
return "result", nil
}

// 主函数
// main is the program entry point that runs a series of example routines demonstrating various behaviors and anti-patterns.
// It logs startup, invokes multiple helper functions (file I/O, unsafe operations, deferred calls in a loop, etc.), launches a goroutine that increments a counter without synchronization, waits for a condition, and logs completion.
func main() {
fmt.Println("Starting application...")

Expand All @@ -169,4 +190,4 @@ func main() {
veryLongFunctionNameWithManyParameters("param1", 123, true, 3.14, []string{"a", "b", "c"})

log.Println("Application finished")
}
}
54 changes: 50 additions & 4 deletions test.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,30 @@ class UserManager
// 未使用的属性 (Unused Code Rules)
private $unusedProperty;

/**
* Initialize a new UserManager instance.
*
* Intentionally empty constructor.
*/
public function __construct()
{
// 空构造函数 (Unused Code Rules)
}

// 过长的函数 (Code Size Rules) - 超过100行
/**
* Filter and return users who meet age, country, and subscription criteria.
*
* Processes the provided user records and returns those accepted by the selection
* rules (age > 18; country is 'US' with 'premium' or 'basic' subscription, or
* country is 'CA'). When $verbose is true, processing messages may be emitted.
*
* @param array $users Array of user records. Each record is expected to contain the keys
* `id`, `name`, `email`, `age`, `country`, `subscription`, and `active`.
* @param bool $verbose When true, emit processing messages for diagnostic purposes.
* @return array The list of user records that satisfy the selection criteria.
*
* Side effects: increments the global $globalCounter.
*/
public function processUserData(array $users, bool $verbose = false): array
{
// 未使用的参数 (Unused Code Rules)
Expand Down Expand Up @@ -114,7 +132,22 @@ public function processUserData(array $users, bool $verbose = false): array
return $result;
}

// 函数参数过多 (Excessive Parameter List)
/**
* Create a new user record from the provided attributes.
*
* @param string $firstName The user's first name.
* @param string $lastName The user's last name.
* @param string $email The user's email address.
* @param string $phone The user's phone number.
* @param string $address The user's street address.
* @param string $city The user's city.
* @param string $state The user's state or region.
* @param string $zipCode The user's postal or ZIP code.
* @param string $country The user's country.
* @param bool $isActive Whether the user is active.
* @param bool $isAdmin Whether the user has administrative privileges.
* @return array The created user represented as an associative array of the provided attributes.
*/
public function createUser(
string $firstName,
string $lastName,
Expand All @@ -131,7 +164,12 @@ public function createUser(
// 函数体为空 (Empty Function Body)
}

// 过深的嵌套 (Depth of Inheritance Tree)
/**
* Classifies an integer into a descriptive category based on its sign, magnitude, and parity.
*
* @param int $value The integer to classify.
* @return string "Special case" if $value is a positive even number not equal to 4; "Even number" if $value is 4; "Odd number" if $value is positive and odd; "Large number" if $value is 10 or greater; "Non-positive" if $value is zero or negative.
*/
public function nestedIfExample(int $value): string
{
if ($value > 0) {
Expand All @@ -157,6 +195,11 @@ public function nestedIfExample(int $value): string
// 未使用的类 (Unused Code Rules)
class UnusedClass
{
/**
* Echoes the literal string "I'm never called!" to the output.
*
* This method performs a direct output side effect and does not return a value.
*/
public function doSomething()
{
echo "I'm never called!";
Expand All @@ -165,6 +208,9 @@ public function doSomething()

// 匿名类 (Anonymous Class)
$anonymous = new class {
/**
* Outputs a greeting message from the anonymous class.
*/
public function greet()
{
echo "Hello from anonymous class!";
Expand Down Expand Up @@ -195,4 +241,4 @@ function unusedFunction(): void
echo "Debug mode is " . ($debugMode ? 'ON' : 'OFF');

// 结束
?>
?>
63 changes: 60 additions & 3 deletions vulnerable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,41 @@ class UserManager {
string db_password = "root";

// 3. SQL 注入 (CWE-89)
// 直接拼接字符串构建 SQL 查询是 C++ Web 后端常见的严重漏洞
/**
* @brief Builds an SQL query for a user ID and prints it.
*
* Constructs an SQL SELECT statement using the provided userId and outputs
* the resulting query string to standard output.
*
* @param userId The user identifier used to populate the WHERE clause.
*/
void queryUser(string userId) {
string query = "SELECT * FROM users WHERE id = '" + userId + "'";
cout << "Executing query: " << query << endl;
}

// 4. 命令注入 (CWE-78)
// 允许外部输入直接进入 system() 函数
/**
* @brief Executes the system ping command targeting the given IP address or hostname.
*
* @param ipAddress IP address or hostname to ping; passed directly to the system shell.
*/
void pingHost(string ipAddress) {
string cmd = "ping -c 4 " + ipAddress;
system(cmd.c_str());
}
};

/**
* @brief Copies a null-terminated C string into a fixed-size stack buffer.
*
* Copies the contents of `input` into a local 10-byte buffer using `strcpy`.
* If `input` has length greater than or equal to 10 bytes (including the null
* terminator), this will overwrite adjacent stack memory and cause undefined
* behavior.
*
* @param input Null-terminated C string to copy into the local buffer.
*/
void legacyBufferOverflow(char* input) {
char buffer[10];

Expand All @@ -39,6 +60,12 @@ void legacyBufferOverflow(char* input) {
strcpy(buffer, input);
}

/**
* @brief Demonstrates allocation of a dynamic array without guaranteed deallocation.
*
* Allocates a heap array of 100 integers and may return before releasing it,
* causing a memory leak in that early-return path.
*/
void memoryLeakAndRawPointers() {
// 6. 内存泄漏 (CWE-401)
// 使用了 new 但没有 delete
Expand All @@ -54,6 +81,16 @@ void memoryLeakAndRawPointers() {
delete[] data;
}

/**
* @brief Demonstrates iterator invalidation by modifying a vector while iterating over it.
*
* Iterates a small vector of integers and calls push_back during traversal when a specific
* element is encountered. Mutating the container while iterating may reallocate the
* underlying storage and invalidate iterators, resulting in undefined behavior or a crash.
*
* @note This function intentionally contains unsafe behavior to illustrate iterator
* invalidation (logic error).
*/
void iteratorInvalidation() {
vector<int> numbers = {1, 2, 3, 4, 5};

Expand All @@ -67,6 +104,14 @@ void iteratorInvalidation() {
}
}

/**
* @brief Generates and prints a non-cryptographic security token.
*
* Prints a time-seeded C-library `rand()` value to stdout in the form
* "Security Token: <value>".
*
* This token is not suitable for cryptographic or security-sensitive purposes.
*/
void weakRandomness() {
// 8. 弱伪随机数生成器 (CWE-338)
// srand/rand 不适合用于安全相关的随机数生成
Expand All @@ -75,6 +120,18 @@ void weakRandomness() {
cout << "Security Token: " << token << endl;
}

/**
* @brief Program entry point that invokes a set of functions demonstrating common insecure coding patterns.
*
* The function constructs a UserManager instance and, when provided a command-line argument,
* passes that argument to several helper functions which exercise vulnerabilities such as
* SQL/command injection, buffer overflow, memory-management issues, iterator invalidation,
* and weak randomness. It returns early when required input is missing.
*
* @param argc Number of command-line arguments.
* @param argv Array of command-line argument strings.
* @return int 0 on normal completion; 1 if a required command-line argument is missing.
*/
int main(int argc, char* argv[]) {
UserManager um;

Expand All @@ -98,4 +155,4 @@ int main(int argc, char* argv[]) {
int y = 100 / x;

return 0;
}
}
Loading