From dfc493bcc8523b86da03476a698ec9535e4691c8 Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Mon, 5 May 2025 13:36:11 -0500 Subject: [PATCH] PLUGINAPI-142 Modify the Plugin API to support OWASP Mobile Top 10 2024 issues --- CHANGELOG.md | 1 + .../api/server/rule/RulesDefinition.java | 39 +++++++++++++++++-- .../server/rule/internal/DefaultNewRule.java | 13 +++++++ .../rule/internal/DefaultNewRuleTest.java | 13 +++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aec324f5..f6da1cce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Deprecate `org.sonar.api.issue.DefaultTransitions` * Deprecate `org.sonar.api.web.UserRole` * Remove deprecated extension points ~~`org.sonar.api.profiles.ProfileExporter`~~ and ~~`org.sonar.api.profiles.ProfileImporter`~~. +* Introduce new security standards for OWASP Mobile 2024 ## 11.3 * Introduce `org.sonar.api.batch.sensor.SensorContext.addAnalysisData`. diff --git a/plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java b/plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java index dbca6b7b..93adb590 100644 --- a/plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java +++ b/plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java @@ -276,10 +276,34 @@ public String prefix() { } } + enum OwaspMobileTop10Version { + Y2024("2024", "owaspMobileTop10-2024"); + + private final String label; + private final String prefix; + + OwaspMobileTop10Version(String label, String prefix) { + this.label = label; + this.prefix = prefix; + } + + public String label() { + return label; + } + + public String prefix() { + return prefix; + } + } + enum OwaspTop10 { A1, A2, A3, A4, A5, A6, A7, A8, A9, A10 } + enum OwaspMobileTop10 { + M1, M2, M3, M4, M5, M6, M7, M8, M9, M10 + } + enum PciDssVersion { V3_2("3.2", "pciDss-3.2"), V4_0("4.0", "pciDss-4.0"); @@ -461,6 +485,7 @@ abstract class NewRule { /** * The Clean Code Attribute of the rule. * Providing it is optional for now, but will become mandatory in the future. + * * @since 10.1 */ public abstract NewRule setCleanCodeAttribute(CleanCodeAttribute attribute); @@ -470,7 +495,8 @@ abstract class NewRule { * For backward compatibility, one of the old method {@link #setHtmlDescription(String)} or {@link #setHtmlDescription(URL)} still * need to be called on top of that one. * Each section must have a different section key when they are non-contextual. - * As soon as one section is contextual for a section key, all sections with that key must be contextual. The pair "section key, context key" pair must still be unique. + * As soon as one section is contextual for a section key, all sections with that key must be contextual. The pair "section key, + * context key" pair must still be unique. * If several sections provide contexts, the provided context keys must be the same between sections. * * @since 9.6 @@ -484,7 +510,8 @@ abstract class NewRule { public abstract NewRule setHtmlDescription(@Nullable String s); /** - * Load description from a file available in classpath. Example : setHtmlDescription(getClass().getResource("/myrepo/Rule1234.html") + * Load description from a file available in classpath. Example : setHtmlDescription(getClass().getResource("/myrepo/Rule1234 + * .html") */ public abstract NewRule setHtmlDescription(@Nullable URL classpathUrl); @@ -498,7 +525,8 @@ abstract class NewRule { public abstract NewRule setMarkdownDescription(@Nullable String s); /** - * Load description from a file available in classpath. Example : {@code setMarkdownDescription(getClass().getResource("/myrepo/Rule1234.md")} + * Load description from a file available in classpath. Example : {@code setMarkdownDescription(getClass().getResource + * ("/myrepo/Rule1234.md")} * * @deprecated since 9.6. Use {@link #addDescriptionSection(RuleDescriptionSection)} instead */ @@ -565,6 +593,11 @@ abstract class NewRule { */ public abstract NewRule addOwaspTop10(OwaspTop10Version version, OwaspTop10... standards); + /** + * @since 11.4 + */ + public abstract NewRule addOwaspMobileTop10(OwaspMobileTop10Version owaspMobileTop10Version, OwaspMobileTop10... standards); + /** * @since 9.5 */ diff --git a/plugin-api/src/main/java/org/sonar/api/server/rule/internal/DefaultNewRule.java b/plugin-api/src/main/java/org/sonar/api/server/rule/internal/DefaultNewRule.java index 92fc5cc8..2755a04e 100644 --- a/plugin-api/src/main/java/org/sonar/api/server/rule/internal/DefaultNewRule.java +++ b/plugin-api/src/main/java/org/sonar/api/server/rule/internal/DefaultNewRule.java @@ -48,6 +48,8 @@ import org.sonar.api.server.rule.RuleDescriptionSection; import org.sonar.api.server.rule.RuleTagFormat; import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.api.server.rule.RulesDefinition.OwaspMobileTop10; +import org.sonar.api.server.rule.RulesDefinition.OwaspMobileTop10Version; import org.sonar.api.server.rule.RulesDefinition.OwaspTop10; import org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version; import org.sonar.api.server.rule.RulesDefinition.PciDssVersion; @@ -335,6 +337,17 @@ public DefaultNewRule addOwaspTop10(OwaspTop10Version owaspTop10Version, OwaspTo return this; } + @Override + public DefaultNewRule addOwaspMobileTop10(OwaspMobileTop10Version owaspMobileTop10Version, OwaspMobileTop10... standards) { + requireNonNull(owaspMobileTop10Version, "Owasp mobile version must not be null"); + + for (OwaspMobileTop10 owaspMobileTop10 : standards) { + String standard = owaspMobileTop10Version.prefix() + ":" + owaspMobileTop10.name().toLowerCase(Locale.ENGLISH); + securityStandards.add(standard); + } + return this; + } + @Override public DefaultNewRule addOwaspAsvs(OwaspAsvsVersion owaspAsvsVersion, String... requirements) { requireNonNull(owaspAsvsVersion, "OWASP ASVS version must not be null"); diff --git a/plugin-api/src/test/java/org/sonar/api/server/rule/internal/DefaultNewRuleTest.java b/plugin-api/src/test/java/org/sonar/api/server/rule/internal/DefaultNewRuleTest.java index c315c6ee..5ca12be9 100644 --- a/plugin-api/src/test/java/org/sonar/api/server/rule/internal/DefaultNewRuleTest.java +++ b/plugin-api/src/test/java/org/sonar/api/server/rule/internal/DefaultNewRuleTest.java @@ -35,6 +35,8 @@ import org.sonar.api.server.rule.RuleDescriptionSectionBuilder; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.server.rule.RulesDefinition.OwaspAsvsVersion; +import org.sonar.api.server.rule.RulesDefinition.OwaspMobileTop10; +import org.sonar.api.server.rule.RulesDefinition.OwaspMobileTop10Version; import org.sonar.api.server.rule.RulesDefinition.OwaspTop10; import org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version; import org.sonar.api.server.rule.RulesDefinition.PciDssVersion; @@ -143,6 +145,10 @@ private void assertSecurityStandards() { assertThat(rule.securityStandards()) .contains("owaspTop10:a1", "owaspTop10:a2", "owaspTop10:a4", "owaspTop10-2021:a3", "owaspTop10-2021:a5"); + rule.addOwaspMobileTop10(OwaspMobileTop10Version.Y2024, OwaspMobileTop10.M2, OwaspMobileTop10.M3); + rule.addOwaspMobileTop10(OwaspMobileTop10Version.Y2024, OwaspMobileTop10.M5); + assertThat(rule.securityStandards()).contains("owaspMobileTop10-2024:m2", "owaspMobileTop10-2024:m3", "owaspMobileTop10-2024:m5"); + rule.addPciDss(PciDssVersion.V3_2, "6.5.1"); rule.addPciDss(PciDssVersion.V3_2, "6.5"); rule.addPciDss(PciDssVersion.V4_0, "6.5.2", "6.5.10"); @@ -228,6 +234,13 @@ public void fail_if_null_owasp_version() { .hasMessage("Owasp version must not be null"); } + @Test + public void fail_if_null_owasp_mobile_version() { + assertThatThrownBy(() -> rule.addOwaspMobileTop10(null, OwaspMobileTop10.M5)) + .isInstanceOf(NullPointerException.class) + .hasMessage("Owasp mobile version must not be null"); + } + @Test public void fail_if_null_pci_dss_version() { assertThatThrownBy(() -> rule.addPciDss(null, "6.5.1"))