Secure Code Review #1: Basics (Getting Started)
When it comes to software engineering, you may often hear the phrase “Trust the process,” but when it comes to security, it’s more…
Secure Code Review: Basics (Getting Started)
When it comes to software engineering, you may often hear the phrase “Trust the process,” but when it comes to security, it’s more appropriate to say “Question the process.” A crucial point to question is during the code review stage.
By carefully examining the code, potential security vulnerabilities can be uncovered before they turn into costly mistakes.
Automated source code analyzers are useful but they only find low hanging vulnerabities and are not capable of looking into the serious business logic issues and improper handling.
Pre-req
- Ability to read and write in at least one coding language.
- Understadning MVC frameworks.
- Knowlege on common web attacks and mitigations.
Approach
- Defining Sources and Sinks:
- Sources: Entry points where data is received into the application, for instance, the code handling a POST/GET request.
- Sinks: Points where data is used, like a database query execution utilizing the input data.
2. Approaches to Analysis:
2.1 Top-Down Approach:
- Initiate by identifying sources.
- Trace application flows towards their respective sinks.
- Aim to uncover sensitive functionality and scrutinize controls like input validation.
2.2 Bottom-Up Approach:
- Begin with the identification of sinks.
- Trace back the application flow to its source, understanding the invocation of the vulnerable function.
- Examine filters and input sanitization mechanisms affecting the exploit payload.
3. Vulnerability Severity and Exposure:
- Bottom-Up: Often unveils higher severity vulnerabilities with lesser exposure likelihood, e.g., RCE.
- Top-Down: Likely to reveal lower severity, but more exposed vulnerabilities like XSS.
4. Ultimate Objectives:
- Detecting vulnerabilities or logic errors.
- Understanding how to invoke vulnerable code.
- Circumventing restrictions to exploit identified vulnerabilities.
How/Where to look for security Bugs
- Check for input sanitization in the code. Start from the source and check for it till it goes to the sink.
- Check for injection when there is a use of databases or there is an OS command.
- Audit the business logic of the application.
- Look for program-specific vulnerabilities such as buffer overflow in c/c++, Unsafe Deserialization, and Type Confusion.
- Look for missing authentication in sensitive process or end points.
- Verfiy that the PII information is stored safely with encryption.
- Check for error handling.
- Look for hard corded credentials.
Vulnerable Code Examples
- XSS
- PHP
<?php
// Assume $_GET['user_input'] is some input from the user
echo $_GET['user_input'];
?>
- Java (using JSP)
<%@ page import="java.util.*" %>
<html>
<body>
<%= request.getParameter("user_input") %>
</body>
</html>
- .NET
<%@ Page Language="C#" %>
<script runat="server">
protected void Page_Load(object sender, EventArgs e) {
Response.Write(Request.QueryString["user_input"]);
}
</script>
<html>
<body>
</body>
</html>
- Node.js
const express = require('express');
const app = express();
app.set('view engine', 'ejs');
app.get('/', (req, res) => {
res.render('index', { user_input: req.query.user_input });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
<html>
<body>
<%- user_input %>
</body>
</html>
2. IDOR
- PHP
<?php
// Assuming a request to get a user's profile information
$user_id = $_GET['user_id'];
$query = "SELECT * FROM users WHERE id = '$user_id'";
$result = mysqli_query($conn, $query);
$row = mysqli_fetch_assoc($result);
echo "User Profile: " . $row['profile'];
?>
- JAVA
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserRepository userRepository;
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) {
return userRepository.findById(id).orElse(null);
}
}
- .NET
[HttpGet("{id}")]
public async Task<IActionResult> GetUser(int id)
{
var user = await _context.Users.FindAsync(id);
if (user == null)
{
return NotFound();
}
return Ok(user);
}
- Node.js
const express = require('express');
const app = express();
const users = require('./userModel');
app.get('/users/:id', (req, res) => {
const userId = req.params.id;
users.findById(userId, (err, user) => {
if (err) {
return res.status(500).send(err);
}
res.json(user);
});
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
3. RCE
- Remote Code Execution (RCE) in PHP:
- Unsafe use of
eval()
orsystem()
functions with user-controlled input.
2. RCE in Java:
- Misconfigurations or insecure deserialization with user-controlled input using libraries like Apache Commons Collections.
3. RCE in .NET:
- Insecure use of
System.Reflection
or deserialization vulnerabilities with user-controlled input.
4. RCE in Node.js:
- Misusing the
eval()
function or executing shell commands with user-controlled input usingchild_process.exec()
.
Checklist
- https://www.awesomecodereviews.com/checklists/secure-code-review-checklist/
- https://github.com/mgreiler/secure-code-review-checklist
- https://www.softwaresecured.com/secure-code-review-checklist/
- https://allabouttesting.org/50-point-checklist-for-secure-code-review/
“Code review is a skill that requires a lot of hard work. The more you are involved in the code review activity, the more you know the techniques involved. “ — link
Thanks for reading. If you want frequent updates, feel free to follow me here.
If you want to reach out to me, here is my Twitter and LinkedIn.
Signing off…