[apex] avoid hardcoding id's
This commit is contained in:
@ -5,7 +5,7 @@ permalink: pmd_rules_apex_security.html
|
||||
folder: pmd/rules/apex
|
||||
sidebaractiveurl: /pmd_rules_apex.html
|
||||
editmepath: ../pmd-apex/src/main/resources/rulesets/apex/security.xml
|
||||
keywords: Security, ApexSharingViolations, ApexOpenRedirect, ApexInsecureEndpoint, ApexXSSFromURLParam, ApexXSSFromEscapeFalse, ApexBadCrypto, ApexCSRF, ApexSOQLInjection, ApexCRUDViolation, ApexDangerousMethods, ApexSuggestUsingNamedCred
|
||||
keywords: Security, ApexSharingViolations, ApexOpenRedirect, ApexInsecureEndpoint, ApexXSSFromURLParam, ApexXSSFromEscapeFalse, ApexBadCrypto, ApexCSRF, ApexSOQLInjection, ApexCRUDViolation, ApexDangerousMethods, ApexSuggestUsingNamedCred, AvoidHardcodingId
|
||||
---
|
||||
## ApexBadCrypto
|
||||
|
||||
@ -412,3 +412,41 @@ public without sharing class Foo {
|
||||
<rule ref="rulesets/apex/security.xml/ApexXSSFromURLParam" />
|
||||
```
|
||||
|
||||
## AvoidHardcodingId
|
||||
|
||||
**Since:** PMD 6.0.0
|
||||
|
||||
**Priority:** Medium (3)
|
||||
|
||||
When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages, it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments, the logic can dynamically identify the proper data to operate against and not fail.
|
||||
|
||||
**This rule is defined by the following Java class:** [net.sourceforge.pmd.lang.apex.rule.security.AvoidHardcodingIdRule](https://github.com/pmd/pmd/blob/master/pmd-apex/src/main/java/net/sourceforge/pmd/lang/apex/rule/security/AvoidHardcodingIdRule.java)
|
||||
|
||||
**Example(s):**
|
||||
|
||||
``` java
|
||||
public without sharing class Foo {
|
||||
for(Account a: Trigger.new){
|
||||
//Error - hardcoded the record type id
|
||||
if(a.RecordTypeId=='012500000009WAr'){
|
||||
//do some logic here.....
|
||||
} else if(a.RecordTypeId=='0123000000095Km'){
|
||||
//do some logic here for a different record type...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**This rule has the following properties:**
|
||||
|
||||
|Name|Default Value|Description|
|
||||
|----|-------------|-----------|
|
||||
|cc_categories|[Style]|Code Climate Categories|
|
||||
|cc_remediation_points_multiplier|1|Code Climate Remediation Points multiplier|
|
||||
|cc_block_highlighting|false|Code Climate Block Highlighting|
|
||||
|
||||
**Use this rule by referencing it:**
|
||||
``` xml
|
||||
<rule ref="rulesets/apex/security.xml/AvoidHardcodingId" />
|
||||
```
|
||||
|
||||
|
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
|
||||
*/
|
||||
|
||||
package net.sourceforge.pmd.lang.apex.rule.security;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTAssignmentExpression;
|
||||
import net.sourceforge.pmd.lang.apex.ast.ASTLiteralExpression;
|
||||
import net.sourceforge.pmd.lang.apex.ast.AbstractApexNode;
|
||||
import net.sourceforge.pmd.lang.apex.rule.AbstractApexRule;
|
||||
|
||||
public class AvoidHardcodingIdRule extends AbstractApexRule {
|
||||
private static final Pattern PATTERN = Pattern.compile("^[a-zA-Z0-9]{5}[0][a-zA-Z0-9]{9,12}$", Pattern.CASE_INSENSITIVE);
|
||||
|
||||
public AvoidHardcodingIdRule() {
|
||||
setProperty(CODECLIMATE_CATEGORIES, "Security");
|
||||
setProperty(CODECLIMATE_REMEDIATION_MULTIPLIER, 100);
|
||||
setProperty(CODECLIMATE_BLOCK_HIGHLIGHTING, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object visit(ASTAssignmentExpression node, Object data) {
|
||||
findHardcodedId(node, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
private void findHardcodedId(AbstractApexNode<?> node, Object data) {
|
||||
ASTLiteralExpression literalNode = node.getFirstChildOfType(ASTLiteralExpression.class);
|
||||
|
||||
if (literalNode != null) {
|
||||
Object o = literalNode.getNode().getLiteral();
|
||||
if (o instanceof String) {
|
||||
String literal = (String) o;
|
||||
if (PATTERN.matcher(literal).matches()) {
|
||||
addViolation(data, literalNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -287,6 +287,15 @@
|
||||
<property name="cc_block_highlighting" value="false"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="rulesets/apex/security.xml/AvoidHardcodingId" message="Avoid hardcoding ID's">
|
||||
<priority>3</priority>
|
||||
<properties>
|
||||
<!-- relevant for Code Climate output only -->
|
||||
<property name="cc_categories" value="Security"/>
|
||||
<property name="cc_remediation_points_multiplier" value="20"/>
|
||||
<property name="cc_block_highlighting" value="false"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<!-- BRACES -->
|
||||
<rule ref="rulesets/apex/braces.xml/IfStmtsMustUseBraces" message="Avoid using if statements without curly braces">
|
||||
<priority>3</priority>
|
||||
|
@ -272,4 +272,31 @@ public class Foo {
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
<rule name="AvoidHardcodingId"
|
||||
since="6.0.0"
|
||||
message="Hardcoding Id's is bound to break when changing environments."
|
||||
class="net.sourceforge.pmd.lang.apex.rule.security.AvoidHardcodingIdRule"
|
||||
externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#avoidhardcodingid">
|
||||
<description>
|
||||
When deploying Apex code between sandbox and production environments, or installing Force.com AppExchange packages,
|
||||
it is essential to avoid hardcoding IDs in the Apex code. By doing so, if the record IDs change between environments,
|
||||
the logic can dynamically identify the proper data to operate against and not fail.
|
||||
</description>
|
||||
<priority>3</priority>
|
||||
<example>
|
||||
<![CDATA[
|
||||
public without sharing class Foo {
|
||||
void foo() {
|
||||
//Error - hardcoded the record type id
|
||||
if(a.RecordTypeId == '012500000009WAr'){
|
||||
//do some logic here.....
|
||||
} else if(a.RecordTypeId == '0123000000095Km'){
|
||||
//do some logic here for a different record type...
|
||||
}
|
||||
}
|
||||
}
|
||||
]]>
|
||||
</example>
|
||||
</rule>
|
||||
|
||||
</ruleset>
|
||||
|
@ -23,5 +23,6 @@ public class SecurityRulesTest extends SimpleAggregatorTst {
|
||||
addRule(RULESET, "ApexCRUDViolation");
|
||||
addRule(RULESET, "ApexDangerousMethods");
|
||||
addRule(RULESET, "ApexSuggestUsingNamedCred");
|
||||
addRule(RULESET, "AvoidHardcodingId");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,53 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<test-data
|
||||
xmlns="http://pmd.sourceforge.net/rule-tests"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://pmd.sourceforge.net/rule-tests http://pmd.sourceforge.net/rule-tests_1_0_0.xsd">
|
||||
|
||||
<test-code>
|
||||
<description>Non compliant scenario: Hardcoded Id</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void method (ID newRecordID) {
|
||||
for (Account current : listOfcounts){
|
||||
if (current.getId == 'a002400000RG1nyAAD') {
|
||||
}
|
||||
}
|
||||
method('3266sd35435sd6a');
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Compliant scenario, getting ID dynamically</description>
|
||||
<expected-problems>1</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
public void method (ID newRecordID) {
|
||||
for (Account current : listOfcounts){
|
||||
if (current.getId == newRecordID) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
otherMethod(newRecordID);
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
|
||||
<test-code>
|
||||
<description>Test for random string combinations</description>
|
||||
<expected-problems>0</expected-problems>
|
||||
<code><![CDATA[
|
||||
public class Foo {
|
||||
void foo() {
|
||||
return 'jatuatzbtazi124';
|
||||
}
|
||||
}
|
||||
]]></code>
|
||||
</test-code>
|
||||
</test-data>
|
Reference in New Issue
Block a user