Entender el riesgo de las inyecciones de código
Cuando cree flujos de trabajo, acciones personalizadas y acciones compuestas, siempre debe plantearse si el código podría ejecutar entradas no fiables de atacantes. Esto puede ocurrir cuando un atacante agrega comandos y scripts malintencionados a un contexto. Cuando tu flujo de trabajo se ejecuta, estas secuencias podrían interpretarse como código que luego se ejecutará en el ejecutor.
Los atacantes pueden agregar su propio contenido malintencionado al contexto de github
, que se debe tratar como una entrada potencialmente no fiable. Normalmente, estos contextos terminan con body
, default_branch
, email
, head_ref
, label
, message
, name
, page_name
, ref
y title
. Por ejemplo: github.event.issue.title
o github.event.pull_request.body
.
Debes asegurarte de que estos valores no fluyan directamente hacia los flujos de trabajo, acciones, llamados a las API ni a cualquier otro lugar en donde se puedan itnerpretar como còdigo ejecutable. Cuando adoptas la misma postura de programaciòn defensiva que utilizaràs para cualquier otro còdigo de aplicaciones privilegiado, puedes ayudar a que la seguridad fortalezca tu uso de las GitHub Actions. Para obtener información sobre algunos de los pasos que podría realizar un atacante, consulta Referencia de uso seguro.
Adicionalmente, hay otras fuentes menos obvias de entradas no confiables, tales como los nombres de rama y las direcciones de correo electrònico, las cuales pueden ser bastante flexibles en cuestiòn de su contenido permitido. Por ejemplo, zzz";echo${IFS}"hello";#
sería un nombre de rama válido y un posible vector de ataque para un repositorio de destino.
Las siguientes secciones explican còmo puedes ayudar a mitigar el riesgo de inyecciòn de scripts.
Ejemplo de un ataque de inyecciòn de scripts
Un ataque de inyecciòn de scripts puede ocurrir directamente dentro de un script dentro de las lìneas de un flujo de trabajo. En el siguiente ejemplo, una acciòn utiliza una expresiòn para probar la validez del tìtulo de una solicitud de cambios, pero tambièn agrega el riesgo de ocasionar una inyecciòn de scripts:
- name: Check PR title
run: |
title="${{ github.event.pull_request.title }}"
if [[ $title =~ ^octocat ]]; then
echo "PR title starts with 'octocat'"
exit 0
else
echo "PR title did not start with 'octocat'"
exit 1
fi
Este ejemplo es vulnerable a la inyección de scripts, ya que el comando run
se ejecuta en un script de shell temporal en el ejecutor. Antes de que se ejecute el script, se evalúan las expresiones dentro de ${{ }}
y luego se sustituyen con los valores resultantes, que puede hacerlo vulnerable a la inyección de comandos de shell.
Para insertar comandos en este flujo de trabajo, el atacante podría crear una solicitud de incorporación de cambios denominada a"; ls $GITHUB_WORKSPACE"
:
En este ejemplo, el carácter "
se usa para interrumpir la instrucción title="${{ github.event.pull_request.title }}"
, lo que permite ejecutar el comando ls
en el ejecutor. Puede ver la salida del comando ls
en el registro:
Run title="a"; ls $GITHUB_WORKSPACE""
README.md
code.yml
example.js
Para obtener los procedimientos recomendados de protección de ejecutores, consulta Referencia de uso seguro.