diff --git a/src/main/java/com/bartek/esa/core/di/PluginModule.java b/src/main/java/com/bartek/esa/core/di/PluginModule.java index e99daca..2786ae4 100644 --- a/src/main/java/com/bartek/esa/core/di/PluginModule.java +++ b/src/main/java/com/bartek/esa/core/di/PluginModule.java @@ -101,4 +101,10 @@ public class PluginModule { public Plugin exportedComponentsPlugin(GlobMatcher globMatcher, XmlHelper xmlHelper) { return new ExportedComponentsPlugin(globMatcher, xmlHelper); } + + @Provides + @IntoSet + public Plugin dangerousPermissionPlugin(GlobMatcher globMatcher, XmlHelper xmlHelper) { + return new DangerousPermissionPlugin(globMatcher, xmlHelper); + } } diff --git a/src/main/java/com/bartek/esa/core/plugin/DangerousPermissionPlugin.java b/src/main/java/com/bartek/esa/core/plugin/DangerousPermissionPlugin.java new file mode 100644 index 0000000..381a09b --- /dev/null +++ b/src/main/java/com/bartek/esa/core/plugin/DangerousPermissionPlugin.java @@ -0,0 +1,47 @@ +package com.bartek.esa.core.plugin; + +import com.bartek.esa.core.archetype.AndroidManifestPlugin; +import com.bartek.esa.core.model.enumeration.Severity; +import com.bartek.esa.core.xml.XmlHelper; +import com.bartek.esa.file.matcher.GlobMatcher; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.inject.Inject; +import javax.xml.xpath.XPathConstants; +import java.util.Optional; + +public class DangerousPermissionPlugin extends AndroidManifestPlugin { + + @Inject + public DangerousPermissionPlugin(GlobMatcher globMatcher, XmlHelper xmlHelper) { + super(globMatcher, xmlHelper); + } + + @Override + protected void run(Document xml) { + NodeList customPermissions = (NodeList) xPath(xml, "/manifest/permission", XPathConstants.NODESET); + stream(customPermissions) + .filter(this::isDangerousPermission) + .filter(this::doesNotHaveDescription) + .forEach(permission -> addIssue(Severity.WARNING, null, tagString(permission))); + } + + private boolean isDangerousPermission(Node permission) { + return Optional.ofNullable(permission.getAttributes().getNamedItem("android:protectionLevel")) + .map(Node::getNodeValue) + .map(v -> v.equals("dangerous")) + .orElse(false); + } + + private boolean doesNotHaveDescription(Node permission) { + Boolean doesHaveDescription = Optional.ofNullable(permission.getAttributes().getNamedItem("android:description")) + .map(Node::getNodeValue) + .map(v -> !v.isEmpty()) + .orElse(false); + + return !doesHaveDescription; + } + +} diff --git a/src/main/resources/description.properties b/src/main/resources/description.properties index a8cd05a..b73dbc1 100644 --- a/src/main/resources/description.properties +++ b/src/main/resources/description.properties @@ -107,3 +107,8 @@ com.bartek.esa.core.plugin.ExportedComponentsPlugin.PROVIDER.NO_PERMISSION=Expor The content provider is exported but not protected by any permissions. \n\ It means any malicious application could make use of data provided by the component and/or insert some new data. \n\ Consider using 'android:readPermission' and 'android:writePermission' tags and adding custom permission to protect it. + +com.bartek.esa.core.plugin.DangerousPermissionPlugin=Custom permission without description.\n\ + Custom permission with 'dangerous' protection level was found and it doesn't have any description.\n\ + As long as the permission requires user attention, he should have provided a meaningful description about\n\ + permission.