Frecuentemente publicamos actualizaciones de nuestra documentación. Es posible que la traducción de esta página esté en curso. Para conocer la información más actual, visita la documentación en inglés. Si existe un problema con las traducciones en esta página, por favor infórmanos.

Soporte de SARIF para escaneo de código

Para mostrar resultados de una herramienta de análisis estático de un tercero en tu repositorio de GitHub, necesitarás que tus resultados se almacenen en un archivo SARIF que sea compatible con un subconjunto específico del modelo SARIF 2.1.0 JSON para escaneo de código. Si utilizas el motor de análisis estático predeterminado de CodeQL, tus resultados se mostrarán automáticamente en tu repositorio de GitHub.

Escaneo de código is available in public repositories, and in private repositories owned by organizations with an Advanced Security license. Para obtener más información, consulta la sección "Productos de GitHub".

En este artículo

¿Te ayudó este documento?

Help us make these docs great!

All GitHub docs are open source. See something that's wrong or unclear? Submit a pull request.

Make a contribution

O, learn how to contribute.

Nota: Escaneo de código se encuentra acutalmente en beta y está sujeto a cambios. To request access to the beta, join the waitlist.

Acerca del soporte de SARIF

SARIF (Formato de Intercambio de Resultados de Análisis Estático, por sus siglas en inglés) es un Estándar de OASIS que define un formato de archivo de salida. El estándar SARIF se utiliza para optimizar la manera en el que las herramientas de análisis estático comparten sus resultados. Escaneo de código es compatible con un subconjunto del modelo SARIF 2.1.0 JSON.

Para cargar un archivo SARIF desde un motor de análisis estático de código desde un tercero, necesitaras asegurarte de que los archivos cargados utilicen la versión SARIF 2.1.0. GitHub analizará el archivo SARIF y mostrará alertas utilizando los resultados en tu repositorio como parte de la experiencia de escaneo de código. Para obtener más información, consulta la sección "Cargar un archivo SARIF a GitHub". Para obtener más información acerca del modelo SARIF 2.1.0, consulta sari-schema-2.1.0.json.

Si tu archivo SARIF no incluye partialFingerprints, este campo se calculará cuando cargues el archivo SARIF utilizando GitHub Actions. Para obtener más información, consulta la sección "Cargar un archivo SARIF a GitHub".

GitHub utiliza propiedades en el archivo SARIF para mostrar alertas. Por ejemplo, la shortDescription y fullDescription aparecen hasta arriba de una alerta de escaneo de código. La location permite a GitHub mostrar anotaciones en tu archivo de código. Para obtener más información, consulta la sección "Administrar alertas desde escaneo de código".

Si SARIF es nuevo para ti y quieres aprender más, consulta el repositorio SARIF tutorials de Microsoft.

Prevenir alertas duplicadas utilizando huellas dactilares

Cada vez que el flujo de trabajo de GitHub Actions ejecuta un nuevo escaneo de código, los resultados de cada ejecución se procesan y se agregan alertas al repositorio. Para prevenir las alertas duplicadas para el mismo problema, escaneo de código utiliza huellas dactilares para empatara los resultados a través de diversas ejecuciones para que solo aparezcan una vez en la última ejecución para la rama seleccionada.

GitHub utiliza la propiedad partialFingerprints en el estándar OASIS para detectar cuando dos resultados son lógicamente idénticos. Para obtener más información, consulta la sección "partialFingerprints property" en la documentación de OASIS.

SARIF files created by the CodeQL Analysis workflow or using the CodeQL runner include fingerprint data. If your SARIF file doesn't include partialFingerprints, the partialFingerprints field will be calculated if you upload the SARIF file using GitHub Actions. Para obtener más información, consulta la sección "Cargar un archivo SARIF a GitHub".

Propiedades compatibles de archivo de salida SARIF

Si utilizas un motor de análisis de código diferente a CodeQL, puedes revisar las propiedades SARIF compatibles para optimizar cómo aparecerán los resultados de tu análisis en GitHub.

Puedes cargar cualquier archivo de salida SARIF 2.1.0 válido, sin embargo, escaneo de código utilizará únicamente las siguientes propiedades compatibles.

Objeto sarifLog

NombreDescripción
$schemaRequerido. la URI del modelo SARIF JSON para la versión 2.1.0. Por ejemplo, https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json.
versionRequerido.Escaneo de código solo es compatible con la versión 2.1.0 de SARIF.
runs[]Requerido. Un archivo SARIF contiene un arreglo de una o más ejecuciones. Cada ejecución representa una sola ejecución de una herramienta de análisis. Para obtener más información acerca de una run, consulta el objeto run.

Objeto run

Escaneo de código utiliza el objeto run para filtrar los resultados por herramienta y proporcionar información acerca del origen de un resultado. El objeto run contienen el objeto componente de herramienta tool.driver, el cual contiene información acerca de la herramienta que generó el resultado. Cada run puede tener únicamente resultados para la herramienta de análisis.

NombreDescripción
tool.driver.nameRequerido. El nombre de la herramienta de análisis. Escaneo de código muestra el nombre en GitHub para permitirte filtrar los resultados por herramienta.
tool.driver.versionOpcional. La versión de la herramienta de análisis. Escaneo de código utiliza el número de versión para rastrear cuando los resultados pudieran haber cambiado debido al cambio de versión en la herramienta en vez de debido a un cambio del código que se analiza. Si el archivo SARIF incluye el campo semanticVersion, escaneo de código no utilizará version.
tool.driver.semanticVersionOpcional. La versión de la herramienta de análisis, especificada por el formato de Semantic Versioning 2.0. Escaneo de código utiliza el número de versión para rastrear cuando los resultados pudieran haber cambiado debido al cambio de versión en la herramienta en vez de debido a un cambio del código que se analiza. Si el archivo SARIF incluye el campo semanticVersion, escaneo de código no utilizará version. Para obtener más información, consulta la sección "Semantic Versioning 2.0.0" en la documentación de Semantic Versioning.
tool.driver.rules[]Requerido. Un arreglo de objetos reportingDescriptor que representen reglas. La herramienta de análisis utiliza reglas para encontrar problemas en el código que se analiza. Para obtener más información, consulta el objeto reportingDescriptor.
results[]Requerido. Los resultados de la herramienta de análisis. Escaneo de código muestra los resultados en GitHub. Para obtener más información, consulta el objeto result.

Objeto reportingDescriptor

NombreDescripción
idRequerido. Un identificador único para la regla. El id se referencia de otras partes del archivo SARIF y escaneo de código puede utilizarlo para mostrar las URL en GitHub.
name (nombre)Opcional. El nombre de la regla. Escaneo de código muestra el nombre para permitir que se filtren los resultados por regla en GitHub.
shortDescription.textRequerido Una descripción breve de la acción. Escaneo de código muestra la descripción corta en GitHub junto a los resultados asociados.
fullDescription.textRequerido Una descripción de la regla. Escaneo de código muestra la descripción completa en GitHub junto a los resultados asociados. La cantidad máxma de caracteres se limita a 1000.
defaultConfiguration.levelOpcional. Nivel de severidad predeterminado de la regla. Escaneo de código utiliza niveles de severidad para ayudarte a entender qué tan crítico es el resultado de una regla. El atributo level en el objeto result anular este valor. Para obtener más información, consulta el objeto result. Predeterminado: warning.
help.textRequerido. Documentación para la regla utilizando el formato de texto. Escaneo de código Muestra esta documentación de ayuda junto a los resultados asociados.
help.markdownRecomendado. Documentación para la regla utilizando el formato Markdown. Escaneo de código Muestra esta documentación de ayuda junto a los resultados asociados. Cuando help.markdown está disponible, se muestra en vez de help.text.
properties.tags[]Opcional. Un arreglo de secuencias. Escaneo de código utiliza tags para permitirte filtrar los resultados en GitHub. Por ejemplo, puedes filtrar todos los resultados que tengan la etiqueta security.
properties.precisionRecomendado. una secuencia que indica qué tan frecuentemente son verdaderos los resultados que indica esta regla. Por ejemplo, si una regla tiene una tasa alta de falsos positivos, la precisión debería ser low. Escaneo de código ordena los resultados de acuerdo con su precisión en GitHub para que aquellos con el level y la precision más altos se muestren primero. Can be one of: very-high, high, medium, or low.

result object

NombreDescripción
ruleIdOpcional. El identificador único de la regla (reportingDescriptor.id). Para obtener más información, consulta el objeto reportingDescriptor. Escaneo de código utiliza el identificador de reglas para filtrar los resultados por regla en GitHub.
ruleIndexOpcional. El índice de la regla asociada (reportingDescriptor object) en el arreglo de rules del componente de la herramienta. Para obtener más información, consulta el objeto run.
ruleOpcional. Una referencia que se utiliza para ubicar la regla (descriptor de reporte) para este resultado. Para obtener más información, consulta el objeto reportingDescriptor.
levelOpcional. La severidad del resultado. Este nivel invalida la severidad predeterminada que se define en la regla. Escaneo de código utiliza el nivel para filtrar los resultados en GitHub por severidad.
message.textRequerido. Un mensaje que describe el resultado. Escaneo de código muestra el texto del mensaje como el título del resultado. Se mostrará únicamente la primera oración del mensaje cuando el espacio visible esté limitado.
locations[]Requerido. El conjunto de ubicaciones donde se detectó el resultado. Sólo se deberá incluir una ubicación a menos de que el problema solo pueda corregirse realizando un cambio en cada ubicación especificada. Nota: Se requiere por lo menos una ubicación para que escaneo de código muestre el resultado. Escaneo de código utilizará esta propiedad para decidir qué archivo anotar con el resultado. Únicamente si se utiliza el primer valor de este arreglo. Se ignorará al resto de los otros valores.
partialFingerprintsRequerido. Un conjunto de secuencias utilizadas para rastrear la identidad única del resultado. Escaneo de código utiliza partialFingerprints para identificar con exactitud qué resultados son los mismos a través de las confirmaciones y ramas. Escaneo de código intentará utilizar partialFingerprints si es que existe. Si estás cargando un archivo SARIF de terceros con el upload-action, la acción creará un partialFingerprints para ti cuando no se incluya en el archivo SARIF. Para obtener más información, consulta "Prevenir alertas duplicadas utilizando huellas dactilares". Nota: Escaneo de código utilizará únicamente el primaryLocationLineHash.
codeFlows[].threadFlows[].locations[]Opcional. Un arreglo de objetos de location para un objeto de threadFlow, el cual describe el progreso de un programa a través de un hilo de ejecución. Un objeto de codeFlow describe un patrón de ejecución de código que se utiliza para detectar un resultado. Si se proporcionan flujos de código, escaneo de código los expandirá en GitHub para el resultado relevante. Para obtener más información, consulta el objeto location.
relatedLocations[]Un conjunto de ubicaciones relevantes para el resultado. Escaneo de código vinculará las ubicaciones cuando se incorporen en el mensaje de resultado. Para obtener más información, consulta el objeto location.
suppressions[].stateOpcional. Cuando el state se configura como accepted, escaneo de código actualizará el estado del resultado a Closed en GitHub.

Objeto location

Una ubicación dentro de un artefacto de programación, tal como un archivo en el repositorio o un archivo que se generó durante una compilación.

NombreDescripción
location.idOpcional. Un identificador único que distingue esta ubicación del resto de las ubicaciones dentro de un objeto de un único resultado.
location.physicalLocationrequerido. Identifica el artefacto y la región. Para obtener más información, consulta la physicalLocation.
location.message.textOpcional. Un mensaje relevante para la ubicación.

Objeto physicalLocation

NombreDescripción
artifactLocation.uriRequerido. Un URI que indica la ubicación de un artefacto, a menudo un archivo ya sea en el repositorio o generado durante una compilación. Si el URI es relativo, deberá ser relativo a la raíz del repositorio de GitHub que se está analizando. Por ejemplo, main.js o src/script.js son relativos a la raíz del repositorio. Si la URI es absoluta, escaneo de código puede utilizarla para revisar el artefacto y empatar archivos en el repositorio. Por ejemplo, https://github.com/github/example/blob/00/src/promiseUtils.js.
region.startLineRequerido. El número del línea para el primer caracter en la región.
region.startColumnRequerido. El número de columna del primer caracter en la región.
region.endLineRequerido. El número de línea de el último caracter en la región.
region.endColumnRequerido. El número de columna del caracter que sigue al final de la región.

Ejemplos de archivo de salida SARIF

Estos ejemplos de archivos de salida SARIF muestran las propiedades compatibles y los valores de ejemplo.

Ejemplo con las propiedades mínimas requeridas

Este archivo de salida SARIF tiene valores de ejemplo para mostrar las propiedades mínimas requeridas para que los resultados de escaneo de código funcionen como se espera. Si eliminas cualquier propiedad u omites valores, estos datos no se mostrarán correctamente ni se sincronizarán en GitHub.

{
    "$schema" : "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
    "version" : "2.1.0",
    "runs" :
    [
    {
        "tool" : {
        "driver" : {
            "name" : "Tool Name"
        }
        },
        "results" : [ {
        "message" : {
            "text" : "Result text. This result does not have a rule associated."
        },
        "locations" : [ {
            "physicalLocation" : {
            "artifactLocation" : {
                "uri" : "src/build.cmd"
            },
            "region" : {
                "startLine" : 2,
                "startColumn" : 7,
                "endColumn" : 10
            }
            }
        } ],
        "partialFingerprints" : {
            "primaryLocationLineHash" : "39fa2ee980eb94b0:1"
        }
        }]
    }       
    ]
}

Ejemplo que muestra todas las propiedades compatibles con SARIF

Este archivo de salida SARIF tiene valores ejemplo para mostrar todas las propiedades de SARIF compatibles con escaneo de código.

{
  "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
  "version": "2.1.0",
  "runs": [
    {
      "tool": {
        "driver": {
          "name": "Tool Name",
          "semanticVersion": "2.0.0",
          "rules": [
            {
              "id": "js/unused-local-variable",
              "name": "js/unused-local-variable",
              "shortDescription": {
                "text": "Unused variable, import, function or class"
              },
              "fullDescription": {
                "text": "Unused variables, imports, functions or classes may be a symptom of a bug and should be examined carefully."
              },
              "defaultConfiguration": {
                "level": "note"
              },
              "properties": {
                "tags": [
                  "maintainability"
                ],
                "precision": "very-high"
              }
            },
            {
              "id": "js/inconsistent-use-of-new",
              "name": "js/inconsistent-use-of-new",
              "shortDescription": {
                "text": "Inconsistent use of 'new'"
              },
              "fullDescription": {
                "text": "If a function is intended to be a constructor, it should always be invoked with 'new'. Otherwise, it should always be invoked as a normal function, that is, without 'new'."
              },
              "defaultConfiguration": null,
              "properties": {
                "tags": [
                  "reliability",
                  "correctness",
                  "language-features"
                ],
                "precision": "very-high"
              }
            }
          ]
        }
      },
      "results": [
        {
          "ruleId": "js/unused-local-variable",
          "ruleIndex": 0,
          "message": {
            "text": "Unused variable foo."
          },
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "main.js",
                  "uriBaseId": "%SRCROOT%",
                  "index": 0
                },
                "region": {
                  "startLine": 2,
                  "startColumn": 7,
                  "endColumn": 10
                }
              }
            }
          ],
          "partialFingerprints": {
            "primaryLocationLineHash": "39fa2ee980eb94b0:1",
            "primaryLocationStartColumnFingerprint": "4"
          }
        },
        {
          "ruleId": "js/inconsistent-use-of-new",
          "ruleIndex": 1,
          "message": {
            "text": "Function resolvingPromise is sometimes invoked as a constructor (for example [here](1)), and sometimes as a normal function (for example [here](2))."
          },
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "https://github.com/github/example/blob/0000000000000000000000000000000000000000/src/promiseUtils.js",
                  "index": 1
                },
                "region": {
                  "startLine": 2
                }
              }
            }
          ],
          "partialFingerprints": {
            "primaryLocationLineHash": "5061c3315a741b7d:1",
            "primaryLocationStartColumnFingerprint": "7"
          },
          "relatedLocations": [
            {
              "id": 1,
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "src/ParseObject.js",
                  "uriBaseId": "%SRCROOT%",
                  "index": 3
                },
                "region": {
                  "startLine": 2281,
                  "startColumn": 33,
                  "endColumn": 55
                }
              },
              "message": {
                "text": "here"
              }
            },
            {
              "id": 2,
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "src/LiveQueryClient.js",
                  "uriBaseId": "%SRCROOT%",
                  "index": 2
                },
                "region": {
                  "startLine": 166
                }
              },
              "message": {
                "text": "here"
              }
            }
          ]
        },
        {
          "message": {
            "text": "Specifying both [ruleIndex](1) and [ruleID](2) might lead to inconsistencies."
          },
          "level": "error",
          "locations": [
            {
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "full.sarif",
                  "uriBaseId": "%SRCROOT%",
                  "index": 0
                },
                "region": {
                  "startLine": 54,
                  "startColumn": 10,
                  "endLine": 55,
                  "endColumn": 25
                }
              }
            }
          ],
          "relatedLocations": [
            {
              "id": 1,
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "full.sarif"
                },
                "region": {
                  "startLine": 81,
                  "startColumn": 10,
                  "endColumn": 18
                }
              },
              "message": {
                "text": "here"
              }
            },
            {
              "id": 2,
              "physicalLocation": {
                "artifactLocation": {
                  "uri": "full.sarif"
                },
                "region": {
                  "startLine": 82,
                  "startColumn": 10,
                  "endColumn": 21
                }
              },
              "message": {
                "text": "here"
              }
            }
          ],
          "codeFlows": [
            {
              "threadFlows": [
                {
                  "locations": [
                    {
                      "location": {
                        "physicalLocation": {
                          "region": {
                            "startLine": 11,
                            "endLine": 29,
                            "startColumn": 10,
                            "endColumn": 18
                          },
                          "artifactLocation": {
                            "uriBaseId": "%SRCROOT%",
                            "uri": "full.sarif"
                          }
                        },
                        "message": {
                          "text": "Rule has index 0"
                        }
                      }
                    },
                    {
                      "location": {
                        "physicalLocation": {
                          "region": {
                            "endColumn": 47,
                            "startColumn": 12,
                            "startLine": 12
                          },
                          "artifactLocation": {
                            "uriBaseId": "%SRCROOT%",
                            "uri": "full.sarif"
                          }
                        }
                      }
                    }
                  ]
                }
              ]
            }
          ],
          "partialFingerprints": {
            "primaryLocationLineHash": "ABC:2"
          }
        }
      ],
      "newlineSequences": [
        "\r\n",
        "\n",
        "",
        "
 "
      ],
      "columnKind": "utf16CodeUnits"
    }
  ]
}

¿Te ayudó este documento?

Help us make these docs great!

All GitHub docs are open source. See something that's wrong or unclear? Submit a pull request.

Make a contribution

O, learn how to contribute.