|
| 1 | +/** |
| 2 | + * Provides YAML document classification shared across IaC YAML query families. |
| 3 | + * |
| 4 | + * This library identifies the broad document kind of a YAML document (Azure |
| 5 | + * DevOps Pipelines, Kubernetes/Helm, Compose, OpenAPI, or CloudFormation) and |
| 6 | + * excludes content that is out of scope for YAML-focused IaC queries even |
| 7 | + * though it may be reachable through the same YAML abstract syntax tree: |
| 8 | + * |
| 9 | + * - JSON files. The extractor represents JSON using the same node types as |
| 10 | + * YAML, since JSON is a syntactic subset of YAML. Callers that only intend |
| 11 | + * to analyze literal YAML syntax must not rely on node type alone. |
| 12 | + * - Azure Resource Manager (ARM) templates. ARM templates are JSON by |
| 13 | + * default (`azuredeploy.json`), but can also carry a `.yaml` extension |
| 14 | + * while keeping the ARM `$schema` marker, so the exclusion is schema-based |
| 15 | + * rather than purely extension-based. |
| 16 | + * |
| 17 | + * Terraform, HCL, and Bicep are not represented as `YamlNode`s at all in this |
| 18 | + * extractor, so no additional exclusion is required for them here. |
| 19 | + */ |
| 20 | + |
| 21 | +import iac |
| 22 | +private import codeql.iac.YAML |
| 23 | +private import codeql.iac.azure.Pipelines |
| 24 | +private import codeql.iac.helmcharts.HelmChart |
| 25 | +private import codeql.iac.compose.Compose |
| 26 | +private import codeql.iac.openapi.OpenApi |
| 27 | +private import codeql.iac.aws.CloudFormation |
| 28 | + |
| 29 | +module YamlDocumentClassification { |
| 30 | + /** |
| 31 | + * A YAML document whose source file uses a YAML extension (`.yml` or |
| 32 | + * `.yaml`), as opposed to a JSON file that happens to be representable by |
| 33 | + * the same node types. |
| 34 | + */ |
| 35 | + class YamlSyntaxDocument extends YamlNode, YamlDocument, YamlMapping { |
| 36 | + YamlSyntaxDocument() { this.getFile().getExtension() = ["yml", "yaml"] } |
| 37 | + } |
| 38 | + |
| 39 | + /** |
| 40 | + * Holds if `doc` carries the Azure Resource Manager (ARM) template schema |
| 41 | + * marker. ARM templates are out of scope for YAML-focused IaC queries even |
| 42 | + * when authored with a `.yaml` extension. |
| 43 | + */ |
| 44 | + private predicate hasArmSchemaMarker(YamlSyntaxDocument doc) { |
| 45 | + yamlToString(doc.lookup("$schema")).matches("%schema.management.azure.com%") |
| 46 | + } |
| 47 | + |
| 48 | + /** |
| 49 | + * The kind of a supported in-scope YAML document. |
| 50 | + */ |
| 51 | + class DocumentKind extends string { |
| 52 | + DocumentKind() { |
| 53 | + this = ["ado-pipeline", "kubernetes-helm", "compose", "openapi", "cloudformation"] |
| 54 | + } |
| 55 | + } |
| 56 | + |
| 57 | + /** |
| 58 | + * Holds if `doc` is a supported, in-scope YAML document of the given |
| 59 | + * `kind`. |
| 60 | + * |
| 61 | + * A document is only classified once its file extension is `.yml`/`.yaml` |
| 62 | + * and it does not carry the ARM template schema marker. Callers writing |
| 63 | + * YAML-only IaC queries should use this predicate, rather than the |
| 64 | + * underlying per-schema `Document` classes directly, so that ARM/JSON |
| 65 | + * content is consistently excluded. |
| 66 | + */ |
| 67 | + predicate isSupportedYamlDocument(YamlSyntaxDocument doc, DocumentKind kind) { |
| 68 | + not hasArmSchemaMarker(doc) and |
| 69 | + ( |
| 70 | + doc instanceof AzurePipelines::Document and kind = "ado-pipeline" |
| 71 | + or |
| 72 | + doc instanceof HelmChart::Document and kind = "kubernetes-helm" |
| 73 | + or |
| 74 | + doc instanceof Compose::Document and kind = "compose" |
| 75 | + or |
| 76 | + doc instanceof OpenApi::Document and kind = "openapi" |
| 77 | + or |
| 78 | + doc instanceof CloudFormation::Document and kind = "cloudformation" |
| 79 | + ) |
| 80 | + } |
| 81 | + |
| 82 | + /** |
| 83 | + * Gets a supported, in-scope YAML document of any kind. |
| 84 | + */ |
| 85 | + YamlSyntaxDocument getASupportedYamlDocument() { isSupportedYamlDocument(result, _) } |
| 86 | +} |
0 commit comments