From 8751252388b956072398263683892104fbaa3b9a Mon Sep 17 00:00:00 2001
From: tomasz-tylenda-sonarsource
With Spring, when a request mapping method is configured to accept bean objects as arguments, the framework will automatically bind HTTP parameters
-to those objects' properties. If the targeted beans are also persistent entities, the framework will also store those properties in the storage
-backend, usually the application’s database. Mass assignment occurs when a framework automatically binds user-controlled input to objects that are directly persisted to a database backend. If
+the application does not restrict which fields are writable, an attacker can inject additional properties into a request to overwrite sensitive
+data—such as authorization levels, ownership, or workflow states. This lack of filtering allows internal server-managed properties to be externally
+modified through a single, unfiltered write operation. By accepting persistent entities as method arguments, the application allows clients to manipulate the object’s properties directly. Because the application does not enforce which fields are writable, an attacker can craft a request containing any document property, including
+those that are meant to be managed exclusively by the server. Fields controlling authorization, ownership, workflow state, or internal identifiers all
+become externally settable through a single unfiltered write operation. Attackers could forge malicious HTTP requests that will alter unexpected properties of persistent objects. This can lead to unauthorized
modifications of the entity’s state. This is known as a mass assignment attack. Traditionally, the explicit constructor invocation (Why is this an issue?
-What is the potential impact?
Compliant solution
Resources
Documentation
-
diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8446.json b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8446.json
index d6ac4dff41c..36df5f30fd9 100644
--- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8446.json
+++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8446.json
@@ -1,5 +1,5 @@
{
- "title": "Only one \"main\" method should be present",
+ "title": "Only one \"main\" method should be defined in a class",
"type": "CODE_SMELL",
"status": "ready",
"remediation": {
diff --git a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8447.html b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8447.html
index 48d0019aac6..66e20dc8e99 100644
--- a/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8447.html
+++ b/sonar-java-plugin/src/main/resources/org/sonar/l10n/java/rules/java/S8447.html
@@ -5,8 +5,8 @@ Why is this an issue?
super(…) or this(…)) had to be the first statement in a
constructor, forcing subclass field initialization to happen after the superclass was already constructed. If the superclass constructor calls an
overridable method, the subclass implementation will see default values (such as null, 0, or false) for its
-fields instead of the values intended by the caller. This leads to subtle bugs, `NullPointerException`s, or inconsistent object states that are
-difficult to debug.NullPointerExceptions, or inconsistent object states that
+are difficult to debug.
Move the initialization of subclass fields before the super() call. This takes advantage of flexible constructor bodies to ensure that
the subclass state is established before the superclass constructor begins its execution. Alternatively, if the method in the superclass does not need
@@ -16,10 +16,10 @@
class Super {
Super() {
- overriddenMethod();
+ foo();
}
- void overriddenMethod() {
+ void foo() {
System.out.println("Base logic");
}
}
@@ -29,11 +29,11 @@ Noncompliant code example
Sub(int x) {
super();
- this.x = x; // Noncompliant: x is uninitialized when overriddenMethod is called by Super()
+ this.x = x; // Noncompliant: x is uninitialized when foo is called by Super()
}
@Override
- void overriddenMethod() {
+ void foo() {
System.out.println(x); // Prints 0 instead of the value of x
}
}
@@ -42,10 +42,10 @@ Compliant solution
class Super {
Super() {
- overriddenMethod();
+ foo();
}
- void overriddenMethod() {
+ void foo() {
System.out.println("Base logic");
}
}
@@ -59,7 +59,7 @@ Compliant solution
}
@Override
- void overriddenMethod() {
+ void foo() {
System.out.println(x); // Prints the expected value
}
}
@@ -67,13 +67,13 @@ Compliant solution
Alternatively, if the method in the superclass does not need to be overridden, it can be marked as final or private to
prevent the issue entirely.
Noncompliant code example
-
+
class Super {
Super() {
- overriddenMethod();
+ foo();
}
- void overriddenMethod() {
+ void foo() {
System.out.println("Base logic");
}
}
@@ -83,23 +83,23 @@ Noncompliant code example
Sub(int x) {
super();
- this.x = x; // Noncompliant: x is uninitialized when overriddenMethod is called by Super()
+ this.x = x; // Noncompliant: x is uninitialized when foo is called by Super()
}
@Override
- void overriddenMethod() {
+ void foo() {
System.out.println(x); // Prints 0 instead of the value of x
}
}
Compliant solution
-
+
class Super {
Super() {
- overriddenMethod();
+ foo();
}
- final void finalMethod() {
+ final void foo() {
System.out.println("Base logic");
}
}
@@ -109,13 +109,13 @@ Compliant solution
Sub(int x) {
super();
- this.x = x; // Compliant: finalMethod is final, so it cannot be overridden and will not access uninitialized fields
+ this.x = x; // Compliant: foo is final, so it cannot be overridden and will not access uninitialized fields
}
}
Resources
Documentation
diff --git a/sonarpedia.json b/sonarpedia.json
index 1a2ce10ad22..25454a0501f 100644
--- a/sonarpedia.json
+++ b/sonarpedia.json
@@ -3,9 +3,9 @@
"languages": [
"JAVA"
],
- "latest-update": "2026-02-26T08:20:43.956169Z",
+ "latest-update": "2026-02-27T13:15:37.935044048Z",
"options": {
"no-language-in-filenames": true,
"preserve-filenames": false
}
-}
+}
\ No newline at end of file