Rules / GL087
GL087 Duplicate key in a mapping
Severity: warn
OWASP: CICD-SEC-7 – Insecure System Configuration
CWE: CWE-561 – Dead Code
Risk
When a key appears twice in the same YAML mapping, GitLab keeps the last value. It loads the pipeline with Ruby's YAML.safe_load, which raises no error: the later entry silently overwrites the earlier one. The same applies to a job name defined twice: GitLab only creates the last definition.
The earlier value is dead configuration that readers and reviewers still take at face value. Most duplicates are copy-paste mistakes, but the pattern also hides changes on purpose: a harmless script: first, the real one below it, and a review of the top of the job looks fine.
What glsec checks
Every mapping in the file, at any depth: top-level keys and job names, keys inside jobs, and nested mappings such as rules: items, artifacts: or variables:, in the spec: header too. Each earlier occurrence of a key is reported at its own line, naming the line of the value GitLab uses.
glsec analyses the file as GitLab runs it: before any other rule looks at the pipeline, the earlier entries are dropped and the last value stays at its own position. A duplicate inside an anchor is reported once, at the anchor. When the earlier value carries an anchor of its own (.tpl: &a … .tpl: &b), the key is dead but the value is still used through its aliases; the message says so and suggests giving it a key of its own.
Trigger example
build:
script:
- echo "building"
script:
- make deploy
Safe alternative
build:
script:
- echo "building"
- make deploy
Not flagged
- Keys that differ in case (
Scriptandscript) or type (1and"1"): GitLab treats them as different keys too. - Merge keys (
<<: *anchor), including several in one mapping, and explicit keys that override merged ones.
See also
- GL086: script lines that YAML parses as a mapping
Documentation for glsec 1.24.0. Source of this page · Rule implementation