Customize rulesets (ULTIMATE)
- Introduced in GitLab 13.5.
- Added support for passthrough chains. Expanded to include additional passthrough types of
file
,git
, andurl
in GitLab 14.6.- Added support for overriding rules in GitLab 14.8.
You can customize the default scanning rules provided by our SAST analyzers. Ruleset customization supports the following that can be used simultaneously:
- Disabling predefined rules. Available for all analyzers.
- Overriding predefined rules. Available for all analyzers.
- Modifying the default behavior of a given analyzer by synthesizing and passing a custom configuration. Available for only
nodejs-scan
,gosec
, andsemgrep
.
To customize the default scanning rules, create a file containing custom rules. These rules are passed through to the analyzer's underlying scanner tools.
To create a custom ruleset:
- Create a
.gitlab
directory at the root of your project, if one doesn't already exist. - Create a custom ruleset file named
sast-ruleset.toml
in the.gitlab
directory.
Disable predefined analyzer rules
To disable analyzer rules:
-
Set the
disabled
flag totrue
in the context of aruleset
section -
In one or more
ruleset.identifier
sub sections, list the rules that you want disabled. Everyruleset.identifier
section has:
- a
type
field, to name the predefined rule identifier that the targeted analyzer uses. - a
value
field, to name the rule to be disabled.
Example: Disable predefined rules of SAST analyzers
In the following example, the disabled rules are assigned to eslint
and sobelow
by matching the type
and value
of identifiers:
[eslint]
[[eslint.ruleset]]
disable = true
[eslint.ruleset.identifier]
type = "eslint_rule_id"
value = "security/detect-object-injection"
[[eslint.ruleset]]
disable = true
[eslint.ruleset.identifier]
type = "cwe"
value = "185"
[sobelow]
[[sobelow.ruleset]]
disable = true
[sobelow.ruleset.identifier]
type = "sobelow_rule_id"
value = "sql_injection"
Those vulnerabilities containing the provided type and value are now disabled, meaning they won't be displayed in Merge Request nor the Vulnerability Report.
Override predefined analyzer rules
To override analyzer rules:
-
In one or more
ruleset.identifier
subsections, list the rules that you want to override. Everyruleset.identifier
section has:- a
type
field, to name the predefined rule identifier that the targeted analyzer uses. - a
value
field, to name the rule to be overridden.
- a
-
In the
ruleset.override
context of aruleset
section, provide the keys to override. Any combination of keys can be overridden. Valid keys are:- description
- message
- name
- severity (valid options are: Critical, High, Medium, Low, Unknown, Info)
Example: Override predefined rules of SAST analyzers
Before adding a ruleset, we verify which vulnerability will be overwritten by viewing the gl-sast-report.json
:
"identifiers": [
{
"type": "gosec_rule_id",
"name": "Gosec Rule ID G307",
"value": "G307"
},
{
"type": "CWE",
"name": "CWE-703",
"value": "703",
"url": "https://cwe.mitre.org/data/definitions/703.html"
}
]
In the following example, rules from gosec
are matched by the type
and value
of identifiers and then overridden:
[gosec]
[[gosec.ruleset]]
[gosec.ruleset.identifier]
type = "CWE"
value = "703"
[gosec.ruleset.override]
severity = "Critical"
If a vulnerability is found with a type CWE
with a value of 703
then
the vulnerability severity is overwritten to Critical
.
Synthesize a custom configuration
To create a custom configuration, you can use passthrough chains.
A passthrough is a single step in a passthrough chain. The passthrough is evaluated in a sequence to incrementally build a configuration. The configuration is then passed to the target analyzer.
A configuration section for an analyzer has the following parameters:
Parameter | Explanation |
---|---|
description |
Description about the analyzer configuration section. |
targetdir |
The targetdir parameter defines the directory where the final configuration is located. If targetdir is empty, the analyzer uses a random directory. The maximum size of targetdir is 100MB. |
validate |
If set to true , the target files for passthroughs (raw , file and url ) are validated. The validation works for yaml , xml , json and toml files. The proper validator is identified based on the extension of the target file. By default, validate is set to false . |
interpolate |
If set to true , environment variable interpolation is enabled so that the configuration uses secrets/tokens. We advise using this feature with caution to not leak any secrets. By default, interpolate is set to false . |
timeout |
The total timeout for the evaluation of a passthrough chain is set to 60 seconds. If timeout is not set, the default timeout is 60 seconds. The timeout cannot exceed 300 seconds. |
A configuration section can include one or more passthrough sections. The maximum number of passthrough sections is 20. There are several types of passthroughs:
Type | Description |
---|---|
file |
Use a file that is already available in the Git repository. |
raw |
Provide the configuration inline. |
git |
Pull the configuration from a remote Git repository. |
url |
Fetch the analyzer configuration through HTTP. |
If multiple passthrough sections are defined in a passthrough chain, their position in the chain defines the order in which they are evaluated.
- Passthroughs listed later in the chain sequence have a higher precedence.
- Passthroughs with a higher precedence overwrite (default) and append data yielded by previous passthroughs. This is useful for cases where you need to use or modify an existing configuration.
Configure a passthrough these parameters:
Parameter | Explanation |
---|---|
type |
One of file , raw , git or url . |
target |
The target file that contains the data written by the passthrough evaluation. If no value is provided, a random target file is generated. |
mode |
overwrite : if target exists, overwrites the file; append : append to file instead. The default is overwrite . |
ref |
This option only applies to the git passthrough type and contains the name of the branch or the SHA to be used. |
subdir |
This option only applies to the git passthrough type and can be used to only consider a certain subdirectory of the source Git repository. |
value |
For the file url and git types, value defines the source location of the file/Git repository; for the raw type, value carries the raw content to be passed through. |
validator |
Can be used to explicitly invoke validators (xml , yaml , json , toml ) on the target files after the application of a passthrough. Per default, no validator is set. |
The amount of data generated by a single passthrough is limited to 1MB.
Passthrough configuration examples
Raw passthrough for nodejs-scan
Define a custom analyzer configuration. In this example, customized rules are
defined for the nodejs-scan
scanner:
[nodejs-scan]
description = 'custom ruleset for nodejs-scan'
[[nodejs-scan.passthrough]]
type = "raw"
value = '''
- nodejs-extensions:
- .js
template-extensions:
- .new
- .hbs
- ''
ignore-filenames:
- skip.js
ignore-paths:
- __MACOSX
- skip_dir
- node_modules
ignore-extensions:
- .hbs
ignore-rules:
- regex_injection_dos
- pug_jade_template
- express_xss
'''
File passthrough for Gosec
Provide the name of the file containing a custom analyzer configuration. In
this example, customized rules for the gosec
scanner are contained in the
file gosec-config.json
:
[gosec]
description = 'custom ruleset for gosec'
[[gosec.passthrough]]
type = "file"
value = "gosec-config.json"
Passthrough chain for Semgrep
In the below example, we generate a custom configuration under the /sgrules
target directory with a total timeout
of 60 seconds.
Several passthrouh types generate a configuration for the target analyzer:
- Two
git
passthrough sections pull the head of branchrefs/remotes/origin/test
from themyrules
Git repository, and revision97f7686
from thesast-rules
Git repository. From thesast-rules
Git repository, only data from thego
subdirectory is considered.- The
sast-rules
entry has a higher precedence because it appears later in the configuration. - If there is a filename collision between files in both repositories, files
from the
sast
repository overwrite files from themyrules
repository, assast-rules
has higher precedence.
- The
- The
raw
entry creates a file namedinsecure.yml
under/sgrules
. The full path is/sgrules/insecure.yml
. - The
url
entry fetches a configuration made available through a URL and stores it in the/sgrules/gosec.yml
file.
Afterwards, Semgrep is invoked with the final configuration located under
/sgrules
.
[semgrep]
description = 'semgrep custom rules configuration'
targetdir = "/sgrules"
timeout = 60
[[semgrep.passthrough]]
type = "git"
value = "https://gitlab.com/user/myrules.git"
ref = "refs/remotes/origin/test"
[[semgrep.passthrough]]
type = "git"
value = "https://gitlab.com/gitlab-org/secure/gsoc-sast-vulnerability-rules/playground/sast-rules.git"
ref = "97f7686db058e2141c0806a477c1e04835c4f395"
subdir = "go"
[[semgrep.passthrough]]
type = "raw"
target = "insecure.yml"
value = """
rules:
- id: "insecure"
patterns:
- pattern: "func insecure() {...}"
message: |
Insecure function insecure detected
metadata:
cwe: "CWE-200: Exposure of Sensitive Information to an Unauthorized Actor"
severity: "ERROR"
languages:
- "go"
"""
[[semgrep.passthrough]]
type = "url"
value = "https://semgrep.dev/c/p/gosec"
target = "gosec.yml"
Interpolation
The code snippet below shows an example configuration that uses an environment
variable $GITURL
to access a private repositories with a Git URL. The variable contains
a username and token in the value
field (for example https://user:token@url
).
It does not explicitly store credentials in the configuration file. To reduce the risk of leaking secrets through created paths and files, use this feature with caution.
[semgrep]
description = 'semgrep custom rules configuration'
targetdir = "/sgrules"
interpolate = true
[[semgrep.passthrough]]
type = "git"
value = "$GITURL"
ref = "refs/remotes/origin/main"
Configure the append mode for passthroughs
To append data to previous passthroughs, use the append
mode for the
passthrough types file
, url
, and raw
.
Passthroughs in override
mode overwrite files
created when preceding passthroughs in the chain find a naming
collision. If mode
is set to append
, a passthrough appends data to the
files created by its predecessors instead of overwriting.
In the below Semgrep configuration,/sgrules/insecure.yml
assembles two passthroughs. The rules are:
insecure
secret
These rules add a search pattern to the analyzer and extends Semgrep capabilities.
For passthrough chains we recommend that you enable validation. To enable validation, you can either:
-
set
validate
totrue
-
set a passthrough
validator
toxml
,json
,yaml
, ortoml
.
[semgrep]
description = 'semgrep custom rules configuration'
targetdir = "/sgrules"
validate = true
[[semgrep.passthrough]]
type = "raw"
target = "insecure.yml"
value = """
rules:
- id: "insecure"
patterns:
- pattern: "func insecure() {...}"
message: |
Insecure function insecure detected
metadata:
cwe: "...
severity: "ERROR"
languages:
- "go"
"""
[[semgrep.passthrough]]
type = "raw"
mode = "append"
target = "insecure.yml"
value = """
- id: "secret"
patterns:
- pattern-either:
- pattern: "$MASK = \"...\""
- metavariable-regex:
metavariable: "$MASK"
regex: "(password|pass|passwd|pwd|secret|token)"
message: |
Use of Hard-coded Password
cwe: "..."
severity: "ERROR"
languages:
- "go"
"""