Skip to content

Commit 8ecae8c

Browse files
committed
Draft of SONARXML-221 solution
1 parent d4db3cd commit 8ecae8c

File tree

4 files changed

+37
-3
lines changed

4 files changed

+37
-3
lines changed

sonar-xml-plugin/src/main/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheck.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,22 @@
1818

1919
import java.util.Arrays;
2020
import java.util.HashSet;
21+
import java.util.Optional;
2122
import java.util.Set;
2223
import javax.xml.xpath.XPathExpression;
2324
import org.sonar.check.Rule;
2425
import org.sonarsource.analyzer.commons.xml.XPathBuilder;
2526
import org.sonarsource.analyzer.commons.xml.XmlFile;
27+
import org.w3c.dom.Node;
2628

29+
import static org.sonar.plugins.xml.checks.security.android.Utils.ANDROID_MANIFEST_TOOLS;
2730
import static org.sonar.plugins.xml.checks.security.android.Utils.ANDROID_MANIFEST_XMLNS;
2831

2932
@Rule(key = "S5604")
3033
public class AndroidPermissionsCheck extends AbstractAndroidManifestCheck {
3134

3235
private static final String MESSAGE = "Make sure the use of \"%s\" permission is necessary.";
33-
private final XPathExpression xPathExpression = XPathBuilder.forExpression("/manifest/uses-permission/@n1:name")
36+
private final XPathExpression xPathExpression = XPathBuilder.forExpression("/manifest/uses-permission")
3437
.withNamespace("n1", ANDROID_MANIFEST_XMLNS)
3538
.build();
3639

@@ -111,12 +114,26 @@ public class AndroidPermissionsCheck extends AbstractAndroidManifestCheck {
111114
@Override
112115
protected final void scanAndroidManifest(XmlFile file) {
113116
evaluateAsList(xPathExpression, file.getDocument()).stream()
114-
.filter(node -> DANGEROUS_PERMISSIONS.contains(node.getNodeValue()))
115-
.forEach(node -> reportIssue(node, String.format(MESSAGE, simpleName(node.getNodeValue()))));
117+
.filter(node -> !hasToolsNodeRemove(node))
118+
.filter(node -> DANGEROUS_PERMISSIONS.contains(findPermissionValue(node)))
119+
.forEach(node -> reportIssue(findPermissionNode(node), String.format(MESSAGE, simpleName(findPermissionValue(node)))));
116120
}
117121

118122
private static String simpleName(String fullyQualifiedName) {
119123
return fullyQualifiedName.substring(fullyQualifiedName.lastIndexOf('.') + 1);
120124
}
121125

126+
private static Node findPermissionNode(Node node) {
127+
return node.getAttributes().getNamedItemNS(ANDROID_MANIFEST_XMLNS, "name");
128+
}
129+
130+
private static String findPermissionValue(Node node) {
131+
return findPermissionNode(node).getNodeValue();
132+
}
133+
134+
private static boolean hasToolsNodeRemove(Node node) {
135+
Node toolsNodeAttribute = node.getAttributes().getNamedItemNS(ANDROID_MANIFEST_TOOLS, "node");
136+
return Optional.ofNullable(toolsNodeAttribute).map(n -> "remove".equals(n.getNodeValue())).orElse(false);
137+
}
138+
122139
}

sonar-xml-plugin/src/main/java/org/sonar/plugins/xml/checks/security/android/Utils.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ private Utils() {
2424
}
2525

2626
public static final String ANDROID_MANIFEST_XMLNS = "http://schemas.android.com/apk/res/android";
27+
public static final String ANDROID_MANIFEST_TOOLS = "http://schemas.android.com/tools";
2728
public static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml";
2829

2930
public static boolean isAndroidManifestFile(XmlFile file) {

sonar-xml-plugin/src/test/java/org/sonar/plugins/xml/checks/security/android/AndroidPermissionsCheckTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,9 @@ void not_manifest() {
3232
SonarXmlCheckVerifier.verifyNoIssue(Paths.get("AnyFileName.xml").toString(), new AndroidPermissionsCheck());
3333
}
3434

35+
@Test
36+
void tools_node_remove() {
37+
SonarXmlCheckVerifier.verifyIssues(Paths.get("ToolsNodeRemove/AndroidManifest.xml").toString(), new AndroidPermissionsCheck());
38+
}
39+
3540
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.example.myapp">
3+
4+
<!-- Compliant -->
5+
<uses-permission android:name="android.permission.ACCEPT_HANDOVER" tools:node="remove"/>
6+
7+
<!-- Noncompliant@+1 {{Make sure the use of "ACCESS_BACKGROUND_LOCATION" permission is necessary.}} -->
8+
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
9+
<!-- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -->
10+
11+
</manifest>

0 commit comments

Comments
 (0)