VNX-201: Insertion of Sensitive Information Into Sent Data
Reports HTTP responses that send a stored record's password, hash, secret, API key or similar field, a whole user/account record fetched from the database and serialised as is, and Django REST ModelSerializers of User with fields = '__all__'.
| Field | Value |
|---|---|
| Rule ID | VNX-201 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | Go, Java, JavaScript / TypeScript, Python |
| CWE | CWE-201 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C |
| Tags | information-leak cwe-201 |
| Source | internal/sast/rules/vnx-201.rego |
Overview
VNX-201 maps to CWE-201: Insertion of Sensitive Information Into Sent Data. An API that serialises a database record straight into a response sends every column, including the password hash, the reset token and the API key. Anyone who can call the endpoint, or read a proxy log of it, gets them.
What Gets Flagged
res.json({ id: user.id, email: user.email, password: user.password }); // flagged
const user = await User.findByPk(req.params.id);
res.json(user); // flagged
return jsonify({"id": user.id, "password_hash": user.password_hash}) # flagged
return jsonify(u.__dict__) # flagged
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = "__all__" # flagged
c.JSON(http.StatusOK, gin.H{"name": u.Name, "password": u.Password}) // flagged
return ResponseEntity.ok(Map.of("login", user.getLogin(), "password", user.getPassword())); // flagged
Not flagged: masked or constant values ("********"), derived values (password.length, password != ""), field names that only start with a sensitive word (passwordChangedAt), lookups that project fields away (.select('-password'), attributes: { exclude: [...] }), records whose password is deleted before sending, projects that hide fields from serialisation (Mongoose select: false or toJSON, Jackson @JsonIgnore, Go json:"-"), serializers with exclude or a write_only password, and comments.
Remediation
Return a response DTO with exactly the fields the client needs, or hide sensitive fields at the model:
const UserSchema = new mongoose.Schema({ email: String, password: { type: String, select: false } });
res.json({ id: user.id, email: user.email });
type User struct {
Name string `json:"name"`
Password string `json:"-"`
}
References
- CWE-201: Insertion of Sensitive Information Into Sent Data
- OWASP API3:2023 Broken Object Property Level Authorization
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-201
// nosec vnx-201
Or record an ignore rule: vulnetix ignore add --rule vnx-201 --reason "...". See Suppressing findings.