Ações da Gitea Artefactos V 4 As URLs de upload/ download assinadas podem ser reescritas para acessar uma tarefa de execução e um contexto de repositório diferente, preservando a assinatura original do HMAC. Um atacante com permissão para executar uma tarefa de Ações da Gitea pode transformar uma URL assinada para um artefato controlado pelo atacante em uma URL que lê artefatos de outro contexto de tarefa, ou escreve dados controlados pelo atacante para o contexto de envio de artefato de outra tarefa, inclusive em um repositório privado. Esta é uma vulnerabilidade com dois caminhos de exploração. - `DownloadArtifact`: artefato de cross- task/cross- repositório lido, dando `C: H`. - `UploadArtifact`: gravação de estadiamento de artefato de cross- task e mutação de metadados, dando `I: H`. A causa raiz é que o V 4 A assinatura do URL assinado do artefato é construída a partir de campos concatenados brutos sem delimitadores ou prefixos de comprimento: ``` go func (r *artifactV 4 Rotas) buildSignature(endpoint, expirs, artefactName string, taskID, artefactID int 64 ) []byte { mac:= hmac.Novo( sha 256.Novo, configuração.GetGeneralTokenSigningSecret()) mac.Write([]byte(endpoint)) mac.Write([]byte(expires)) mac.Write([]byte(artifactName)) _, _ = fmt.Fprint(mac, taskID) _, _ = fmt.Fprint(mac, artefactID) retorna mac.Sum(nil)} ``` Código afetado: `routers/api/actions/artifactsv 4.go: 164 - 171 `. Como ` ArtifactName`, `taskID` e ` ArtifactID` são concatenados sem limites, dois tuplos de URL diferentes podem produzir o mesmo entrada do HMAC. Por exemplo:.

```` texto assinado tuple: artefactName = "Artifacto- 795 - 153 " taskID = 48 artefatoID = Tuple forjado: artefactName = "Artifacto- 795 - 1 " taskID = 53 artefactID = 48 ``` O sufixo de entrada final do HMAC é idêntico. ````texto artefato- 795 - 15348 ``` O atacante não precisa saber o banco de dados do artefato alvo `artifactID`. O URL forjado do 'ArtifactID' só precisa carregar dígitos que preservem a entrada original do HMAC. Após verificação, o artefato de alvo real é procurado por tarefa/ execução/ atentação e `ArtifactName`, não pelo `ArtifactID' assinado. Os manipuladores de URL assinados não são autênticos e usam o `ArtifactV 4 Apenas Contexter()`: ```go m.Group("), func() { m.Put("UploadArtifact", r.uploadArtifact) m.Get("DownloadArtifact", r.downloadArtifact) }, ArtifactV 4 Contexter()) ```.

Código afetado: `routers/api/actions/artifactsv 4.go: 156 - 159 `. Após verificar o HMAC, `verifySignature()` confia no `taskID' controlado por URL, carrega essa tarefa, verifica que está sendo executado e retorna o `ArtifactName' controlado por URL. Ele analisa `ArtifactID` para o HMAC, mas não carrega ou liga o artefato por aquele ID assinado: ```go task, err:= actions_model.GetTaskByID(ctx, taskID)... se task.Status!= actions_model.StatusRunning {... }... retornar tarefa, artefactName, true ``` Código afetado: `routers/api/actions/artifactsv 4.go: 224 - 267 `. A busca de artefato então usa o nome de artefato selecionado por URL: ```go has, err:= db.GetEngine(ctx).Where(builder.Eq{ "run_id": runID, "run_attempt_id": runAttempID, "artifact_name": nome, }, builter.Like{"content_encoding", "%/%"}).Get(&art) ```.

Código afetado: `routers/api/actions/artifactsv 4.go: 270 - 278 `. Para download, o URL forjado atinge `downloadArtifact()`, que verifica a assinatura, resolve o artefato pelo contexto de tarefa/ execução/nome forjado, e o serve: ```go task, artefactName, ok:= r.verifySignature(ctx, "DownloadArtifact")... artefato, err:= r.getArtifactByName(ctx, task.Job.RunID, task.Job.RunAtempID, artefactName)... err = ações.BaixeArtifactV 4 Leia o armazenamento(ctx.Base, artefato) ``` Código afetado: `routers/api/actions/artifactsv 4.go: 674 - 693 `. Para carregar, o URL forjado atinge `uploadArtifact()`, que verifica a assinatura, resolve o artefato alvo pelo contexto forjado tarefa/execução/nome, anexa dados controlados pelo atacante e atualiza metadados do artefato alvo:.

```go task, artefactName, ok:= r.verifySignature(ctx, "UploadArtifact")... artefato, err:= r.getArtifactByName(ctx, task.Job.RunID, task.Job.RunAtemptedID, artefactName)... uploadLongueza, errr:= anexarUploadChunkV 3 (r.fs, ctx, artefato, artefato.RunID, artefato.FileSize)... artefato.FileComprimidoTamanho += carregadoArtfato de comprimento.FileSize += carregadoLongth... actions_model.AtualizarArtifactoByID(ctx, artefato.ID, artefato) ``` Código afetado: `routers/api/actions/artifactsv 4.go: 382 - 422 `. O PoC dinâmico reforçado também abre o objeto de armazenamento criado pelo upload forjado e verifica que os bytes controlados pelo atacante foram escritos sob a execução do alvo e o caminho de estadiamento do ID do artefato. Isto demonstra um primitivo de gravação não autorizado no contexto de upload do artefato- alvo. O PoC atual não afirma que um download finalizado já serve bytes modificados; para o caminho de integridade, o impacto confirmado é gravar o estadiamento cruzado do contexto mais a mutação de metadados do artefato. Em fluxo normal de upload de artefatos, os dados nesta área de estadiamento é o que ` FinalizeArtifact` mais tarde consome. V 4 A criação de artefatos também parece omitir a validação do nome de artefato existente: ``` go artefactName:= req.Name... artefato, err:= actions_model.CrearArtifact(ctx, ctx.ActionTask, artefactName, arquivoName, retentionDays) ```. Código afetado: `routers/api/actions/artifactsv 4.go: 309 - 337 `.

Este é um problema de endurecimento, mas não é necessário para a colisão de limites de tupla demonstrada. Os nomes de artefatos criados no PoC usam caracteres comuns, tais como letras, dígitos e guiões que normalmente seriam válidos. A causa raiz é a carga útil assinada ambígua mais a busca pós- verificação pelo contexto de tarefa/ execução/ nome selecionado por URL. A tarefa alvo deve estar sendo executada, mas essa é a janela de validade normal destes URLs assinados. O próprio exploit é um parâmetro determinístico reescrito contra o fluxo de URL do artefato ativo, por isso `AC:L` é apropriado. Mesmo que o impacto de integridade seja marcado de forma conservadora, o caminho `DownloadArtifact` demonstra de forma independente a divulgação privada de artefatos de repositório cruzado. Constrangimentos práticos. - a tarefa alvo deve estar em estado de "correr"; - o ID da tarefa alvo e o nome do artefato devem ser conhecidos ou previsíveis; - para "DownloadArtifact" em ramos mais recentes, o artefato alvo deve ser já "UploadConfirmado" enquanto a tarefa alvo ainda estiver em execução. V mais velho 4 as implementações diferem ligeiramente no gerenciamento de dados/estatuto de artefato; o PoC valida a condição específica do ramo usada por cada versão testada; - o decimal forjado `artifactID` deve analisar como `int 64 `; - o efeito de armazenamento exato depende da backend de armazenamento de artefatos configurado. O PoC local usa o caminho de armazenamento não- Azure padrão. A causa raiz ainda existe antes do gerenciamento do backend de armazenamento porque o contexto URL assinado é confuso antes de enviar/descarregar. - o exploit demonstrado se aplica quando a Gitea emitir seu próprio V 4 'UploadArtifact`/`DownloadArtifact` assinado URLs. As configurações ou backends de armazenamento que retornam URLs de backend direto devem ser avaliadas separadamente, pois podem contornar esses manipuladores de URL assinados pela Gitea. Testado contra a compra da "main" da Gitea. ``` Texto 6 a 270662690439 Cabe 8582 e 92 c 22 b 04 d 1 f 8 a 3 fe 9 ```.

Verificou versões afetadas testadas localmente. ``` texto principal 6 a 27066269 reproduzida dinâmicamente v 1.26.1 afdbd 9 b 7 c 5 reproduzida dinâmicamente v 1.25.5 f 913 d 90 ab 6 reproduzida dinâmicamente v 1.24.7 99053 ce 4 fa reproduzida dinâmicamente v 1.23.8 cccd 54999 um v reproduzido dinâmicamente 1.22.6 8 efa 1 f 6 de reproduzido dinamicamente com Go 1.22.12 Teste da cadeia de ferramentas v 1.21.11 V 4 artefactosv 4. go rota não presente em routers/ api/actions; não afetado por este V 4 o caminho URL assinado como testado ``` A menos que se indique o contrário, os fragmentos de código afetados e os números de linha acima se referem ao checkout `main` testado ` 6 a 27066269 `. Os ramos de lançamento mais antigos contêm a mesma confusão de contexto de URL vulnerável assinada e pós- verificação, mas os números de linha e os detalhes de busca de artefatos diferem ligeiramente entre as versões. Por exemplo, o código mais novo inclui `run_attemp_id` na busca do artefato, enquanto o V mais antigo 4 as implementações procuram por execução/nome/ caminho/codificação de conteúdo. Estas diferenças não afetam o primitivo de contorno- colisão demonstrado do HMAC. Para `main`, `v 1.26.1 `, e ` v 1.25.5 `, o PoC usa o `usuário privado 2 / replica 2 ` fixture e demonstra a leitura do artefato de repositório cruzado. Para ` v 1.24.7 `, ` v 1.23.8 `, e ` v 1.22.6 `, os dispositivos de teste compatíveis diferem, por isso o PoC portátil demonstra a mesma URL assinada reescrever em contextos de tarefa/execução; ` v 1.22.6 ` cria o artefato alvo dentro do teste porque essa versão não inclui o arquivo de fixação do artefato mais recente. O impacto da divulgação de repositórios privados é demonstrado nas versões com dispositivos de repositório privados adequados; em dispositivos antigos, o teste portátil confirma o mesmo contexto cruzado assinado URL reescrever primitivo, o que se aplica a alvos privados sob as mesmas condições de execução e identificação conhecida. O PoC foi adaptado por versão apenas para conta para diferenças de fixação e de cadeia de ferramentas de teste; o primitivo exploração é a mesma reescreveção do tuple URL assinado. Ambiente de teste local. - ambiente de teste de integração da Gitea. - Armazenamento de artefatos de ação local padrão, não upload direto da Azure. - Tarefas/artifícios de fixação existentes a partir dos dispositivos de teste da Gitea. - O PoC dinâmico define o estado da tarefa alvo para "correr" antes de explorar a URL, correspondendo ao requisito de URL vulnerável assinado.

``` bash cd /home/kali/gitea/pocs GITEA_REPO=/home/kali/gitea/repo GOTOOLCHAIN=auto go run./actions_artifact_v 4 _cross_task_access_dynamic_poc.go ```. O PoC dinâmico escreve um teste de integração temporária no checkout da Gitea, executa apenas aquele teste e remove o teste temporário depois. Tarefa do atacante ``` texto: 48 execução do atacante: 792 trabalho do atacante: 193 id do repositório atacante: 4 tarefa de alvo: 53 Executão do alvo: 795 tarefa de alvo: 198 repositório de alvo: usuário 2 / replica 2, id do repositório 2 artefato- alvo: artefato- 795 - 1 artefato atacante criado: artefato- 795 - 153 ``` 1. Criar um token de autorização de ações para a tarefa do atacante ` 48 `. 2. Verificar o token do atacante não pode solicitar uma URL assinada para a execução do alvo ` 795 ` através da API Twirp autenticada. 3. Criar um V controlado pelo atacante 4 artefato chamado ` artefacto- 795 - 153 `. 4. Carregue e finalize aquele artefato atacante para obter uma URL assinada legítima. 5. Reescrever a URL de download assinada: ````texto artefactName=artifact- 795 - 1 taskID= 53 artefactID= 48 ```. 6. Envie o falso final `GET` sem qualquer sinal e receba o artefato de alvo privado do `usuário' 2 / replica 2 `. 7. Reescrever a URL de upload assinada da mesma forma. 8. Envie um 'PUT...& comp=apendBlock` forjado com dados controlados pelo atacante. 9. Confirme que os metadados do artefato- alvo foram alterados pelo upload forjado. 10. Abra o bloco de estadiamento do armazenamento e confirme que contém os bytes controlados pelo atacante.

```texto fonte=/home/kali/gitea/repo ok code.gitea.io/gitea/tests/integration 9.069 s reproduzido: a tarefa do atacante não pode solicitar um URL assinado com o alvo executado através do método Twirp autenticado reproduzido: o atacante- criou V 4 URL assinado mantém o HMAC após a tarefa ID/artifictName/artifictID reescrever reproduzido: GET final não autenticado retorna o artefato de alvo selecionado por URL em vez do conteúdo do atacante reproduzido: UploadArtifact URL forjado escreve bytes controlados pelo atacante em arranque de alvo/artifict estading storage e altera metadados de alvo do artefato condição=atacker pode executar uma tarefa de ação da Gitea e identificadores de tarefa/artifict são conhecidos enquanto a tarefa de alvo está executando cvss_ candidate= CVSS: 3.1 /AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N ``` Comandos de teste de versão de exemplo. ``` bash cd /home/kali/gitea/pocs GITEA_REPO=/home/kali/gitea/version-tests/gitea-v 1.26.1 ir executar./actions_artifact_v 4 _cross_task_access_dynamic_poc.go GITEA_REPO=/home/kali/gitea/version-tests/gitea-v 1.25.5 ir executar./actions_artifact_v 4 _cross_task_access_dynamic_poc.go GITEA_REPO=/home/kali/gitea/version-tests/gitea-v 1.24.7 ir executar./actions_artifact_v 4 _cross_task_access_dynamic_poc.go GITEA_REPO=/home/kali/gitea/version-tests/gitea-v 1.23.8 ir executar./actions_artifact_v 4 _cross_task_access_dynamic_poc.go GITEA_REPO=/home/kali/gitea/version-tests/gitea-v 1.22.6 GITEA_TEST_GOTOOLCHAIN=go 1.22.12 ir executar./actions_artifact_v 4 _cross_task_access_dynamic_poc.go ``` Algumas árvores de lançamento requerem um binário local `gitea` antes de se executarem os testes de integração: ``` bash cd /path/ to/gitea- release-worktree vai construir -tags 'sqlite sqlite_unlock_notify' -o gitea. ``` Este é um cruzamento de tarefas e de autorização de repositório cruzado no manuseio de artefatos de Ações da Gitea.

Um atacante que pode executar uma tarefa de Ações pode obter um V válido 4 artefato assinado URL para a sua própria tarefa, reescrever sem invalidar o HMAC, e fazer o servidor operar em outro contexto de tarefa em execução. Os usuários impactados são instâncias da Gitea com ações ativadas e V 4 manipulação de URL assinada de artefato em uso. Os repositórios privados são impactados porque os manipuladores de URL assinados não remarcam o acesso ao repositório após reconstruir o contexto de tarefa a partir dos parâmetros de URL. - Confidencialidade: leia artefatos de uma tarefa de execução de alvo em um repositório privado. - Integridade: escreva dados de artefatos controlados pelo atacante no armazenamento de execução/ artéria de estadiamento de alvo e mute metadados de artefatos de alvo. Isto pode expor saídas de compilação, registros ou artefatos empacotados armazenados como artefatos de fluxo de trabalho, e pode interferir com o envio de artefatos em voo. Dependendo do fluxo de upload/finalização do alvo, ele pode envenenar os dados de artefatos consumidos por etapas posteriores do fluxo de trabalho, liberar a automação, tarefas de implantação ou usuários a jusante. - Assine uma carga útil estruturada canônica, como JSON/ protobuf ou campos prefixados com comprimento, em vez de concatenar valores brutos. Uma carga útil versada é preferível, por exemplo `HMAC(versionїї canonical_payload)`. - Incluir e executar o endpoint, caducidade, ID de tarefa, ID de artefato, nome de artefato, ID de execução, ID de tentativa de execução, ID de repositório e ID do dono na carga útil assinada. - Após s.