Enforcement of proper encapsulation in coding practices
import express from 'express';
class User {
public id: number;
public name: string;
public email: string;
constructor(id: number, name: string, email: string) {
this.id = id;
this.name = name;
this.email = email;
}
}
const app = express();
app.get('/user/:id', (req, res) => {
const userId = parseInt(req.params.id);
const user = new User(userId, 'John Doe', 'johndoe@example.com');
res.json(user);
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The vulnerability in the given code is that the fields of the
User
class (
id
,
name
, and
email
) are defined as public. This violates the encapsulation principle, which states that the internal state of an object should be hidden and accessed only through methods.
By having public fields, anyone can directly access and modify the attributes of a
User
object. This can lead to unauthorized access and modification of sensitive data. For example, an attacker could modify the
id
field to gain access to another user's data or change the
email
field to impersonate another user.
To fix this vulnerability, the attributes of the
User
class should be set as private. Private attributes can only be accessed and modified within the class itself. To provide controlled access to these attributes, getter and setter methods should be implemented. These methods can enforce any necessary validation or access control logic before allowing access or modification of the attributes.
import express from 'express';
class User {
private id: number;
private name: string;
private email: string;
constructor(id: number, name: string, email: string) {
this.id = id;
this.name = name;
this.email = email;
}
getId(): number {
return this.id;
}
getName(): string {
return this.name;
}
getEmail(): string {
return this.email;
}
}
const app = express();
app.get('/user/:id', (req, res) => {
const userId = parseInt(req.params.id);
const user = new User(userId, 'John Doe', 'johndoe@example.com');
res.json({
id: user.getId(),
name: user.getName(),
email: user.getEmail()
});
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
The fixed code addresses the vulnerability of inappropriate coding practices by implementing proper encapsulation.
In the User class, the fields (id, name, and email) are now declared as private, which means they can only be accessed within the class itself. This ensures that the attributes cannot be obtained or modified directly from outside the class.
To provide controlled access to these private attributes, getter methods (getId, getName, and getEmail) are implemented. These methods allow external code, such as the route handler in this case, to retrieve the values of the private attributes.
In the route handler, when a GET request is made to '/user/:id', the user's id is extracted from the request parameters and used to create a new User object. The getter methods are then used to retrieve the user's id, name, and email, which are sent as a JSON response.
By setting the attributes as private and generating getter methods, the code ensures that the private attributes cannot be accessed or modified directly, adhering to the principle of encapsulation.