CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes
Learn about CWE-915 (Improperly Controlled Modification of Dynamically-Determined Object Attributes), its security impact, exploitation methods, and prevention guidelines.
What is Improperly Controlled Modification of Dynamically-Determined Object Attributes?
• Overview: Improperly Controlled Modification of Dynamically-Determined Object Attributes (CWE-915) occurs when a software application allows input to define or change multiple attributes of an object without properly restricting which attributes can be modified. This vulnerability is often associated with mechanisms like mass assignment, autobinding, or object injection.
• Exploitation Methods:
- Attackers can exploit this vulnerability by sending requests with unexpected parameters that modify sensitive or internal object attributes.
- Common attack patterns include injecting unexpected fields into requests to alter object states in unintended ways, leading to unauthorized operations or privilege escalation.
• Security Impact:
- Direct consequences of successful exploitation include unauthorized access to sensitive data, modification of application state, and potential data corruption.
- Potential cascading effects involve unauthorized actions being performed on behalf of legitimate users, leading to further security breaches.
- Business impact can include data leaks, loss of customer trust, legal repercussions, and financial loss due to breach remediation and fines.
• Prevention Guidelines:
- Specific code-level fixes include implementing whitelisting for attributes that can be modified and using parameterized data handling functions.
- Security best practices involve conducting regular code reviews, employing thorough input validation, and ensuring the principle of least privilege is applied to object attribute modification.
- Recommended tools and frameworks include using ORM libraries with built-in attribute protection features, static analysis tools to detect vulnerabilities, and employing security-focused coding practices to limit exposure to mass assignment vulnerabilities.
Technical Details
Likelihood of Exploit: Not specified
Affected Languages: Ruby, ASP.NET, PHP, Python, Not Language-Specific
Affected Technologies: Not specified
Vulnerable Code Example
class User
attr_accessor :name, :email, :role
def initialize(name, email, role)
@name = name
@email = email
@role = role
end
end
class UserController
def update_user(user, params)
# Vulnerable code: Directly updating user attributes from params
# This allows for improper modification of sensitive attributes like 'role'
params.each do |key, value|
user.send("#{key}=", value)
end
end
end
# Example usage
user = User.new("John Doe", "john@example.com", "user")
params = { "name" => "Jane Doe", "role" => "admin" } # An attacker can modify the role here
UserController.new.update_user(user, params)
puts user.role # Outputs: admin (unexpected and potentially dangerous change)
How to fix Improperly Controlled Modification of Dynamically-Determined Object Attributes?
To fix this vulnerability, we need to strictly control which attributes of an object can be modified dynamically. Allowing unrestricted modification can lead to unauthorized changes, especially to sensitive attributes such as user roles. The best practice is to whitelist the attributes that can be safely modified and reject any others. This minimizes the risk of unauthorized access or privilege escalation.
Fixed Code Example
class User
attr_accessor :name, :email, :role
def initialize(name, email, role)
@name = name
@email = email
@role = role
end
end
class UserController
# Define a constant with the permitted attributes
PERMITTED_ATTRIBUTES = %w[name email].freeze
def update_user(user, params)
# Fixed code: Use a whitelist to control which attributes can be modified
params.each do |key, value|
if PERMITTED_ATTRIBUTES.include?(key)
user.send("#{key}=", value)
else
puts "Unauthorized attribute modification attempt: #{key}"
end
end
end
end
# Example usage
user = User.new("John Doe", "john@example.com", "user")
params = { "name" => "Jane Doe", "role" => "admin" } # Attempt to modify the role is ignored
UserController.new.update_user(user, params)
puts user.role # Outputs: user (unchanged, as expected)
In the fixed code, we introduced a PERMITTED_ATTRIBUTES
constant that defines which attributes can be modified. This approach ensures that only safe changes are allowed while attempts to modify sensitive attributes like role
are ignored and logged. This implementation helps prevent unauthorized attribute modifications and enhances the security of the application.