Skip to content

Commit 22706bb

Browse files
SONARPY-1193 FP on rule S6304: 'Granting access to all resources' should not be raised on actions without resource-level permissions (#1305)
1 parent be08db8 commit 22706bb

File tree

9 files changed

+9056
-14
lines changed

9 files changed

+9056
-14
lines changed

its/ruling/src/test/resources/expected/python-S6304.json

Lines changed: 0 additions & 5 deletions
This file was deleted.

python-checks/src/main/java/org/sonar/python/checks/cdk/ResourceAccessPolicyCheck.java

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,23 @@
1919
*/
2020
package org.sonar.python.checks.cdk;
2121

22-
import java.util.Locale;
22+
import java.io.BufferedReader;
23+
import java.io.IOException;
24+
import java.io.InputStream;
25+
import java.io.InputStreamReader;
26+
import java.nio.charset.StandardCharsets;
27+
import java.util.ArrayList;
28+
import java.util.Collections;
29+
import java.util.HashSet;
30+
import java.util.List;
2331
import java.util.Optional;
32+
import java.util.Set;
2433
import java.util.function.Predicate;
2534
import javax.annotation.Nullable;
35+
import org.sonar.api.utils.log.Logger;
36+
import org.sonar.api.utils.log.Loggers;
2637
import org.sonar.check.Rule;
38+
import org.sonar.plugins.python.api.SubscriptionCheck;
2739
import org.sonar.plugins.python.api.tree.Expression;
2840
import org.sonar.python.checks.cdk.CdkUtils.ExpressionFlow;
2941

@@ -32,29 +44,65 @@
3244
@Rule(key = "S6304")
3345
public class ResourceAccessPolicyCheck extends AbstractIamPolicyStatementCheck {
3446

47+
private static final Logger LOG = Loggers.get(ResourceAccessPolicyCheck.class);
3548
private static final String MESSAGE = "Make sure granting access to all resources is safe here.";
3649
private static final String SECONDARY_MESSAGE = "Related effect";
50+
// visible for testing
51+
String resourceNameSensitiveAwsActions = "ResourceAccessPolicyCheck.txt";
52+
private Set<String> sensitiveAwsActions = null;
53+
54+
void init() {
55+
try {
56+
sensitiveAwsActions = new HashSet<>(loadResource(resourceNameSensitiveAwsActions));
57+
} catch (IOException e) {
58+
sensitiveAwsActions = Collections.emptySet();
59+
LOG.error("Couldn't load resource '" + resourceNameSensitiveAwsActions + "', rule [S6304] ResourceAccessPolicyCheck will be disabled.", e);
60+
}
61+
}
62+
63+
@Override
64+
public void initialize(SubscriptionCheck.Context context) {
65+
super.initialize(context);
66+
init();
67+
}
68+
69+
private static List<String> loadResource(String resourceName) throws IOException {
70+
try (InputStream is = ResourceAccessPolicyCheck.class.getResourceAsStream(resourceName)) {
71+
if (is == null) {
72+
throw new IOException("Cannot find resource file '" + resourceName + "'");
73+
}
74+
try (InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
75+
BufferedReader br = new BufferedReader(isr)) {
76+
List<String> result = new ArrayList<>();
77+
String line;
78+
while((line = br.readLine()) != null) {
79+
result.add(line);
80+
}
81+
return result;
82+
}
83+
}
84+
}
3785

3886
@Override
3987
protected void checkAllowingPolicyStatement(PolicyStatement policyStatement) {
4088
CdkUtils.ExpressionFlow actions = policyStatement.actions();
4189
CdkUtils.ExpressionFlow resources = policyStatement.resources();
4290

43-
if (resources == null || actions == null || hasOnlyKmsActions(actions)) {
91+
if (resources == null || actions == null || !isSensitiveAction(actions)) {
4492
return;
4593
}
4694

4795
Optional.ofNullable(getSensitiveExpression(resources, isWildcard()))
4896
.ifPresent(wildcard -> reportWildcardResourceAndEffect(wildcard, policyStatement.effect()));
4997
}
5098

51-
private static boolean hasOnlyKmsActions(ExpressionFlow actions) {
52-
return getSensitiveExpression(actions, notStartsWith("kms:")) == null;
99+
private boolean isSensitiveAction(ExpressionFlow actions) {
100+
return getSensitiveExpression(actions, inSensitiveSet()) != null;
53101
}
54102

55-
public static Predicate<Expression> notStartsWith(String expected) {
103+
public Predicate<Expression> inSensitiveSet() {
56104
return expression -> CdkUtils.getString(expression)
57-
.filter(str -> !str.toLowerCase(Locale.ROOT).startsWith(expected)).isPresent();
105+
.filter(sensitiveAwsActions::contains).isPresent();
58106
}
59107

60108
private static void reportWildcardResourceAndEffect(ExpressionFlow wildcard, @Nullable ExpressionFlow effect) {

0 commit comments

Comments
 (0)