tutanus 0.12.7 → 0.12.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/dist/analysts/corrections/analyst-quick-fixes.d.ts.map +1 -1
  2. package/dist/analysts/corrections/analyst-quick-fixes.js +0 -1
  3. package/dist/analysts/corrections/analyst-quick-fixes.js.map +1 -1
  4. package/dist/analysts/corrections/analyst-scoring.d.ts.map +1 -1
  5. package/dist/analysts/corrections/analyst-scoring.js +0 -1
  6. package/dist/analysts/corrections/analyst-scoring.js.map +1 -1
  7. package/dist/analysts/github-actions/analysts/analyst-github-actions.d.ts.map +1 -1
  8. package/dist/analysts/github-actions/analysts/analyst-github-actions.js +1 -1
  9. package/dist/analysts/github-actions/analysts/analyst-github-actions.js.map +1 -1
  10. package/dist/analysts/github-actions/detectors/detector-dependencies-vulnerable.d.ts.map +1 -1
  11. package/dist/analysts/github-actions/detectors/detector-dependencies-vulnerable.js +1 -1
  12. package/dist/analysts/github-actions/detectors/detector-dependencies-vulnerable.js.map +1 -1
  13. package/dist/analysts/github-actions/detectors/detector-workflow-accessibility.d.ts.map +1 -1
  14. package/dist/analysts/github-actions/detectors/detector-workflow-accessibility.js +1 -1
  15. package/dist/analysts/github-actions/detectors/detector-workflow-accessibility.js.map +1 -1
  16. package/dist/analysts/github-actions/detectors/detector-workflow-security.d.ts.map +1 -1
  17. package/dist/analysts/github-actions/detectors/detector-workflow-security.js +1 -1
  18. package/dist/analysts/github-actions/detectors/detector-workflow-security.js.map +1 -1
  19. package/dist/analysts/github-actions/detectors/detector-workflow-trigger-unsafe.d.ts.map +1 -1
  20. package/dist/analysts/github-actions/detectors/detector-workflow-trigger-unsafe.js +1 -1
  21. package/dist/analysts/github-actions/detectors/detector-workflow-trigger-unsafe.js.map +1 -1
  22. package/dist/analysts/gitlab-ci/analysts/analyst-gitlab-ci.d.ts.map +1 -1
  23. package/dist/analysts/gitlab-ci/analysts/analyst-gitlab-ci.js +1 -1
  24. package/dist/analysts/gitlab-ci/analysts/analyst-gitlab-ci.js.map +1 -1
  25. package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-performance.d.ts.map +1 -1
  26. package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-performance.js +1 -1
  27. package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-performance.js.map +1 -1
  28. package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-security.d.ts.map +1 -1
  29. package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-security.js +1 -1
  30. package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-security.js.map +1 -1
  31. package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-structure.d.ts.map +1 -1
  32. package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-structure.js +1 -1
  33. package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-structure.js.map +1 -1
  34. package/dist/analysts/html/analysts/analyst-html.d.ts +2 -4
  35. package/dist/analysts/html/analysts/analyst-html.d.ts.map +1 -1
  36. package/dist/analysts/html/analysts/analyst-html.js.map +1 -1
  37. package/dist/analysts/react/corrections/correction-react.js.map +1 -1
  38. package/dist/analysts/shell/analysts/analyst-shell.d.ts.map +1 -1
  39. package/dist/analysts/shell/analysts/analyst-shell.js.map +1 -1
  40. package/dist/app/github/app/check-run-builder.d.ts +1 -11
  41. package/dist/app/github/app/check-run-builder.d.ts.map +1 -1
  42. package/dist/app/github/app/check-run-builder.js.map +1 -1
  43. package/dist/app/github/app/check-suite-handler.js.map +1 -1
  44. package/dist/app/github/app/seguranca.d.ts +9 -0
  45. package/dist/app/github/app/seguranca.d.ts.map +1 -0
  46. package/dist/app/github/app/seguranca.js +58 -0
  47. package/dist/app/github/app/seguranca.js.map +1 -0
  48. package/dist/app/github/app/server.d.ts.map +1 -1
  49. package/dist/app/github/app/server.js +19 -3
  50. package/dist/app/github/app/server.js.map +1 -1
  51. package/dist/app/github/app/workflow-reader.d.ts +1 -14
  52. package/dist/app/github/app/workflow-reader.d.ts.map +1 -1
  53. package/dist/app/github/app/workflow-reader.js.map +1 -1
  54. package/dist/app/github/dashboard/routes.d.ts.map +1 -1
  55. package/dist/app/github/dashboard/routes.js +15 -8
  56. package/dist/app/github/dashboard/routes.js.map +1 -1
  57. package/dist/app/github/push-analysis/report-helpers.d.ts +1 -19
  58. package/dist/app/github/push-analysis/report-helpers.d.ts.map +1 -1
  59. package/dist/app/github/push-analysis/report-helpers.js.map +1 -1
  60. package/dist/core/config/excludes-padrao.d.ts.map +1 -1
  61. package/dist/core/config/excludes-padrao.js.map +1 -1
  62. package/dist/core/messages/en/analysts/index.d.ts +1 -1
  63. package/dist/core/messages/en/analysts/index.d.ts.map +1 -1
  64. package/dist/core/messages/en/analysts/index.js +1 -1
  65. package/dist/core/messages/en/analysts/index.js.map +1 -1
  66. package/dist/core/messages/en/github/github-app-messages.d.ts +3 -0
  67. package/dist/core/messages/en/github/github-app-messages.d.ts.map +1 -1
  68. package/dist/core/messages/en/github/github-app-messages.js +3 -0
  69. package/dist/core/messages/en/github/github-app-messages.js.map +1 -1
  70. package/dist/core/messages/en/guardian/guardian-messages.d.ts +1 -0
  71. package/dist/core/messages/en/guardian/guardian-messages.d.ts.map +1 -1
  72. package/dist/core/messages/en/guardian/guardian-messages.js +1 -0
  73. package/dist/core/messages/en/guardian/guardian-messages.js.map +1 -1
  74. package/dist/core/messages/en/reports/report-messages.d.ts.map +1 -1
  75. package/dist/core/messages/en/reports/report-messages.js.map +1 -1
  76. package/dist/core/messages/ja/analysts/index.d.ts +1 -1
  77. package/dist/core/messages/ja/analysts/index.d.ts.map +1 -1
  78. package/dist/core/messages/ja/analysts/index.js +1 -1
  79. package/dist/core/messages/ja/analysts/index.js.map +1 -1
  80. package/dist/core/messages/ja/github/github-app-messages.d.ts +3 -0
  81. package/dist/core/messages/ja/github/github-app-messages.d.ts.map +1 -1
  82. package/dist/core/messages/ja/github/github-app-messages.js +3 -0
  83. package/dist/core/messages/ja/github/github-app-messages.js.map +1 -1
  84. package/dist/core/messages/ja/guardian/guardian-messages.d.ts +1 -0
  85. package/dist/core/messages/ja/guardian/guardian-messages.d.ts.map +1 -1
  86. package/dist/core/messages/ja/guardian/guardian-messages.js +1 -0
  87. package/dist/core/messages/ja/guardian/guardian-messages.js.map +1 -1
  88. package/dist/core/messages/ja/reports/report-messages.d.ts.map +1 -1
  89. package/dist/core/messages/ja/reports/report-messages.js.map +1 -1
  90. package/dist/core/messages/pt/analysts/index.d.ts +1 -1
  91. package/dist/core/messages/pt/analysts/index.d.ts.map +1 -1
  92. package/dist/core/messages/pt/analysts/index.js +1 -1
  93. package/dist/core/messages/pt/analysts/index.js.map +1 -1
  94. package/dist/core/messages/pt/github/github-app-messages.d.ts +3 -0
  95. package/dist/core/messages/pt/github/github-app-messages.d.ts.map +1 -1
  96. package/dist/core/messages/pt/github/github-app-messages.js +3 -0
  97. package/dist/core/messages/pt/github/github-app-messages.js.map +1 -1
  98. package/dist/core/messages/pt/guardian/guardian-messages.d.ts +1 -0
  99. package/dist/core/messages/pt/guardian/guardian-messages.d.ts.map +1 -1
  100. package/dist/core/messages/pt/guardian/guardian-messages.js +1 -0
  101. package/dist/core/messages/pt/guardian/guardian-messages.js.map +1 -1
  102. package/dist/core/messages/pt/reports/report-messages.d.ts.map +1 -1
  103. package/dist/core/messages/pt/reports/report-messages.js.map +1 -1
  104. package/dist/core/messages/zh/analysts/index.d.ts +1 -1
  105. package/dist/core/messages/zh/analysts/index.d.ts.map +1 -1
  106. package/dist/core/messages/zh/analysts/index.js +1 -1
  107. package/dist/core/messages/zh/analysts/index.js.map +1 -1
  108. package/dist/core/messages/zh/github/github-app-messages.d.ts +3 -0
  109. package/dist/core/messages/zh/github/github-app-messages.d.ts.map +1 -1
  110. package/dist/core/messages/zh/github/github-app-messages.js +3 -0
  111. package/dist/core/messages/zh/github/github-app-messages.js.map +1 -1
  112. package/dist/core/messages/zh/guardian/guardian-messages.d.ts +1 -0
  113. package/dist/core/messages/zh/guardian/guardian-messages.d.ts.map +1 -1
  114. package/dist/core/messages/zh/guardian/guardian-messages.js +1 -0
  115. package/dist/core/messages/zh/guardian/guardian-messages.js.map +1 -1
  116. package/dist/core/messages/zh/reports/report-messages.d.ts.map +1 -1
  117. package/dist/core/messages/zh/reports/report-messages.js.map +1 -1
  118. package/dist/core/workers/worker-executor.js +1 -1
  119. package/dist/core/workers/worker-executor.js.map +1 -1
  120. package/dist/guardian/gpg.d.ts +1 -4
  121. package/dist/guardian/gpg.d.ts.map +1 -1
  122. package/dist/guardian/gpg.js +3 -0
  123. package/dist/guardian/gpg.js.map +1 -1
  124. package/dist/reports/report-structure.d.ts.map +1 -1
  125. package/dist/reports/report-structure.js.map +1 -1
  126. package/dist/shared/persistence/persistence.js.map +1 -1
  127. package/dist/types/analysts/html.d.ts +4 -0
  128. package/dist/types/analysts/html.d.ts.map +1 -0
  129. package/dist/types/analysts/html.js +2 -0
  130. package/dist/types/analysts/html.js.map +1 -0
  131. package/dist/types/analysts/index.d.ts +1 -0
  132. package/dist/types/analysts/index.d.ts.map +1 -1
  133. package/dist/types/analysts/index.js +1 -0
  134. package/dist/types/analysts/index.js.map +1 -1
  135. package/dist/types/github/app.d.ts +42 -0
  136. package/dist/types/github/app.d.ts.map +1 -1
  137. package/dist/types/github/app.js.map +1 -1
  138. package/dist/types/guardian/integrity.d.ts +4 -0
  139. package/dist/types/guardian/integrity.d.ts.map +1 -1
  140. package/dist/types/guardian/integrity.js.map +1 -1
  141. package/dist/types/index.d.ts +1 -0
  142. package/dist/types/index.d.ts.map +1 -1
  143. package/dist/types/index.js +1 -0
  144. package/dist/types/index.js.map +1 -1
  145. package/package.json +3 -1
  146. package/out/404/index.html +0 -1
  147. package/out/404.html +0 -1
  148. package/out/__next.__PAGE__.txt +0 -9
  149. package/out/__next._full.txt +0 -18
  150. package/out/__next._head.txt +0 -5
  151. package/out/__next._index.txt +0 -6
  152. package/out/__next._tree.txt +0 -3
  153. package/out/_next/static/chunks/05-c3ty_6dwfk.js +0 -1
  154. package/out/_next/static/chunks/0cz1d0mv5g_q7.js +0 -1
  155. package/out/_next/static/chunks/1061ff024jzvu.js +0 -2
  156. package/out/_next/static/chunks/14mrh2-p_w84d.js +0 -1
  157. package/out/_next/static/chunks/15orcrkp-_9ct.js +0 -4
  158. package/out/_next/static/chunks/1jiobya7ette1.js +0 -11
  159. package/out/_next/static/chunks/1jq4o6yq14o4c.js +0 -31
  160. package/out/_next/static/chunks/1rxncug86bump.js +0 -1
  161. package/out/_next/static/chunks/2n-4qa9h44lgj.js +0 -1
  162. package/out/_next/static/chunks/3n7dm2ojtyzwn.js +0 -1
  163. package/out/_next/static/chunks/3uta7d_6k863-.css +0 -1
  164. package/out/_next/static/chunks/turbopack-2xb6mmb6_q43u.js +0 -1
  165. package/out/_next/static/media/icon-1.008jpsm4iakzh.png +0 -0
  166. package/out/_next/static/rSwWA0jiTeQUXZXHLMAZ1/_buildManifest.js +0 -11
  167. package/out/_next/static/rSwWA0jiTeQUXZXHLMAZ1/_clientMiddlewareManifest.js +0 -1
  168. package/out/_next/static/rSwWA0jiTeQUXZXHLMAZ1/_ssgManifest.js +0 -1
  169. package/out/_not-found/__next._full.txt +0 -16
  170. package/out/_not-found/__next._head.txt +0 -5
  171. package/out/_not-found/__next._index.txt +0 -6
  172. package/out/_not-found/__next._not-found.__PAGE__.txt +0 -5
  173. package/out/_not-found/__next._not-found.txt +0 -5
  174. package/out/_not-found/__next._tree.txt +0 -3
  175. package/out/_not-found/index.html +0 -1
  176. package/out/_not-found/index.txt +0 -16
  177. package/out/changelog/__next._full.txt +0 -573
  178. package/out/changelog/__next._head.txt +0 -5
  179. package/out/changelog/__next._index.txt +0 -6
  180. package/out/changelog/__next._tree.txt +0 -4
  181. package/out/changelog/__next.changelog.__PAGE__.txt +0 -560
  182. package/out/changelog/__next.changelog.txt +0 -5
  183. package/out/changelog/index.html +0 -550
  184. package/out/changelog/index.txt +0 -573
  185. package/out/github/dashboard/__next._full.txt +0 -20
  186. package/out/github/dashboard/__next._head.txt +0 -5
  187. package/out/github/dashboard/__next._index.txt +0 -6
  188. package/out/github/dashboard/__next._tree.txt +0 -3
  189. package/out/github/dashboard/__next.github.dashboard.__PAGE__.txt +0 -9
  190. package/out/github/dashboard/__next.github.dashboard.txt +0 -4
  191. package/out/github/dashboard/__next.github.txt +0 -5
  192. package/out/github/dashboard/index.html +0 -1
  193. package/out/github/dashboard/index.txt +0 -20
  194. package/out/index.html +0 -1
  195. package/out/index.txt +0 -18
  196. package/out/privacy-policy/__next._full.txt +0 -38
  197. package/out/privacy-policy/__next._head.txt +0 -5
  198. package/out/privacy-policy/__next._index.txt +0 -6
  199. package/out/privacy-policy/__next._tree.txt +0 -4
  200. package/out/privacy-policy/__next.privacy-policy.__PAGE__.txt +0 -23
  201. package/out/privacy-policy/__next.privacy-policy.txt +0 -5
  202. package/out/privacy-policy/index.html +0 -1
  203. package/out/privacy-policy/index.txt +0 -38
  204. package/out/terms-of-use/__next._full.txt +0 -37
  205. package/out/terms-of-use/__next._head.txt +0 -5
  206. package/out/terms-of-use/__next._index.txt +0 -6
  207. package/out/terms-of-use/__next._tree.txt +0 -4
  208. package/out/terms-of-use/__next.terms-of-use.__PAGE__.txt +0 -18
  209. package/out/terms-of-use/__next.terms-of-use.txt +0 -5
  210. package/out/terms-of-use/index.html +0 -1
  211. package/out/terms-of-use/index.txt +0 -37
@@ -1 +1 @@
1
- {"version":3,"file":"analyst-quick-fixes.d.ts","sourceRoot":"","sources":["../../../src/analysts/corrections/analyst-quick-fixes.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,GAAG,CAAC;AAG9C,eAAO,MAAM,kBAAkB,EAAE,QAqEhC,CAAC"}
1
+ {"version":3,"file":"analyst-quick-fixes.d.ts","sourceRoot":"","sources":["../../../src/analysts/corrections/analyst-quick-fixes.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,GAAG,CAAC;AAG9C,eAAO,MAAM,kBAAkB,EAAE,QAqEhC,CAAC"}
@@ -1,4 +1,3 @@
1
- import { messages } from '../../core/messages/index.js';
2
1
  import { findQuickFixes } from '../../core/config/auto/index.js';
3
2
  import { criarOcorrencia } from '../../types/index.js';
4
3
  export const analistaQuickFixes = {
@@ -1 +1 @@
1
- {"version":3,"file":"analyst-quick-fixes.js","sourceRoot":"","sources":["../../../src/analysts/corrections/analyst-quick-fixes.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\nimport { messages } from '@core/messages';\nimport type { NodePath } from '@babel/traverse';\nimport type { Node } from '@babel/types';\nimport { findQuickFixes, type PatternBasedQuickFix } from '@core/config/auto';\n\nimport type { Analista, Ocorrencia } from '@';\nimport { criarOcorrencia } from '@';\n\nexport const analistaQuickFixes: Analista = {\n nome: 'quick-fixes',\n categoria: 'melhorias',\n descricao: 'Detecta problemas comuns e oferece correções automáticas',\n test: (relPath: string): boolean => {\n return /\\.(js|jsx|ts|tsx|mjs|cjs|svg)$/.test(relPath);\n },\n aplicar: (src: string, relPath: string, _ast: NodePath<Node> | null): Ocorrencia[] => {\n if (!src) return [];\n const ocorrencias: Ocorrencia[] = [];\n\n // Buscar quick fixes gerais\n const quickFixes = findQuickFixes(src, undefined, undefined, relPath);\n\n // Buscar quick fixes específicos por tipo de problema detectado\n const problemaTipos = ['unhandled-async', 'console-log', 'memory-leak', 'dangerous-html', 'eval-usage', 'complex-regex'];\n for (const problemTipo of problemaTipos) {\n const specificFixes = findQuickFixes(src, problemTipo, undefined, relPath);\n quickFixes.push(...specificFixes);\n }\n\n // Remover duplicatas por ID\n const uniqueFixes = quickFixes.filter((fix, index, arr) => arr.findIndex(arquivo => arquivo.id === fix.id) === index);\n for (const fixResultado of uniqueFixes) {\n for (const match of fixResultado.matches) {\n // Calcular linha aproximada do match\n const beforeMatch = src.substring(0, match.index || 0);\n const linha = beforeMatch.split('\\n').length;\n\n // Gerar preview da correção\n const previewCorrecao = fixResultado.fix(match, src);\n const originalLine = src.split('\\n')[linha - 1] || '';\n const fixedLine = previewCorrecao.split('\\n')[linha - 1] || '';\n\n // Criar sugestão com preview mais detalhado\n const sugestao = [fixResultado.description, '', `[CHAVE-INGLESA] Correção sugerida:`, `[ERRO] Antes: ${originalLine.trim()}`, `[OK] Depois: ${fixedLine.trim()}`, '', `Confiança: ${fixResultado.confidence}%`, `Categoria: ${fixResultado.category}`, `ID do Fix: ${fixResultado.id}`].join('\\n');\n\n // Mapear categoria para nível\n const nivel = mapearCategoriaNivel(fixResultado.category);\n\n // Criar ocorrência base\n const ocorrencia = criarOcorrencia({\n tipo: 'auto-fix-disponivel',\n nivel,\n mensagem: `${fixResultado.title}`,\n relPath,\n linha\n });\n\n // Adicionar campos extras como propriedades do objeto genérico\n const ocorrenciaGenerica = ocorrencia as Ocorrencia & {\n sugestao?: string;\n quickFixId?: string;\n confidence?: number;\n category?: string;\n matchIndex?: number;\n matchLength?: number;\n }; // OcorrenciaGenerica allows extra properties\n ocorrenciaGenerica.sugestao = sugestao;\n ocorrenciaGenerica.quickFixId = fixResultado.id;\n ocorrenciaGenerica.confidence = fixResultado.confidence;\n ocorrenciaGenerica.category = fixResultado.category;\n ocorrenciaGenerica.matchIndex = match.index;\n ocorrenciaGenerica.matchLength = match[0].length;\n ocorrencias.push(ocorrencia);\n }\n }\n return ocorrencias;\n }\n};\nfunction mapearCategoriaNivel(category: PatternBasedQuickFix['category']): 'info' | 'aviso' | 'erro' {\n switch (category) {\n case 'security':\n return 'erro';\n case 'performance':\n return 'aviso';\n case 'style':\n case 'documentation':\n return 'info';\n default:\n return 'info';\n }\n}"]}
1
+ {"version":3,"file":"analyst-quick-fixes.js","sourceRoot":"","sources":["../../../src/analysts/corrections/analyst-quick-fixes.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\nimport type { NodePath } from '@babel/traverse';\nimport type { Node } from '@babel/types';\nimport { findQuickFixes, type PatternBasedQuickFix } from '@core/config/auto';\n\nimport type { Analista, Ocorrencia } from '@';\nimport { criarOcorrencia } from '@';\n\nexport const analistaQuickFixes: Analista = {\n nome: 'quick-fixes',\n categoria: 'melhorias',\n descricao: 'Detecta problemas comuns e oferece correções automáticas',\n test: (relPath: string): boolean => {\n return /\\.(js|jsx|ts|tsx|mjs|cjs|svg)$/.test(relPath);\n },\n aplicar: (src: string, relPath: string, _ast: NodePath<Node> | null): Ocorrencia[] => {\n if (!src) return [];\n const ocorrencias: Ocorrencia[] = [];\n\n // Buscar quick fixes gerais\n const quickFixes = findQuickFixes(src, undefined, undefined, relPath);\n\n // Buscar quick fixes específicos por tipo de problema detectado\n const problemaTipos = ['unhandled-async', 'console-log', 'memory-leak', 'dangerous-html', 'eval-usage', 'complex-regex'];\n for (const problemTipo of problemaTipos) {\n const specificFixes = findQuickFixes(src, problemTipo, undefined, relPath);\n quickFixes.push(...specificFixes);\n }\n\n // Remover duplicatas por ID\n const uniqueFixes = quickFixes.filter((fix, index, arr) => arr.findIndex(arquivo => arquivo.id === fix.id) === index);\n for (const fixResultado of uniqueFixes) {\n for (const match of fixResultado.matches) {\n // Calcular linha aproximada do match\n const beforeMatch = src.substring(0, match.index || 0);\n const linha = beforeMatch.split('\\n').length;\n\n // Gerar preview da correção\n const previewCorrecao = fixResultado.fix(match, src);\n const originalLine = src.split('\\n')[linha - 1] || '';\n const fixedLine = previewCorrecao.split('\\n')[linha - 1] || '';\n\n // Criar sugestão com preview mais detalhado\n const sugestao = [fixResultado.description, '', `[CHAVE-INGLESA] Correção sugerida:`, `[ERRO] Antes: ${originalLine.trim()}`, `[OK] Depois: ${fixedLine.trim()}`, '', `Confiança: ${fixResultado.confidence}%`, `Categoria: ${fixResultado.category}`, `ID do Fix: ${fixResultado.id}`].join('\\n');\n\n // Mapear categoria para nível\n const nivel = mapearCategoriaNivel(fixResultado.category);\n\n // Criar ocorrência base\n const ocorrencia = criarOcorrencia({\n tipo: 'auto-fix-disponivel',\n nivel,\n mensagem: `${fixResultado.title}`,\n relPath,\n linha\n });\n\n // Adicionar campos extras como propriedades do objeto genérico\n const ocorrenciaGenerica = ocorrencia as Ocorrencia & {\n sugestao?: string;\n quickFixId?: string;\n confidence?: number;\n category?: string;\n matchIndex?: number;\n matchLength?: number;\n }; // OcorrenciaGenerica allows extra properties\n ocorrenciaGenerica.sugestao = sugestao;\n ocorrenciaGenerica.quickFixId = fixResultado.id;\n ocorrenciaGenerica.confidence = fixResultado.confidence;\n ocorrenciaGenerica.category = fixResultado.category;\n ocorrenciaGenerica.matchIndex = match.index;\n ocorrenciaGenerica.matchLength = match[0].length;\n ocorrencias.push(ocorrencia);\n }\n }\n return ocorrencias;\n }\n};\nfunction mapearCategoriaNivel(category: PatternBasedQuickFix['category']): 'info' | 'aviso' | 'erro' {\n switch (category) {\n case 'security':\n return 'erro';\n case 'performance':\n return 'aviso';\n case 'style':\n case 'documentation':\n return 'info';\n default:\n return 'info';\n }\n}"]}
@@ -1 +1 @@
1
- {"version":3,"file":"analyst-scoring.d.ts","sourceRoot":"","sources":["../../../src/analysts/corrections/analyst-scoring.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,GAAG,CAAC;AAuB9C,eAAO,MAAM,kBAAkB,EAAE,QA0DhC,CAAC;AAIF,eAAO,MAAM,iBAAiB,EAAE,QAoC/B,CAAC;AAIF,eAAO,MAAM,SAAS,EAAE,QAAQ,EAA4C,CAAC"}
1
+ {"version":3,"file":"analyst-scoring.d.ts","sourceRoot":"","sources":["../../../src/analysts/corrections/analyst-scoring.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,GAAG,CAAC;AAuB9C,eAAO,MAAM,kBAAkB,EAAE,QA0DhC,CAAC;AAIF,eAAO,MAAM,iBAAiB,EAAE,QAoC/B,CAAC;AAIF,eAAO,MAAM,SAAS,EAAE,QAAQ,EAA4C,CAAC"}
@@ -1,4 +1,3 @@
1
- import { messages } from '../../core/messages/index.js';
2
1
  import { findQuickFixes } from '../../core/config/auto/index.js';
3
2
  import { extrairSupressoes, isRegraSuprimida } from '../../shared/helpers/index.js';
4
3
  import { criarOcorrencia } from '../../types/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"analyst-scoring.js","sourceRoot":"","sources":["../../../src/analysts/corrections/analyst-scoring.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\nimport { messages } from '@core/messages';\nimport type { NodePath } from '@babel/traverse';\nimport type { Node } from '@babel/types';\nimport { findQuickFixes, type PatternBasedQuickFix } from '@core/config/auto';\nimport { extrairSupressoes, isRegraSuprimida } from '@shared/helpers';\n\nimport type { Analista, Ocorrencia } from '@';\nimport { criarOcorrencia } from '@';\n\nimport { analisarTexto, calcularLinha } from './scoring-shared.js';\n\n// ─── Helpers / Config ─────────────────────────────────────────\n\nfunction mapearCategoriaNivel(category: PatternBasedQuickFix['category']): 'info' | 'aviso' | 'erro' {\n switch (category) {\n case 'security':\n return 'erro';\n case 'performance':\n return 'aviso';\n case 'style':\n case 'documentation':\n return 'info';\n default:\n return 'info';\n }\n}\n\n// ─── analistaQuickFixes ───────────────────────────────────────\n\nexport const analistaQuickFixes: Analista = {\n nome: 'quick-fixes',\n categoria: 'melhorias',\n descricao: 'Detecta problemas comuns e oferece correções automáticas',\n test: (relPath: string): boolean => {\n // Inclui SVGs para permitir quick-fixes seguros (otimização e viewBox)\n return /\\.(js|jsx|ts|tsx|mjs|cjs|svg)$/.test(relPath);\n },\n aplicar: (src: string, relPath: string, _ast: NodePath<Node> | null): Ocorrencia[] => {\n if (!src) return [];\n const ocorrencias: Ocorrencia[] = [];\n\n // Quick fixes gerais\n const quickFixes = findQuickFixes(src, undefined, undefined, relPath);\n\n // Quick fixes específicos por tipo de problema detectado\n const problemaTipos = ['unhandled-async', 'console-log', 'memory-leak', 'dangerous-html', 'eval-usage', 'complex-regex'];\n for (const problemTipo of problemaTipos) {\n const specificFixes = findQuickFixes(src, problemTipo, undefined, relPath);\n quickFixes.push(...specificFixes);\n }\n\n // Remover duplicatas por ID\n const uniqueFixes = quickFixes.filter((fix, index, arr) => arr.findIndex(arquivo => arquivo.id === fix.id) === index);\n for (const fixResultado of uniqueFixes) {\n for (const match of fixResultado.matches) {\n const linha = calcularLinha(src, match.index, match);\n const previewCorrecao = fixResultado.fix(match, src);\n const originalLine = src.split('\\n')[linha - 1] || '';\n const fixedLine = previewCorrecao.split('\\n')[linha - 1] || '';\n const sugestao = [fixResultado.description, '', `[CHAVE-INGLESA] Correção sugerida:`, `[ERRO] Antes: ${originalLine.trim()}`, `[OK] Depois: ${fixedLine.trim()}`, '', `Confiança: ${fixResultado.confidence}%`, `Categoria: ${fixResultado.category}`, `ID do Fix: ${fixResultado.id}`].join('\\n');\n const nivel = mapearCategoriaNivel(fixResultado.category);\n const ocorrencia = criarOcorrencia({\n tipo: 'auto-fix-disponivel',\n nivel,\n mensagem: `${fixResultado.title}`,\n relPath,\n linha\n });\n const ocorrenciaGenerica = ocorrencia as Ocorrencia & {\n sugestao?: string;\n quickFixId?: string;\n confidence?: number;\n category?: string;\n matchIndex?: number;\n matchLength?: number;\n };\n ocorrenciaGenerica.sugestao = sugestao;\n ocorrenciaGenerica.quickFixId = fixResultado.id;\n ocorrenciaGenerica.confidence = fixResultado.confidence;\n ocorrenciaGenerica.category = fixResultado.category;\n ocorrenciaGenerica.matchIndex = match.index;\n ocorrenciaGenerica.matchLength = match[0].length;\n ocorrencias.push(ocorrencia);\n }\n }\n return ocorrencias;\n }\n};\n\n// ─── analistaPontuacao ────────────────────────────────────────\n\nexport const analistaPontuacao: Analista = {\n nome: 'pontuacao-fix',\n categoria: 'formatacao',\n descricao: 'Detecta problemas de pontuação, caracteres estranhos e formatação de texto',\n test: (relPath: string): boolean => {\n return /\\.(md|txt|mdx)$/.test(relPath);\n },\n aplicar: (src: string, relPath: string): Ocorrencia[] => {\n if (!src) return [];\n const supressoes = extrairSupressoes(src);\n const problemas = analisarTexto(src);\n const ocorrencias: Ocorrencia[] = [];\n for (const problema of problemas) {\n const linha = calcularLinha(src, problema.posicao);\n if (isRegraSuprimida(problema.tipo, linha, supressoes)) continue;\n const linhas = src.split('\\n');\n const contexto = linhas[linha - 1] || '';\n const ocorrencia = criarOcorrencia({\n tipo: problema.tipo,\n nivel: (problema.confianca ?? 0) > 80 ? 'aviso' : 'info',\n mensagem: problema.descricao,\n relPath,\n linha\n });\n const ocorrenciaExtendida = ocorrencia as Ocorrencia & {\n sugestao?: string;\n confianca?: number;\n contexto?: string;\n };\n ocorrenciaExtendida.sugestao = problema.sugestao;\n ocorrenciaExtendida.confianca = problema.confianca;\n ocorrenciaExtendida.contexto = contexto;\n ocorrencias.push(ocorrencia);\n }\n return ocorrencias;\n }\n};\n\n// ─── Exports adicionais ───────────────────────────────────────\n\nexport const analistas: Analista[] = [analistaQuickFixes, analistaPontuacao];\n"]}
1
+ {"version":3,"file":"analyst-scoring.js","sourceRoot":"","sources":["../../../src/analysts/corrections/analyst-scoring.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\nimport type { NodePath } from '@babel/traverse';\nimport type { Node } from '@babel/types';\nimport { findQuickFixes, type PatternBasedQuickFix } from '@core/config/auto';\nimport { extrairSupressoes, isRegraSuprimida } from '@shared/helpers';\n\nimport type { Analista, Ocorrencia } from '@';\nimport { criarOcorrencia } from '@';\n\nimport { analisarTexto, calcularLinha } from './scoring-shared.js';\n\n// ─── Helpers / Config ─────────────────────────────────────────\n\nfunction mapearCategoriaNivel(category: PatternBasedQuickFix['category']): 'info' | 'aviso' | 'erro' {\n switch (category) {\n case 'security':\n return 'erro';\n case 'performance':\n return 'aviso';\n case 'style':\n case 'documentation':\n return 'info';\n default:\n return 'info';\n }\n}\n\n// ─── analistaQuickFixes ───────────────────────────────────────\n\nexport const analistaQuickFixes: Analista = {\n nome: 'quick-fixes',\n categoria: 'melhorias',\n descricao: 'Detecta problemas comuns e oferece correções automáticas',\n test: (relPath: string): boolean => {\n // Inclui SVGs para permitir quick-fixes seguros (otimização e viewBox)\n return /\\.(js|jsx|ts|tsx|mjs|cjs|svg)$/.test(relPath);\n },\n aplicar: (src: string, relPath: string, _ast: NodePath<Node> | null): Ocorrencia[] => {\n if (!src) return [];\n const ocorrencias: Ocorrencia[] = [];\n\n // Quick fixes gerais\n const quickFixes = findQuickFixes(src, undefined, undefined, relPath);\n\n // Quick fixes específicos por tipo de problema detectado\n const problemaTipos = ['unhandled-async', 'console-log', 'memory-leak', 'dangerous-html', 'eval-usage', 'complex-regex'];\n for (const problemTipo of problemaTipos) {\n const specificFixes = findQuickFixes(src, problemTipo, undefined, relPath);\n quickFixes.push(...specificFixes);\n }\n\n // Remover duplicatas por ID\n const uniqueFixes = quickFixes.filter((fix, index, arr) => arr.findIndex(arquivo => arquivo.id === fix.id) === index);\n for (const fixResultado of uniqueFixes) {\n for (const match of fixResultado.matches) {\n const linha = calcularLinha(src, match.index, match);\n const previewCorrecao = fixResultado.fix(match, src);\n const originalLine = src.split('\\n')[linha - 1] || '';\n const fixedLine = previewCorrecao.split('\\n')[linha - 1] || '';\n const sugestao = [fixResultado.description, '', `[CHAVE-INGLESA] Correção sugerida:`, `[ERRO] Antes: ${originalLine.trim()}`, `[OK] Depois: ${fixedLine.trim()}`, '', `Confiança: ${fixResultado.confidence}%`, `Categoria: ${fixResultado.category}`, `ID do Fix: ${fixResultado.id}`].join('\\n');\n const nivel = mapearCategoriaNivel(fixResultado.category);\n const ocorrencia = criarOcorrencia({\n tipo: 'auto-fix-disponivel',\n nivel,\n mensagem: `${fixResultado.title}`,\n relPath,\n linha\n });\n const ocorrenciaGenerica = ocorrencia as Ocorrencia & {\n sugestao?: string;\n quickFixId?: string;\n confidence?: number;\n category?: string;\n matchIndex?: number;\n matchLength?: number;\n };\n ocorrenciaGenerica.sugestao = sugestao;\n ocorrenciaGenerica.quickFixId = fixResultado.id;\n ocorrenciaGenerica.confidence = fixResultado.confidence;\n ocorrenciaGenerica.category = fixResultado.category;\n ocorrenciaGenerica.matchIndex = match.index;\n ocorrenciaGenerica.matchLength = match[0].length;\n ocorrencias.push(ocorrencia);\n }\n }\n return ocorrencias;\n }\n};\n\n// ─── analistaPontuacao ────────────────────────────────────────\n\nexport const analistaPontuacao: Analista = {\n nome: 'pontuacao-fix',\n categoria: 'formatacao',\n descricao: 'Detecta problemas de pontuação, caracteres estranhos e formatação de texto',\n test: (relPath: string): boolean => {\n return /\\.(md|txt|mdx)$/.test(relPath);\n },\n aplicar: (src: string, relPath: string): Ocorrencia[] => {\n if (!src) return [];\n const supressoes = extrairSupressoes(src);\n const problemas = analisarTexto(src);\n const ocorrencias: Ocorrencia[] = [];\n for (const problema of problemas) {\n const linha = calcularLinha(src, problema.posicao);\n if (isRegraSuprimida(problema.tipo, linha, supressoes)) continue;\n const linhas = src.split('\\n');\n const contexto = linhas[linha - 1] || '';\n const ocorrencia = criarOcorrencia({\n tipo: problema.tipo,\n nivel: (problema.confianca ?? 0) > 80 ? 'aviso' : 'info',\n mensagem: problema.descricao,\n relPath,\n linha\n });\n const ocorrenciaExtendida = ocorrencia as Ocorrencia & {\n sugestao?: string;\n confianca?: number;\n contexto?: string;\n };\n ocorrenciaExtendida.sugestao = problema.sugestao;\n ocorrenciaExtendida.confianca = problema.confianca;\n ocorrenciaExtendida.contexto = contexto;\n ocorrencias.push(ocorrencia);\n }\n return ocorrencias;\n }\n};\n\n// ─── Exports adicionais ───────────────────────────────────────\n\nexport const analistas: Analista[] = [analistaQuickFixes, analistaPontuacao];\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"analyst-github-actions.d.ts","sourceRoot":"","sources":["../../../../src/analysts/github-actions/analysts/analyst-github-actions.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAoB,cAAc,EAAgC,MAAM,GAAG,CAAC;AAmDlG,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAE7E;AACD,wBAAgB,4BAA4B,IAAI,cAAc,EAAE,CAE/D;AACD,eAAO,MAAM,qBAAqB,EAAE,QAuCnC,CAAC;AACF,eAAO,MAAM,2BAA2B,EAAE,QA2HzC,CAAC"}
1
+ {"version":3,"file":"analyst-github-actions.d.ts","sourceRoot":"","sources":["../../../../src/analysts/github-actions/analysts/analyst-github-actions.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,QAAQ,EAAoB,cAAc,EAAgC,MAAM,GAAG,CAAC;AAkDlG,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAE7E;AACD,wBAAgB,4BAA4B,IAAI,cAAc,EAAE,CAE/D;AACD,eAAO,MAAM,qBAAqB,EAAE,QAuCnC,CAAC;AACF,eAAO,MAAM,2BAA2B,EAAE,QA2HzC,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { messages } from '../../../core/messages/index.js';
1
2
  import { parseDocument } from 'yaml';
2
3
  import { detectorDependenciasVulneraveis } from '../detectors/detector-dependencies-vulnerable.js';
3
4
  import { detectarProblemasAcessibilidade } from '../detectors/detector-workflow-accessibility.js';
@@ -7,7 +8,6 @@ import { detectorWorkflowSecurity } from '../detectors/detector-workflow-securit
7
8
  import { detectarJobsPassivos, detectorWorkflowEstrutura } from '../detectors/detector-workflow-structure.js';
8
9
  import { detectorWorkflowTriggerInseguro } from '../detectors/detector-workflow-trigger-unsafe.js';
9
10
  import { isOrgVerificada } from '../detectors/org-verified.js';
10
- import { messages } from '../../../core/messages/index.js';
11
11
  let _workflowNeedsFullHistory = false;
12
12
  const detectoresRegistrados = [];
13
13
  export function registrarDetectorGithubActions(detector) {
@@ -1 +1 @@
1
- {"version":3,"file":"analyst-github-actions.js","sourceRoot":"","sources":["../../../../src/analysts/github-actions/analysts/analyst-github-actions.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\n\n/**\n * @fileoverview Analista de qualidade para workflows do GitHub Actions (v0.6.0)\n */\n\nimport type { NodePath } from '@babel/traverse';\nimport { parseDocument } from 'yaml';\n\nimport type { Analista, ContextoExecucao, DeteccaoCustom, Ocorrencia, ProblemaWorkflow } from '@';\n\nimport { detectorDependenciasVulneraveis } from '../detectors/detector-dependencies-vulnerable.js';\nimport { detectarProblemasAcessibilidade } from '../detectors/detector-workflow-accessibility.js';\nimport { detectarProblemasCompliance } from '../detectors/detector-workflow-compliance.js';\nimport { detectorWorkflowPerformance } from '../detectors/detector-workflow-performance.js';\nimport { detectorWorkflowSecurity } from '../detectors/detector-workflow-security.js';\nimport { detectarJobsPassivos, detectorWorkflowEstrutura } from '../detectors/detector-workflow-structure.js';\nimport { detectorWorkflowTriggerInseguro } from '../detectors/detector-workflow-trigger-unsafe.js';\nimport { isOrgVerificada } from '../detectors/org-verified.js';\nimport { messages } from '@core/messages';\n\ninterface WorkflowStep {\n name?: string;\n uses?: string;\n with?: {\n path?: string;\n 'fetch-depth'?: number | string;\n 'cache-from'?: string;\n 'cache-to'?: string;\n [chave: string]: unknown;\n };\n env?: Record<string, unknown>;\n run?: string;\n}\ninterface WorkflowJob {\n name?: string;\n needs?: string | string[];\n strategy?: {\n matrix?: unknown;\n 'fail-fast'?: unknown;\n };\n container?: unknown;\n steps?: WorkflowStep[];\n}\ninterface WorkflowNode extends Record<string, unknown> {\n name?: string;\n container?: unknown;\n strategy?: {\n matrix?: unknown;\n 'fail-fast'?: unknown;\n };\n jobs?: Record<string, WorkflowJob>;\n steps?: WorkflowStep[];\n uses?: string;\n run?: string;\n}\n/** Flag global temporária (resetada a cada execução) para indicar se o workflow precisa de histórico completo do git */\nlet _workflowNeedsFullHistory = false;\n\nconst detectoresRegistrados: DeteccaoCustom[] = [];\nexport function registrarDetectorGithubActions(detector: DeteccaoCustom): void {\n detectoresRegistrados.push(detector);\n}\nexport function obterDetectoresGithubActions(): DeteccaoCustom[] {\n return [...detectoresRegistrados];\n}\nexport const analistaGithubActions: Analista = {\n nome: 'github-actions',\n categoria: 'workflows',\n descricao: 'Analista avançado de workflows do GitHub Actions com suporte a plugins',\n test: (relPath: string) => relPath.startsWith('.github/workflows/'),\n async aplicar(conteudo: string, relPath: string, _ast: unknown = null, _fc?: string, contexto?: ContextoExecucao): Promise<Ocorrencia[]> {\n const ocorrencias: Ocorrencia[] = [];\n try {\n const doc = parseDocument(conteudo);\n const workflow = doc.toJS();\n const problemas = await executarDetectoresNativos(workflow, conteudo);\n const caminhos = contexto?.arquivos.map(arquivo => arquivo.relPath) || [];\n const plugResults = await Promise.all(detectoresRegistrados.map(diretorio => Promise.resolve(diretorio.testar(workflow, {\n conteudo,\n caminhos\n })).catch(() => [])));\n const securityResults = await Promise.resolve(detectorWorkflowSecurity.aplicar(conteudo, relPath, _ast as NodePath | null, _fc, contexto));\n const performanceResults = await Promise.resolve(detectorWorkflowPerformance.aplicar(conteudo, relPath, _ast as NodePath | null, _fc, contexto));\n const estruturaResults = await Promise.resolve(detectorWorkflowEstrutura.aplicar(conteudo, relPath, _ast as NodePath | null, _fc, contexto));\n const depsResults = await Promise.resolve(detectorDependenciasVulneraveis.aplicar(conteudo, relPath, _ast as NodePath | null, _fc, contexto));\n const triggerResults = await Promise.resolve(detectorWorkflowTriggerInseguro.aplicar(conteudo, relPath, _ast as NodePath | null, _fc, contexto));\n const todos = [...problemas, ...plugResults.flat()];\n ocorrencias.push(...(securityResults as Ocorrencia[]), ...(performanceResults as Ocorrencia[]), ...(estruturaResults as Ocorrencia[]), ...(depsResults as Ocorrencia[]), ...(triggerResults as Ocorrencia[]));\n for (const caminho of todos) {\n ocorrencias.push({\n tipo: `GITHUB_ACTIONS_${caminho.tipo.toUpperCase().replace(/-/g, '_')}`,\n mensagem: caminho.descricao,\n relPath,\n linha: caminho.linha || 1,\n coluna: 1,\n sugestao: caminho.sugestao || '',\n nivel: caminho.severidade === 'critica' || caminho.severidade === 'alta' ? 'erro' : caminho.severidade === 'media' ? 'aviso' : 'info'\n });\n }\n } catch {\n // Basic regex fallback if YAML fails\n }\n return ocorrencias;\n }\n};\nexport const analistaGithubActionsGlobal: Analista = {\n nome: 'github-actions-global',\n categoria: 'workflows',\n descricao: 'Governança Global do GitHub',\n test: () => false,\n async aplicar(_c, _p, _a, _f, ctx?: ContextoExecucao): Promise<Ocorrencia[]> {\n if (!ctx) return [];\n const ores: Ocorrencia[] = [];\n const paths = ctx.arquivos.map(arquivo => arquivo.relPath);\n\n // CODEOWNERS\n if (!paths.some(caminho => /CODEOWNERS/i.test(caminho))) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_CODEOWNERS_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingCodeowners,\n relPath: '.github/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // README\n const readme = ctx.arquivos?.find(arquivo => /README\\.md/i.test(arquivo.relPath ?? ''));\n const content = readme ? readme.content as string | null || '' : '';\n if (readme && !/Code of Conduct|Código de Conduta/i.test(content)) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_DOC_GOVERNANCE_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingCodeOfConduct,\n relPath: readme.relPath,\n linha: 1,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // Stale Bot\n if (!paths.some(caminho => /stale/i.test(caminho))) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_STALE_BOT_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingStaleBot,\n relPath: '.github/workflows/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // Release\n if (!paths.some(caminho => /release|deploy/i.test(caminho))) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_RELEASE_AUTOMATION_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingReleaseAutomation,\n relPath: '.github/workflows/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // Issue Templates\n if (!paths.some(caminho => /\\.github\\/ISSUE_TEMPLATE/i.test(caminho))) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_ISSUE_TEMPLATES_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingIssueTemplates,\n relPath: '.github/ISSUE_TEMPLATE/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // PR Template\n if (!paths.some(caminho => /pull_request_template/i.test(caminho))) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_PR_TEMPLATE_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingPrTemplate,\n relPath: '.github/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // Semantic Versioning & Changelog\n const hasSemanticRelease = paths.some(caminho => /semantic-release|semrel/i.test(caminho));\n const hasChangelog = paths.some(caminho => /changelog/i.test(caminho));\n if (!hasSemanticRelease) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_SEMANTIC_VERSIONING_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingSemanticVersioning,\n relPath: '.github/workflows/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n if (!hasChangelog) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_CHANGELOG_AUTOMATION_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingChangelogAutomation,\n relPath: '.github/workflows/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // License Headers\n const sourceFiles = ctx.arquivos.filter(arquivo => /\\.(ts|js)$/.test(arquivo.relPath));\n const missingLicense = sourceFiles.filter(arquivo => !/SPDX-License-Identifier/i.test(arquivo.content as string || ''));\n if (missingLicense.length > sourceFiles.length / 2) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_LICENSE_HEADERS_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingLicenseHeaders,\n relPath: './',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n return ores;\n }\n};\n/**\n * Verifica se o workflow contém comandos git que exigem histórico completo.\n */\nfunction workflowRequerHistoricoCompleto(wf: WorkflowNode, raw: string): boolean {\n // Verificar no raw por comandos git conhecidos que precisam de histórico completo\n const gitCommandsQuePrecisamDeHistorico = /\\b(git\\s+(rev-parse|tag|describe|log|shortlog|diff|bisect|blame)|git\\s+checkout\\s+-b|git\\s+fetch\\s+--unshallow|git\\s+clone\\s+--depth)/gi;\n if (gitCommandsQuePrecisamDeHistorico.test(raw)) {\n return true;\n }\n\n // Verificar nas ações steps por comandos que indicam necessidade de histórico\n const jobs = wf?.jobs ? Object.values(wf.jobs) : [];\n const allSteps = jobs.flatMap(job => job?.steps || []);\n for (const step of allSteps) {\n if (step?.run && gitCommandsQuePrecisamDeHistorico.test(step.run)) {\n return true;\n }\n }\n\n return false;\n}\n\nasync function executarDetectoresNativos(wf: unknown, raw: string): Promise<ProblemaWorkflow[]> {\n const probs: ProblemaWorkflow[] = [];\n if (!wf) return probs;\n\n _workflowNeedsFullHistory = workflowRequerHistoricoCompleto(wf as WorkflowNode, raw);\n\n // Handle various snippet styles for tests\n const candidates = Array.isArray(wf) ? wf : [wf];\n for (const item of candidates) {\n if (typeof item === 'object' && item !== null) {\n analisarEstrutura(item as WorkflowNode, probs);\n }\n }\n\n // Compliance checks\n probs.push(...detectarProblemasCompliance(wf, raw));\n\n // Accessibility checks\n probs.push(...detectarProblemasAcessibilidade(wf));\n\n // Passive jobs check\n if (typeof wf === 'object' && 'jobs' in wf) {\n const wfJobs = (wf as {\n jobs?: Record<string, {\n steps?: Array<{\n uses?: string;\n run?: string;\n }>;\n }>;\n }).jobs;\n if (wfJobs) {\n for (const [, job] of Object.entries(wfJobs)) {\n if (detectarJobsPassivos(job as {\n steps?: Array<{\n uses?: string;\n run?: string;\n }>;\n })) {\n probs.push({\n tipo: 'job-passivo-workflow',\n descricao: 'Job passivo detectado',\n severidade: 'baixa'\n });\n }\n }\n }\n }\n\n // Final check for raw string patterns (like sudo)\n if (/sudo\\s+/.test(raw)) {\n probs.push({\n tipo: 'uso-sudo',\n descricao: 'Uso de sudo detectado',\n severidade: 'alta'\n });\n }\n if (raw.includes('pull_request_target:')) {\n probs.push({\n tipo: 'estrutura-workflow',\n descricao: 'Uso de pull_request_target',\n severidade: 'alta'\n });\n }\n return probs;\n}\nfunction analisarEstrutura(wf: WorkflowNode, probs: ProblemaWorkflow[]) {\n // Workflow sem nome\n if (!wf.name) {\n probs.push({\n tipo: 'workflow-sem-nome',\n descricao: 'Workflow sem nome definido',\n severidade: 'baixa'\n });\n }\n\n // Container (Root level for snippets)\n if (wf.container && typeof wf.container === 'string') {\n probs.push({\n tipo: 'container-sem-user',\n descricao: 'Container sem user',\n severidade: 'media'\n });\n }\n\n // Strategy\n if (wf.strategy?.matrix && wf.strategy['fail-fast'] === undefined) {\n probs.push({\n tipo: 'matrix-sem-fail-fast',\n descricao: 'Matrix sem fail-fast',\n severidade: 'baixa'\n });\n }\n\n // Detect Secrets in generic maps (for environment snippets in tests)\n for (const [chave, valor] of Object.entries(wf)) {\n if (/(KEY|TOKEN|SECRET|PASSWORD)/i.test(chave) && valor && typeof valor !== 'object' && !String(valor).includes('${{')) {\n probs.push({\n tipo: 'env-sensivel',\n descricao: `Secret hardcoded em ${chave}`,\n severidade: 'critica'\n });\n }\n }\n\n // Jobs\n if (wf.jobs) {\n const jobEntries = Object.entries(wf.jobs);\n for (const [id, job] of jobEntries) {\n if (job?.strategy?.matrix && job.strategy['fail-fast'] === undefined) {\n probs.push({\n tipo: 'matrix-sem-fail-fast',\n descricao: `Job ${id} sem fail-fast`,\n severidade: 'baixa'\n });\n }\n if (job?.container && typeof job.container === 'string') {\n probs.push({\n tipo: 'container-sem-user',\n descricao: 'Container rodando como root',\n severidade: 'media'\n });\n }\n\n // --- v0.4.5: Job sem nome descritivo ---\n if (/^(job\\d+|step\\d+|build\\d*|test\\d*|j\\d+)$/i.test(id) && !job?.name) {\n probs.push({\n tipo: 'job-sem-nome',\n descricao: `Job '${id}' usa ID genérico sem campo 'name'`,\n severidade: 'baixa',\n sugestao: 'Usar nomes semânticos como build-backend, test-integration'\n });\n }\n if (job?.steps) {\n for (const string of job.steps) analisarStep(string, probs);\n\n // --- v0.4.5: Steps sem nome ---\n analisarStepsSemNome(job.steps, probs);\n\n // --- v0.7.0: Jobs muito longos ---\n if (job.steps.length > 15) {\n probs.push({\n tipo: 'job-longo',\n descricao: `Job '${id}' possui ${job.steps.length} steps, o que dificulta a manutenção`,\n severidade: 'baixa',\n sugestao: 'Considere quebrar em jobs menores ou usar composite actions'\n });\n }\n }\n }\n\n // --- v0.4.5: Build sem parallelismo ---\n analisarParalelismo(jobEntries, probs);\n\n // --- v0.4.5: Download desnecessário de artifacts ---\n analisarDownloadArtifacts(jobEntries, probs);\n\n // --- v0.4.5: Múltiplas instalações de dependências ---\n analisarMultiplasInstalacoesDeps(jobEntries, probs);\n }\n\n // Se forem passos diretos na raiz (snippet)\n if (wf.steps && Array.isArray(wf.steps)) {\n for (const string of wf.steps) analisarStep(string, probs);\n analisarStepsSemNome(wf.steps, probs);\n }\n\n // Direct steps (if snippet is a list)\n if (wf.uses || wf.run) analisarStep(wf as WorkflowStep, probs);\n}\nfunction analisarStep(string: WorkflowStep, probs: ProblemaWorkflow[]) {\n if (!string) return;\n // Pinning - only for non-verified orgs\n if (string.uses && /@v\\d+/.test(string.uses)) {\n const actionRef = string.uses.split('@')[0];\n if (!isOrgVerificada(actionRef)) {\n probs.push({\n tipo: 'falta-sha-pinning',\n descricao: 'Pinning por SHA faltando',\n severidade: 'media'\n });\n }\n }\n // Upload\n if (string.uses?.includes('upload-artifact') && string.with?.path?.includes('.env')) {\n probs.push({\n tipo: 'upload-sensivel',\n descricao: 'Upload de .env',\n severidade: 'critica'\n });\n }\n // Env\n if (string.env) {\n for (const [chave, valor] of Object.entries(string.env)) {\n if (/(KEY|TOKEN|SECRET|PASSWORD)/i.test(chave) && valor && typeof valor !== 'object' && !String(valor).includes('${{')) {\n probs.push({\n tipo: 'env-sensivel',\n descricao: `Env ${chave} hardcoded`,\n severidade: 'critica'\n });\n }\n }\n }\n // Injection\n if (string.run && /\\$\\{\\{\\s*github\\.event\\./.test(string.run)) {\n probs.push({\n tipo: 'script-injection',\n descricao: 'Script injection',\n severidade: 'alta'\n });\n }\n\n // --- v0.4.5: Docker build sem layer caching ---\n if (string.uses && /docker\\/build-push-action/.test(string.uses)) {\n const hasCacheFrom = string.with?.['cache-from'] !== undefined;\n const hasCacheTo = string.with?.['cache-to'] !== undefined;\n if (!hasCacheFrom && !hasCacheTo) {\n probs.push({\n tipo: 'docker-sem-layer-cache',\n descricao: 'Docker build sem cache de layers configurado',\n severidade: 'media',\n sugestao: 'Adicionar cache-from e cache-to para otimizar builds Docker'\n });\n }\n }\n\n // --- v0.4.5: Checkout com fetch-depth: 0 desnecessário ---\n if (string.uses && /actions\\/checkout/.test(string.uses) && string.with) {\n const fd = string.with['fetch-depth'];\n if (fd === 0 || fd === '0') {\n // Não emitir se já foi identificado que o workflow precisa de histórico completo\n if (!_workflowNeedsFullHistory) {\n probs.push({\n tipo: 'fetch-depth-desnecessario',\n descricao: 'checkout com fetch-depth: 0 baixa todo o histórico do repositório',\n severidade: 'baixa',\n sugestao: 'Usar fetch-depth: 1 (default) a menos que precise do histórico completo para tags/changelog'\n });\n }\n }\n }\n}\n\nconst ACTIONS_AUTO_EXPLICATIVAS = [\n 'actions/checkout',\n 'actions/setup-node',\n 'actions/setup-python',\n 'actions/setup-java',\n 'actions/setup-go',\n 'actions/setup-dotnet',\n 'actions/setup-ruby',\n 'actions/upload-artifact',\n 'actions/download-artifact',\n 'actions/cache',\n 'actions/stale',\n 'actions/labeler',\n 'actions/dependency-review',\n 'actions/attest-build-provenance',\n 'docker/login-action',\n 'docker/build-push-action',\n 'docker/metadata-action',\n 'docker/setup-buildx-action',\n 'docker/setup-qemu-action',\n 'azure/login',\n 'azure/webapps-deploy',\n 'aws-actions/configure-aws-credentials',\n 'google-github-actions/auth',\n 'github/codeql-action/init',\n 'github/codeql-action/analyze',\n 'github/codeql-action/autobuild',\n 'softprops/action-gh-release',\n 'cypress-io/github-action',\n];\n\n/**\n * v0.4.5: Detecta steps sem campo 'name'\n * Não reporta para actions bem conhecidas e auto-explicativas\n */\nfunction analisarStepsSemNome(steps: WorkflowStep[], probs: ProblemaWorkflow[]) {\n for (const string of steps) {\n if (!string || string.name) continue;\n if (string.uses || string.run) {\n // Pular actions auto-explicativas (não precisam de name)\n if (string.uses && ACTIONS_AUTO_EXPLICATIVAS.some(action => string.uses?.startsWith(action))) {\n continue;\n }\n const ident = string.uses ? `uses: ${string.uses}` : 'run command';\n probs.push({\n tipo: 'step-sem-nome',\n descricao: `Step sem campo 'name' (${ident})`,\n severidade: 'baixa',\n sugestao: 'Adicionar campo name: para melhor legibilidade nos logs do Actions'\n });\n }\n }\n}\n\n/**\n * v0.4.5: Detecta jobs que poderiam rodar em paralelo mas têm 'needs' desnecessário\n * Heurística: se todos os jobs têm 'needs' formando uma cadeia linear, sugere paralelismo\n * Exceção: workflows de release/deploy são intrinsecamente sequenciais\n */\nfunction analisarParalelismo(jobEntries: [string, WorkflowJob][], probs: ProblemaWorkflow[]) {\n if (jobEntries.length < 3) return;\n\n // Check if this is a release/deploy workflow (sequential by nature)\n const workflowName = jobEntries[0]?.[1]?.name?.toLowerCase() || '';\n const jobNames = jobEntries.map(([, j]) => j?.name?.toLowerCase() || '').join(' ');\n const isReleaseWorkflow = /release|deploy|publish|ship/i.test(workflowName) || /release|deploy|publish|ship/i.test(jobNames);\n if (isReleaseWorkflow) return;\n\n let totalWithNeeds = 0;\n for (const [, job] of jobEntries) {\n if (job?.needs) totalWithNeeds++;\n }\n\n // Se todos os jobs (exceto o primeiro) dependem do anterior em cadeia linear\n if (totalWithNeeds === jobEntries.length - 1) {\n probs.push({\n tipo: 'build-sem-parallelismo',\n descricao: 'Todos os jobs estão em cadeia linear - considere paralelizar jobs independentes',\n severidade: 'media',\n sugestao: 'Remover dependências (needs) desnecessárias para permitir execução paralela'\n });\n }\n}\n\n/**\n * v0.4.5: Detecta múltiplos download-artifact em jobs diferentes\n */\nfunction analisarDownloadArtifacts(jobEntries: [string, WorkflowJob][], probs: ProblemaWorkflow[]) {\n let downloadCount = 0;\n for (const [, job] of jobEntries) {\n if (!job?.steps) continue;\n for (const string of job.steps) {\n if (string.uses && /download-artifact/.test(string.uses)) downloadCount++;\n }\n }\n if (downloadCount >= 3) {\n probs.push({\n tipo: 'download-artifacts-desnecessario',\n descricao: `${downloadCount} download-artifact encontrados - considere consolidar artifacts`,\n severidade: 'baixa',\n sugestao: 'Consolidar artifacts ou usar cache compartilhado'\n });\n }\n}\n\n/**\n * v0.4.5: Detecta npm ci/npm install em múltiplos jobs sem cache compartilhado\n */\nfunction analisarMultiplasInstalacoesDeps(jobEntries: [string, WorkflowJob][], probs: ProblemaWorkflow[]) {\n let installCount = 0;\n let hasCacheStep = false;\n let hasSetupNodeWithCache = false;\n for (const [, job] of jobEntries) {\n if (!job?.steps) continue;\n let jobHasInstall = false;\n for (const string of job.steps) {\n if (string.run && /\\b(npm\\s+(ci|install)|yarn\\s+install|pnpm\\s+install)\\b/.test(string.run)) {\n jobHasInstall = true;\n }\n if (string.uses && /actions\\/cache/.test(string.uses)) {\n hasCacheStep = true;\n }\n if (string.uses && /actions\\/setup-node/.test(string.uses) && string.with?.cache) {\n hasSetupNodeWithCache = true;\n }\n }\n if (jobHasInstall) installCount++;\n }\n if (installCount >= 2 && !hasCacheStep && !hasSetupNodeWithCache) {\n probs.push({\n tipo: 'multiplas-instalacoes-deps',\n descricao: `Instalação de dependências em ${installCount} jobs sem cache compartilhado`,\n severidade: 'media',\n sugestao: 'Usar actions/cache ou artifact de node_modules para evitar instalações duplicadas'\n });\n }\n}"]}
1
+ {"version":3,"file":"analyst-github-actions.js","sourceRoot":"","sources":["../../../../src/analysts/github-actions/analysts/analyst-github-actions.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\n\n/**\n * @fileoverview Analista de qualidade para workflows do GitHub Actions (v0.6.0)\n */\n\nimport type { NodePath } from '@babel/traverse';\nimport { messages } from '@core/messages';\nimport { parseDocument } from 'yaml';\n\nimport type { Analista, ContextoExecucao, DeteccaoCustom, Ocorrencia, ProblemaWorkflow } from '@';\n\nimport { detectorDependenciasVulneraveis } from '../detectors/detector-dependencies-vulnerable.js';\nimport { detectarProblemasAcessibilidade } from '../detectors/detector-workflow-accessibility.js';\nimport { detectarProblemasCompliance } from '../detectors/detector-workflow-compliance.js';\nimport { detectorWorkflowPerformance } from '../detectors/detector-workflow-performance.js';\nimport { detectorWorkflowSecurity } from '../detectors/detector-workflow-security.js';\nimport { detectarJobsPassivos, detectorWorkflowEstrutura } from '../detectors/detector-workflow-structure.js';\nimport { detectorWorkflowTriggerInseguro } from '../detectors/detector-workflow-trigger-unsafe.js';\nimport { isOrgVerificada } from '../detectors/org-verified.js';\n\ninterface WorkflowStep {\n name?: string;\n uses?: string;\n with?: {\n path?: string;\n 'fetch-depth'?: number | string;\n 'cache-from'?: string;\n 'cache-to'?: string;\n [chave: string]: unknown;\n };\n env?: Record<string, unknown>;\n run?: string;\n}\ninterface WorkflowJob {\n name?: string;\n needs?: string | string[];\n strategy?: {\n matrix?: unknown;\n 'fail-fast'?: unknown;\n };\n container?: unknown;\n steps?: WorkflowStep[];\n}\ninterface WorkflowNode extends Record<string, unknown> {\n name?: string;\n container?: unknown;\n strategy?: {\n matrix?: unknown;\n 'fail-fast'?: unknown;\n };\n jobs?: Record<string, WorkflowJob>;\n steps?: WorkflowStep[];\n uses?: string;\n run?: string;\n}\n/** Flag global temporária (resetada a cada execução) para indicar se o workflow precisa de histórico completo do git */\nlet _workflowNeedsFullHistory = false;\n\nconst detectoresRegistrados: DeteccaoCustom[] = [];\nexport function registrarDetectorGithubActions(detector: DeteccaoCustom): void {\n detectoresRegistrados.push(detector);\n}\nexport function obterDetectoresGithubActions(): DeteccaoCustom[] {\n return [...detectoresRegistrados];\n}\nexport const analistaGithubActions: Analista = {\n nome: 'github-actions',\n categoria: 'workflows',\n descricao: 'Analista avançado de workflows do GitHub Actions com suporte a plugins',\n test: (relPath: string) => relPath.startsWith('.github/workflows/'),\n async aplicar(conteudo: string, relPath: string, _ast: unknown = null, _fc?: string, contexto?: ContextoExecucao): Promise<Ocorrencia[]> {\n const ocorrencias: Ocorrencia[] = [];\n try {\n const doc = parseDocument(conteudo);\n const workflow = doc.toJS();\n const problemas = await executarDetectoresNativos(workflow, conteudo);\n const caminhos = contexto?.arquivos.map(arquivo => arquivo.relPath) || [];\n const plugResults = await Promise.all(detectoresRegistrados.map(diretorio => Promise.resolve(diretorio.testar(workflow, {\n conteudo,\n caminhos\n })).catch(() => [])));\n const securityResults = await Promise.resolve(detectorWorkflowSecurity.aplicar(conteudo, relPath, _ast as NodePath | null, _fc, contexto));\n const performanceResults = await Promise.resolve(detectorWorkflowPerformance.aplicar(conteudo, relPath, _ast as NodePath | null, _fc, contexto));\n const estruturaResults = await Promise.resolve(detectorWorkflowEstrutura.aplicar(conteudo, relPath, _ast as NodePath | null, _fc, contexto));\n const depsResults = await Promise.resolve(detectorDependenciasVulneraveis.aplicar(conteudo, relPath, _ast as NodePath | null, _fc, contexto));\n const triggerResults = await Promise.resolve(detectorWorkflowTriggerInseguro.aplicar(conteudo, relPath, _ast as NodePath | null, _fc, contexto));\n const todos = [...problemas, ...plugResults.flat()];\n ocorrencias.push(...(securityResults as Ocorrencia[]), ...(performanceResults as Ocorrencia[]), ...(estruturaResults as Ocorrencia[]), ...(depsResults as Ocorrencia[]), ...(triggerResults as Ocorrencia[]));\n for (const caminho of todos) {\n ocorrencias.push({\n tipo: `GITHUB_ACTIONS_${caminho.tipo.toUpperCase().replace(/-/g, '_')}`,\n mensagem: caminho.descricao,\n relPath,\n linha: caminho.linha || 1,\n coluna: 1,\n sugestao: caminho.sugestao || '',\n nivel: caminho.severidade === 'critica' || caminho.severidade === 'alta' ? 'erro' : caminho.severidade === 'media' ? 'aviso' : 'info'\n });\n }\n } catch {\n // Basic regex fallback if YAML fails\n }\n return ocorrencias;\n }\n};\nexport const analistaGithubActionsGlobal: Analista = {\n nome: 'github-actions-global',\n categoria: 'workflows',\n descricao: 'Governança Global do GitHub',\n test: () => false,\n async aplicar(_c, _p, _a, _f, ctx?: ContextoExecucao): Promise<Ocorrencia[]> {\n if (!ctx) return [];\n const ores: Ocorrencia[] = [];\n const paths = ctx.arquivos.map(arquivo => arquivo.relPath);\n\n // CODEOWNERS\n if (!paths.some(caminho => /CODEOWNERS/i.test(caminho))) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_CODEOWNERS_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingCodeowners,\n relPath: '.github/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // README\n const readme = ctx.arquivos?.find(arquivo => /README\\.md/i.test(arquivo.relPath ?? ''));\n const content = readme ? readme.content as string | null || '' : '';\n if (readme && !/Code of Conduct|Código de Conduta/i.test(content)) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_DOC_GOVERNANCE_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingCodeOfConduct,\n relPath: readme.relPath,\n linha: 1,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // Stale Bot\n if (!paths.some(caminho => /stale/i.test(caminho))) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_STALE_BOT_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingStaleBot,\n relPath: '.github/workflows/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // Release\n if (!paths.some(caminho => /release|deploy/i.test(caminho))) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_RELEASE_AUTOMATION_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingReleaseAutomation,\n relPath: '.github/workflows/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // Issue Templates\n if (!paths.some(caminho => /\\.github\\/ISSUE_TEMPLATE/i.test(caminho))) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_ISSUE_TEMPLATES_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingIssueTemplates,\n relPath: '.github/ISSUE_TEMPLATE/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // PR Template\n if (!paths.some(caminho => /pull_request_template/i.test(caminho))) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_PR_TEMPLATE_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingPrTemplate,\n relPath: '.github/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // Semantic Versioning & Changelog\n const hasSemanticRelease = paths.some(caminho => /semantic-release|semrel/i.test(caminho));\n const hasChangelog = paths.some(caminho => /changelog/i.test(caminho));\n if (!hasSemanticRelease) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_SEMANTIC_VERSIONING_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingSemanticVersioning,\n relPath: '.github/workflows/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n if (!hasChangelog) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_CHANGELOG_AUTOMATION_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingChangelogAutomation,\n relPath: '.github/workflows/',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n\n // License Headers\n const sourceFiles = ctx.arquivos.filter(arquivo => /\\.(ts|js)$/.test(arquivo.relPath));\n const missingLicense = sourceFiles.filter(arquivo => !/SPDX-License-Identifier/i.test(arquivo.content as string || ''));\n if (missingLicense.length > sourceFiles.length / 2) {\n ores.push({\n tipo: 'GITHUB_ACTIONS_LICENSE_HEADERS_MISSING',\n mensagem: messages.AnalistaGithubActionsMensagens.missingLicenseHeaders,\n relPath: './',\n linha: 0,\n coluna: 0,\n nivel: 'info'\n });\n }\n return ores;\n }\n};\n/**\n * Verifica se o workflow contém comandos git que exigem histórico completo.\n */\nfunction workflowRequerHistoricoCompleto(wf: WorkflowNode, raw: string): boolean {\n // Verificar no raw por comandos git conhecidos que precisam de histórico completo\n const gitCommandsQuePrecisamDeHistorico = /\\b(git\\s+(rev-parse|tag|describe|log|shortlog|diff|bisect|blame)|git\\s+checkout\\s+-b|git\\s+fetch\\s+--unshallow|git\\s+clone\\s+--depth)/gi;\n if (gitCommandsQuePrecisamDeHistorico.test(raw)) {\n return true;\n }\n\n // Verificar nas ações steps por comandos que indicam necessidade de histórico\n const jobs = wf?.jobs ? Object.values(wf.jobs) : [];\n const allSteps = jobs.flatMap(job => job?.steps || []);\n for (const step of allSteps) {\n if (step?.run && gitCommandsQuePrecisamDeHistorico.test(step.run)) {\n return true;\n }\n }\n\n return false;\n}\n\nasync function executarDetectoresNativos(wf: unknown, raw: string): Promise<ProblemaWorkflow[]> {\n const probs: ProblemaWorkflow[] = [];\n if (!wf) return probs;\n\n _workflowNeedsFullHistory = workflowRequerHistoricoCompleto(wf as WorkflowNode, raw);\n\n // Handle various snippet styles for tests\n const candidates = Array.isArray(wf) ? wf : [wf];\n for (const item of candidates) {\n if (typeof item === 'object' && item !== null) {\n analisarEstrutura(item as WorkflowNode, probs);\n }\n }\n\n // Compliance checks\n probs.push(...detectarProblemasCompliance(wf, raw));\n\n // Accessibility checks\n probs.push(...detectarProblemasAcessibilidade(wf));\n\n // Passive jobs check\n if (typeof wf === 'object' && 'jobs' in wf) {\n const wfJobs = (wf as {\n jobs?: Record<string, {\n steps?: Array<{\n uses?: string;\n run?: string;\n }>;\n }>;\n }).jobs;\n if (wfJobs) {\n for (const [, job] of Object.entries(wfJobs)) {\n if (detectarJobsPassivos(job as {\n steps?: Array<{\n uses?: string;\n run?: string;\n }>;\n })) {\n probs.push({\n tipo: 'job-passivo-workflow',\n descricao: 'Job passivo detectado',\n severidade: 'baixa'\n });\n }\n }\n }\n }\n\n // Final check for raw string patterns (like sudo)\n if (/sudo\\s+/.test(raw)) {\n probs.push({\n tipo: 'uso-sudo',\n descricao: 'Uso de sudo detectado',\n severidade: 'alta'\n });\n }\n if (raw.includes('pull_request_target:')) {\n probs.push({\n tipo: 'estrutura-workflow',\n descricao: 'Uso de pull_request_target',\n severidade: 'alta'\n });\n }\n return probs;\n}\nfunction analisarEstrutura(wf: WorkflowNode, probs: ProblemaWorkflow[]) {\n // Workflow sem nome\n if (!wf.name) {\n probs.push({\n tipo: 'workflow-sem-nome',\n descricao: 'Workflow sem nome definido',\n severidade: 'baixa'\n });\n }\n\n // Container (Root level for snippets)\n if (wf.container && typeof wf.container === 'string') {\n probs.push({\n tipo: 'container-sem-user',\n descricao: 'Container sem user',\n severidade: 'media'\n });\n }\n\n // Strategy\n if (wf.strategy?.matrix && wf.strategy['fail-fast'] === undefined) {\n probs.push({\n tipo: 'matrix-sem-fail-fast',\n descricao: 'Matrix sem fail-fast',\n severidade: 'baixa'\n });\n }\n\n // Detect Secrets in generic maps (for environment snippets in tests)\n for (const [chave, valor] of Object.entries(wf)) {\n if (/(KEY|TOKEN|SECRET|PASSWORD)/i.test(chave) && valor && typeof valor !== 'object' && !String(valor).includes('${{')) {\n probs.push({\n tipo: 'env-sensivel',\n descricao: `Secret hardcoded em ${chave}`,\n severidade: 'critica'\n });\n }\n }\n\n // Jobs\n if (wf.jobs) {\n const jobEntries = Object.entries(wf.jobs);\n for (const [id, job] of jobEntries) {\n if (job?.strategy?.matrix && job.strategy['fail-fast'] === undefined) {\n probs.push({\n tipo: 'matrix-sem-fail-fast',\n descricao: `Job ${id} sem fail-fast`,\n severidade: 'baixa'\n });\n }\n if (job?.container && typeof job.container === 'string') {\n probs.push({\n tipo: 'container-sem-user',\n descricao: 'Container rodando como root',\n severidade: 'media'\n });\n }\n\n // --- v0.4.5: Job sem nome descritivo ---\n if (/^(job\\d+|step\\d+|build\\d*|test\\d*|j\\d+)$/i.test(id) && !job?.name) {\n probs.push({\n tipo: 'job-sem-nome',\n descricao: `Job '${id}' usa ID genérico sem campo 'name'`,\n severidade: 'baixa',\n sugestao: 'Usar nomes semânticos como build-backend, test-integration'\n });\n }\n if (job?.steps) {\n for (const string of job.steps) analisarStep(string, probs);\n\n // --- v0.4.5: Steps sem nome ---\n analisarStepsSemNome(job.steps, probs);\n\n // --- v0.7.0: Jobs muito longos ---\n if (job.steps.length > 15) {\n probs.push({\n tipo: 'job-longo',\n descricao: `Job '${id}' possui ${job.steps.length} steps, o que dificulta a manutenção`,\n severidade: 'baixa',\n sugestao: 'Considere quebrar em jobs menores ou usar composite actions'\n });\n }\n }\n }\n\n // --- v0.4.5: Build sem parallelismo ---\n analisarParalelismo(jobEntries, probs);\n\n // --- v0.4.5: Download desnecessário de artifacts ---\n analisarDownloadArtifacts(jobEntries, probs);\n\n // --- v0.4.5: Múltiplas instalações de dependências ---\n analisarMultiplasInstalacoesDeps(jobEntries, probs);\n }\n\n // Se forem passos diretos na raiz (snippet)\n if (wf.steps && Array.isArray(wf.steps)) {\n for (const string of wf.steps) analisarStep(string, probs);\n analisarStepsSemNome(wf.steps, probs);\n }\n\n // Direct steps (if snippet is a list)\n if (wf.uses || wf.run) analisarStep(wf as WorkflowStep, probs);\n}\nfunction analisarStep(string: WorkflowStep, probs: ProblemaWorkflow[]) {\n if (!string) return;\n // Pinning - only for non-verified orgs\n if (string.uses && /@v\\d+/.test(string.uses)) {\n const actionRef = string.uses.split('@')[0];\n if (!isOrgVerificada(actionRef)) {\n probs.push({\n tipo: 'falta-sha-pinning',\n descricao: 'Pinning por SHA faltando',\n severidade: 'media'\n });\n }\n }\n // Upload\n if (string.uses?.includes('upload-artifact') && string.with?.path?.includes('.env')) {\n probs.push({\n tipo: 'upload-sensivel',\n descricao: 'Upload de .env',\n severidade: 'critica'\n });\n }\n // Env\n if (string.env) {\n for (const [chave, valor] of Object.entries(string.env)) {\n if (/(KEY|TOKEN|SECRET|PASSWORD)/i.test(chave) && valor && typeof valor !== 'object' && !String(valor).includes('${{')) {\n probs.push({\n tipo: 'env-sensivel',\n descricao: `Env ${chave} hardcoded`,\n severidade: 'critica'\n });\n }\n }\n }\n // Injection\n if (string.run && /\\$\\{\\{\\s*github\\.event\\./.test(string.run)) {\n probs.push({\n tipo: 'script-injection',\n descricao: 'Script injection',\n severidade: 'alta'\n });\n }\n\n // --- v0.4.5: Docker build sem layer caching ---\n if (string.uses && /docker\\/build-push-action/.test(string.uses)) {\n const hasCacheFrom = string.with?.['cache-from'] !== undefined;\n const hasCacheTo = string.with?.['cache-to'] !== undefined;\n if (!hasCacheFrom && !hasCacheTo) {\n probs.push({\n tipo: 'docker-sem-layer-cache',\n descricao: 'Docker build sem cache de layers configurado',\n severidade: 'media',\n sugestao: 'Adicionar cache-from e cache-to para otimizar builds Docker'\n });\n }\n }\n\n // --- v0.4.5: Checkout com fetch-depth: 0 desnecessário ---\n if (string.uses && /actions\\/checkout/.test(string.uses) && string.with) {\n const fd = string.with['fetch-depth'];\n if (fd === 0 || fd === '0') {\n // Não emitir se já foi identificado que o workflow precisa de histórico completo\n if (!_workflowNeedsFullHistory) {\n probs.push({\n tipo: 'fetch-depth-desnecessario',\n descricao: 'checkout com fetch-depth: 0 baixa todo o histórico do repositório',\n severidade: 'baixa',\n sugestao: 'Usar fetch-depth: 1 (default) a menos que precise do histórico completo para tags/changelog'\n });\n }\n }\n }\n}\n\nconst ACTIONS_AUTO_EXPLICATIVAS = [\n 'actions/checkout',\n 'actions/setup-node',\n 'actions/setup-python',\n 'actions/setup-java',\n 'actions/setup-go',\n 'actions/setup-dotnet',\n 'actions/setup-ruby',\n 'actions/upload-artifact',\n 'actions/download-artifact',\n 'actions/cache',\n 'actions/stale',\n 'actions/labeler',\n 'actions/dependency-review',\n 'actions/attest-build-provenance',\n 'docker/login-action',\n 'docker/build-push-action',\n 'docker/metadata-action',\n 'docker/setup-buildx-action',\n 'docker/setup-qemu-action',\n 'azure/login',\n 'azure/webapps-deploy',\n 'aws-actions/configure-aws-credentials',\n 'google-github-actions/auth',\n 'github/codeql-action/init',\n 'github/codeql-action/analyze',\n 'github/codeql-action/autobuild',\n 'softprops/action-gh-release',\n 'cypress-io/github-action',\n];\n\n/**\n * v0.4.5: Detecta steps sem campo 'name'\n * Não reporta para actions bem conhecidas e auto-explicativas\n */\nfunction analisarStepsSemNome(steps: WorkflowStep[], probs: ProblemaWorkflow[]) {\n for (const string of steps) {\n if (!string || string.name) continue;\n if (string.uses || string.run) {\n // Pular actions auto-explicativas (não precisam de name)\n if (string.uses && ACTIONS_AUTO_EXPLICATIVAS.some(action => string.uses?.startsWith(action))) {\n continue;\n }\n const ident = string.uses ? `uses: ${string.uses}` : 'run command';\n probs.push({\n tipo: 'step-sem-nome',\n descricao: `Step sem campo 'name' (${ident})`,\n severidade: 'baixa',\n sugestao: 'Adicionar campo name: para melhor legibilidade nos logs do Actions'\n });\n }\n }\n}\n\n/**\n * v0.4.5: Detecta jobs que poderiam rodar em paralelo mas têm 'needs' desnecessário\n * Heurística: se todos os jobs têm 'needs' formando uma cadeia linear, sugere paralelismo\n * Exceção: workflows de release/deploy são intrinsecamente sequenciais\n */\nfunction analisarParalelismo(jobEntries: [string, WorkflowJob][], probs: ProblemaWorkflow[]) {\n if (jobEntries.length < 3) return;\n\n // Check if this is a release/deploy workflow (sequential by nature)\n const workflowName = jobEntries[0]?.[1]?.name?.toLowerCase() || '';\n const jobNames = jobEntries.map(([, j]) => j?.name?.toLowerCase() || '').join(' ');\n const isReleaseWorkflow = /release|deploy|publish|ship/i.test(workflowName) || /release|deploy|publish|ship/i.test(jobNames);\n if (isReleaseWorkflow) return;\n\n let totalWithNeeds = 0;\n for (const [, job] of jobEntries) {\n if (job?.needs) totalWithNeeds++;\n }\n\n // Se todos os jobs (exceto o primeiro) dependem do anterior em cadeia linear\n if (totalWithNeeds === jobEntries.length - 1) {\n probs.push({\n tipo: 'build-sem-parallelismo',\n descricao: 'Todos os jobs estão em cadeia linear - considere paralelizar jobs independentes',\n severidade: 'media',\n sugestao: 'Remover dependências (needs) desnecessárias para permitir execução paralela'\n });\n }\n}\n\n/**\n * v0.4.5: Detecta múltiplos download-artifact em jobs diferentes\n */\nfunction analisarDownloadArtifacts(jobEntries: [string, WorkflowJob][], probs: ProblemaWorkflow[]) {\n let downloadCount = 0;\n for (const [, job] of jobEntries) {\n if (!job?.steps) continue;\n for (const string of job.steps) {\n if (string.uses && /download-artifact/.test(string.uses)) downloadCount++;\n }\n }\n if (downloadCount >= 3) {\n probs.push({\n tipo: 'download-artifacts-desnecessario',\n descricao: `${downloadCount} download-artifact encontrados - considere consolidar artifacts`,\n severidade: 'baixa',\n sugestao: 'Consolidar artifacts ou usar cache compartilhado'\n });\n }\n}\n\n/**\n * v0.4.5: Detecta npm ci/npm install em múltiplos jobs sem cache compartilhado\n */\nfunction analisarMultiplasInstalacoesDeps(jobEntries: [string, WorkflowJob][], probs: ProblemaWorkflow[]) {\n let installCount = 0;\n let hasCacheStep = false;\n let hasSetupNodeWithCache = false;\n for (const [, job] of jobEntries) {\n if (!job?.steps) continue;\n let jobHasInstall = false;\n for (const string of job.steps) {\n if (string.run && /\\b(npm\\s+(ci|install)|yarn\\s+install|pnpm\\s+install)\\b/.test(string.run)) {\n jobHasInstall = true;\n }\n if (string.uses && /actions\\/cache/.test(string.uses)) {\n hasCacheStep = true;\n }\n if (string.uses && /actions\\/setup-node/.test(string.uses) && string.with?.cache) {\n hasSetupNodeWithCache = true;\n }\n }\n if (jobHasInstall) installCount++;\n }\n if (installCount >= 2 && !hasCacheStep && !hasSetupNodeWithCache) {\n probs.push({\n tipo: 'multiplas-instalacoes-deps',\n descricao: `Instalação de dependências em ${installCount} jobs sem cache compartilhado`,\n severidade: 'media',\n sugestao: 'Usar actions/cache ou artifact de node_modules para evitar instalações duplicadas'\n });\n }\n}"]}
@@ -1 +1 @@
1
- {"version":3,"file":"detector-dependencies-vulnerable.d.ts","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-dependencies-vulnerable.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,GAAG,CAAC;AAoL9C,eAAO,MAAM,+BAA+B,EAAE,QAqE7C,CAAC"}
1
+ {"version":3,"file":"detector-dependencies-vulnerable.d.ts","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-dependencies-vulnerable.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,GAAG,CAAC;AAmL9C,eAAO,MAAM,+BAA+B,EAAE,QAqE7C,CAAC"}
@@ -1,7 +1,7 @@
1
+ import { messages } from '../../../core/messages/index.js';
1
2
  import { splitLines } from '../../../shared/helpers/index.js';
2
3
  import { criarOcorrencia } from '../../../types/index.js';
3
4
  import { isOrgVerificada } from './org-verified.js';
4
- import { messages } from '../../../core/messages/index.js';
5
5
  const CVES_CONHECIDOS = [{
6
6
  action: 'actions/checkout',
7
7
  versions: '<v3',
@@ -1 +1 @@
1
- {"version":3,"file":"detector-dependencies-vulnerable.js","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-dependencies-vulnerable.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\n/**\n * [BUSCA] Detector de Dependências Vulneráveis para GitHub Actions\n *\n * Detecta dependências potencialmente vulneráveis em workflows:\n * - Actions com CVEs conhecidos (base de dados de vulnerabilidades)\n * - Actions que não usam SHA pinning (facilmente exploráveis)\n * - Versões desatualizadas de actions com patches de segurança\n * - Dependências npm/yarn com versões conhecidamente vulneráveis\n * - Uso de actions de forks sem verificação\n */\n\nimport { splitLines } from '@shared/helpers';\n\nimport type { Analista, Ocorrencia } from '@';\nimport { criarOcorrencia } from '@';\n\nimport { isOrgVerificada } from './org-verified.js';\nimport { messages } from '@core/messages';\n\n// Base de dados de CVEs conhecidos para actions populares\ntype CVEEntry = {\n action: string;\n versions: string;\n cve: string;\n descricao: string;\n severidade: 'alta' | 'media' | 'baixa';\n fix: string;\n};\nconst CVES_CONHECIDOS: CVEEntry[] = [{\n action: 'actions/checkout',\n versions: '<v3',\n cve: 'CVE-2022-32197',\n descricao: 'Checkout v1/v2 não valida refs de pull request de forks',\n severidade: 'alta',\n fix: 'Atualizar para actions/checkout@v4'\n}, {\n action: 'actions/upload-artifact',\n versions: '<v4',\n cve: 'CVE-2023-34941',\n descricao: 'Upload de artifacts sem checksum pode permitir adulteração',\n severidade: 'media',\n fix: 'Atualizar para actions/upload-artifact@v4'\n}, {\n action: 'actions/download-artifact',\n versions: '<v4',\n cve: 'CVE-2023-34941',\n descricao: 'Download de artifacts sem verificação de integridade',\n severidade: 'media',\n fix: 'Atualizar para actions/download-artifact@v4'\n}, {\n action: 'actions/cache',\n versions: '<v4',\n descricao: 'Cache v1/v2/v3 com risco de restauração de conteúdo inesperado',\n cve: 'CVE-2023-22490',\n severidade: 'baixa',\n fix: 'Atualizar para actions/cache@v4'\n}, {\n action: 'actions/setup-node',\n versions: '<v4',\n cve: 'CVE-2023-32471',\n descricao: 'setup-node v1-v3 pode injetar conteúdo no GITHUB_STATE',\n severidade: 'media',\n fix: 'Atualizar para actions/setup-node@v4'\n}, {\n action: 'docker/login-action',\n versions: '<v3',\n cve: 'CVE-2023-29017',\n descricao: 'login-action v2 loga argumentos do Docker incluindo tokens',\n severidade: 'alta',\n fix: 'Atualizar para docker/login-action@v3'\n}, {\n action: 'docker/build-push-action',\n versions: '<v5',\n cve: 'CVE-2023-34941',\n descricao: 'Build sem proveniência verificável',\n severidade: 'media',\n fix: 'Atualizar para docker/build-push-action@v5'\n}, {\n action: 'actions/setup-python',\n versions: '<v5',\n cve: 'CVE-2023-39446',\n descricao: 'setup-python v4 não sanitiza variáveis de ambiente',\n severidade: 'baixa',\n fix: 'Atualizar para actions/setup-python@v5'\n}];\n\n// Actions frequentemente usadas em forks maliciosos\nconst FORK_SUSPEITO_PATTERNS = [/^[a-zA-Z0-9-]+\\/[a-zA-Z0-9-]+@[a-f0-9]{40}$/,\n// Fork com SHA longo não oficial\n/^[a-zA-Z0-9-]+-[a-zA-Z0-9-]+-[a-zA-Z0-9-]+@/ // Padrão de nome de fork suspeito\n];\nconst VERSOES_VULNERAVEIS_NPM: Record<string, {\n vulneravel: string;\n fix: string;\n}> = {\n 'serialize-javascript': {\n vulneravel: '<6.0.0',\n fix: 'Atualizar para serialize-javascript@>=6.0.0'\n },\n 'node-fetch': {\n vulneravel: '<2.6.7',\n fix: 'Atualizar para node-fetch@>=2.6.7'\n },\n 'tar': {\n vulneravel: '<6.1.11',\n fix: 'Atualizar para tar@>=6.1.11'\n },\n 'minimist': {\n vulneravel: '<1.2.6',\n fix: 'Atualizar para minimist@>=1.2.6'\n },\n 'lodash': {\n vulneravel: '<4.17.21',\n fix: 'Atualizar para lodash@>=4.17.21'\n },\n 'yaml': {\n vulneravel: '<2.0.0',\n fix: 'Atualizar para yaml@>=2.0.0'\n }\n};\nfunction verificarActionVulneravel(uses: string, linha: number, relPath: string): Ocorrencia | null {\n const match = uses.match(/^([a-zA-Z0-9-]+\\/[a-zA-Z0-9-]+)@(.+)$/);\n if (!match) return null;\n const [, actionRef, version] = match;\n\n // Verificar CVEs conhecidos\n for (const cve of CVES_CONHECIDOS) {\n if (actionRef === cve.action) {\n const versaoNum = parseInt(version.replace(/^v/, ''), 10);\n const maxVersao = parseInt(cve.versions.replace(/^<v/, ''), 10);\n if (!isNaN(versaoNum) && !isNaN(maxVersao) && versaoNum < maxVersao) {\n return criarOcorrencia({\n tipo: 'dependencia-vulneravel',\n nivel: cve.severidade === 'alta' ? 'erro' : cve.severidade === 'media' ? 'aviso' : 'info',\n mensagem: `${actionRef}@${version}: ${cve.descricao} (${cve.cve})`,\n relPath,\n linha,\n sugestao: cve.fix\n });\n }\n }\n }\n\n // Verificar fork suspeito - APENAS se NÃO for de organização verificada\n // SHA pinning em actions de orgs verificadas é boa prática de segurança\n if (!isOrgVerificada(actionRef)) {\n for (const pattern of FORK_SUSPEITO_PATTERNS) {\n if (pattern.test(uses)) {\n return criarOcorrencia({\n tipo: 'fork-suspeito',\n nivel: 'aviso',\n mensagem: messages.AnalistaGithubActionsMensagens.suspiciousActionDetected(uses),\n relPath,\n linha,\n sugestao: messages.AnalistaGithubActionsMensagens.suspiciousActionDetectedSugestao\n });\n }\n }\n }\n return null;\n}\nfunction verificarDependenciasNpm(runCommand: string, linha: number, relPath: string): Ocorrencia | null {\n for (const [dep, info] of Object.entries(VERSOES_VULNERAVEIS_NPM)) {\n // Detectar require/import de versões vulneráveis\n if (new RegExp(`${dep}@?[\\\\s'\\\"<>=]`).test(runCommand)) {\n if (runCommand.includes(`npm install ${dep}`) || runCommand.includes(`npm i ${dep}`)) {\n // Se instala sem versão específica, não sabemos a versão, mas vale avisar\n return criarOcorrencia({\n tipo: 'dependencia-npm-vulneravel',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.possibleVulnerableNpmDependency(dep),\n relPath,\n linha,\n sugestao: info.fix\n });\n }\n\n // Extrair versão do package.json se mencionado\n const versionMatch = runCommand.match(new RegExp(`${dep}@([\\\\d^~<>]+)`));\n if (versionMatch) {\n return criarOcorrencia({\n tipo: 'dependencia-npm-vulneravel',\n nivel: 'aviso',\n mensagem: `${dep}@${versionMatch[1]} pode conter vulnerabilidades conhecidas`,\n relPath,\n linha,\n sugestao: info.fix\n });\n }\n }\n }\n return null;\n}\nexport const detectorDependenciasVulneraveis: Analista = {\n nome: 'detector-dependencias-vulneraveis',\n categoria: 'workflows',\n descricao: 'Detecta dependências vulneráveis em GitHub Actions',\n test: (relPath: string): boolean => /\\.github\\/workflows\\/.*\\.ya?ml$/i.test(relPath),\n aplicar: (src: string, relPath: string): Ocorrencia[] => {\n if (!src) return [];\n const ocorrencias: Ocorrencia[] = [];\n const linhas = splitLines(src);\n for (let indice = 0; indice < linhas.length; indice++) {\n const linha = linhas[indice];\n const numeroLinha = indice + 1;\n\n // --- 1. Actions com CVEs conhecidos ---\n const usesMatch = linha.match(/uses:\\s*([a-zA-Z0-9-]+\\/[a-zA-Z0-9-]+@[\\w.]+)/);\n if (usesMatch) {\n const ocorrencia = verificarActionVulneravel(usesMatch[1], numeroLinha, relPath);\n if (ocorrencia) {\n ocorrencias.push(ocorrencia);\n }\n }\n\n // --- 2. Dependências npm vulneráveis em run commands ---\n if (linha.match(/run:\\s*['\"]?npm/)) {\n const npmOcorrencia = verificarDependenciasNpm(linha, numeroLinha, relPath);\n if (npmOcorrencia) {\n ocorrencias.push(npmOcorrencia);\n }\n }\n }\n\n // --- 3. Verificar falta de audit step em workflows com instalação de deps ---\n const hasInstallStep = /npm\\s+(install|i\\b)|yarn\\s+install|pnpm\\s+install/i.test(src);\n const hasAuditStep = /\\b(npm\\s+audit|yarn\\s+audit|pnpm\\s+audit|snyk|trivy)\\b/i.test(src);\n if (hasInstallStep && !hasAuditStep) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-sem-audit',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.workflowInstallsDepsWithoutAudit,\n relPath,\n linha: 1,\n sugestao: messages.AnalistaGithubActionsMensagens.workflowInstallsDepsWithoutAuditSugestao\n }));\n }\n\n // --- 4. Verificar se actions de checkout têm persist-credentials: true (padrão perigoso) ---\n // Reportar apenas uma vez por workflow, e ignorar workflows que claramente precisam de escrita\n const isReleaseOrDeployWorkflow = /release|deploy|publish|tag|changelog/i.test(src);\n const checkoutsWithoutPersistFalse: number[] = [];\n for (let indice = 0; indice < linhas.length; indice++) {\n if (/uses:\\s*actions\\/checkout/.test(linhas[indice])) {\n const proximasLinhas = linhas.slice(indice, Math.min(indice + 10, linhas.length)).join('\\n');\n if (!/persist-credentials:\\s*false/.test(proximasLinhas)) {\n checkoutsWithoutPersistFalse.push(indice + 1);\n }\n }\n }\n if (checkoutsWithoutPersistFalse.length > 0 && !isReleaseOrDeployWorkflow) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'checkout-sem-persist-credentials-false',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.checkoutsWithoutPersistCredentials(checkoutsWithoutPersistFalse.length),\n relPath,\n linha: checkoutsWithoutPersistFalse[0],\n sugestao: messages.AnalistaGithubActionsMensagens.checkoutsWithoutPersistCredentialsSugestao\n }));\n }\n return ocorrencias;\n }\n};"]}
1
+ {"version":3,"file":"detector-dependencies-vulnerable.js","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-dependencies-vulnerable.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,GAAG,CAAC;AAEpC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAWpD,MAAM,eAAe,GAAe,CAAC;QACnC,MAAM,EAAE,kBAAkB;QAC1B,QAAQ,EAAE,KAAK;QACf,GAAG,EAAE,gBAAgB;QACrB,SAAS,EAAE,yDAAyD;QACpE,UAAU,EAAE,MAAM;QAClB,GAAG,EAAE,oCAAoC;KAC1C,EAAE;QACD,MAAM,EAAE,yBAAyB;QACjC,QAAQ,EAAE,KAAK;QACf,GAAG,EAAE,gBAAgB;QACrB,SAAS,EAAE,4DAA4D;QACvE,UAAU,EAAE,OAAO;QACnB,GAAG,EAAE,2CAA2C;KACjD,EAAE;QACD,MAAM,EAAE,2BAA2B;QACnC,QAAQ,EAAE,KAAK;QACf,GAAG,EAAE,gBAAgB;QACrB,SAAS,EAAE,sDAAsD;QACjE,UAAU,EAAE,OAAO;QACnB,GAAG,EAAE,6CAA6C;KACnD,EAAE;QACD,MAAM,EAAE,eAAe;QACvB,QAAQ,EAAE,KAAK;QACf,SAAS,EAAE,gEAAgE;QAC3E,GAAG,EAAE,gBAAgB;QACrB,UAAU,EAAE,OAAO;QACnB,GAAG,EAAE,iCAAiC;KACvC,EAAE;QACD,MAAM,EAAE,oBAAoB;QAC5B,QAAQ,EAAE,KAAK;QACf,GAAG,EAAE,gBAAgB;QACrB,SAAS,EAAE,wDAAwD;QACnE,UAAU,EAAE,OAAO;QACnB,GAAG,EAAE,sCAAsC;KAC5C,EAAE;QACD,MAAM,EAAE,qBAAqB;QAC7B,QAAQ,EAAE,KAAK;QACf,GAAG,EAAE,gBAAgB;QACrB,SAAS,EAAE,4DAA4D;QACvE,UAAU,EAAE,MAAM;QAClB,GAAG,EAAE,uCAAuC;KAC7C,EAAE;QACD,MAAM,EAAE,0BAA0B;QAClC,QAAQ,EAAE,KAAK;QACf,GAAG,EAAE,gBAAgB;QACrB,SAAS,EAAE,oCAAoC;QAC/C,UAAU,EAAE,OAAO;QACnB,GAAG,EAAE,4CAA4C;KAClD,EAAE;QACD,MAAM,EAAE,sBAAsB;QAC9B,QAAQ,EAAE,KAAK;QACf,GAAG,EAAE,gBAAgB;QACrB,SAAS,EAAE,oDAAoD;QAC/D,UAAU,EAAE,OAAO;QACnB,GAAG,EAAE,wCAAwC;KAC9C,CAAC,CAAC;AAGH,MAAM,sBAAsB,GAAG,CAAC,6CAA6C;IAE7E,6CAA6C;CAC5C,CAAC;AACF,MAAM,uBAAuB,GAGxB;IACH,sBAAsB,EAAE;QACtB,UAAU,EAAE,QAAQ;QACpB,GAAG,EAAE,6CAA6C;KACnD;IACD,YAAY,EAAE;QACZ,UAAU,EAAE,QAAQ;QACpB,GAAG,EAAE,mCAAmC;KACzC;IACD,KAAK,EAAE;QACL,UAAU,EAAE,SAAS;QACrB,GAAG,EAAE,6BAA6B;KACnC;IACD,UAAU,EAAE;QACV,UAAU,EAAE,QAAQ;QACpB,GAAG,EAAE,iCAAiC;KACvC;IACD,QAAQ,EAAE;QACR,UAAU,EAAE,UAAU;QACtB,GAAG,EAAE,iCAAiC;KACvC;IACD,MAAM,EAAE;QACN,UAAU,EAAE,QAAQ;QACpB,GAAG,EAAE,6BAA6B;KACnC;CACF,CAAC;AACF,SAAS,yBAAyB,CAAC,IAAY,EAAE,KAAa,EAAE,OAAe;IAC7E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAClE,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC;IAGrC,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;QAClC,IAAI,SAAS,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAC1D,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAChE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,SAAS,GAAG,SAAS,EAAE,CAAC;gBACpE,OAAO,eAAe,CAAC;oBACrB,IAAI,EAAE,wBAAwB;oBAC9B,KAAK,EAAE,GAAG,CAAC,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM;oBACzF,QAAQ,EAAE,GAAG,SAAS,IAAI,OAAO,KAAK,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC,GAAG,GAAG;oBAClE,OAAO;oBACP,KAAK;oBACL,QAAQ,EAAE,GAAG,CAAC,GAAG;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAID,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;QAChC,KAAK,MAAM,OAAO,IAAI,sBAAsB,EAAE,CAAC;YAC7C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,OAAO,eAAe,CAAC;oBACrB,IAAI,EAAE,eAAe;oBACrB,KAAK,EAAE,OAAO;oBACd,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,wBAAwB,CAAC,IAAI,CAAC;oBAChF,OAAO;oBACP,KAAK;oBACL,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,gCAAgC;iBACnF,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AACD,SAAS,wBAAwB,CAAC,UAAkB,EAAE,KAAa,EAAE,OAAe;IAClF,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,uBAAuB,CAAC,EAAE,CAAC;QAElE,IAAI,IAAI,MAAM,CAAC,GAAG,GAAG,eAAe,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;YACvD,IAAI,UAAU,CAAC,QAAQ,CAAC,eAAe,GAAG,EAAE,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAS,GAAG,EAAE,CAAC,EAAE,CAAC;gBAErF,OAAO,eAAe,CAAC;oBACrB,IAAI,EAAE,4BAA4B;oBAClC,KAAK,EAAE,MAAM;oBACb,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,+BAA+B,CAAC,GAAG,CAAC;oBACtF,OAAO;oBACP,KAAK;oBACL,QAAQ,EAAE,IAAI,CAAC,GAAG;iBACnB,CAAC,CAAC;YACL,CAAC;YAGD,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,GAAG,GAAG,eAAe,CAAC,CAAC,CAAC;YACzE,IAAI,YAAY,EAAE,CAAC;gBACjB,OAAO,eAAe,CAAC;oBACrB,IAAI,EAAE,4BAA4B;oBAClC,KAAK,EAAE,OAAO;oBACd,QAAQ,EAAE,GAAG,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,0CAA0C;oBAC7E,OAAO;oBACP,KAAK;oBACL,QAAQ,EAAE,IAAI,CAAC,GAAG;iBACnB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AACD,MAAM,CAAC,MAAM,+BAA+B,GAAa;IACvD,IAAI,EAAE,mCAAmC;IACzC,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,oDAAoD;IAC/D,IAAI,EAAE,CAAC,OAAe,EAAW,EAAE,CAAC,kCAAkC,CAAC,IAAI,CAAC,OAAO,CAAC;IACpF,OAAO,EAAE,CAAC,GAAW,EAAE,OAAe,EAAgB,EAAE;QACtD,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,MAAM,WAAW,GAAiB,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAC/B,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;YACtD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAC7B,MAAM,WAAW,GAAG,MAAM,GAAG,CAAC,CAAC;YAG/B,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC;YAC/E,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,UAAU,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;gBACjF,IAAI,UAAU,EAAE,CAAC;oBACf,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC;YAGD,IAAI,KAAK,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACnC,MAAM,aAAa,GAAG,wBAAwB,CAAC,KAAK,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;gBAC5E,IAAI,aAAa,EAAE,CAAC;oBAClB,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC;QACH,CAAC;QAGD,MAAM,cAAc,GAAG,oDAAoD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACtF,MAAM,YAAY,GAAG,yDAAyD,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzF,IAAI,cAAc,IAAI,CAAC,YAAY,EAAE,CAAC;YACpC,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC;gBAC/B,IAAI,EAAE,oBAAoB;gBAC1B,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,gCAAgC;gBAClF,OAAO;gBACP,KAAK,EAAE,CAAC;gBACR,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,wCAAwC;aAC3F,CAAC,CAAC,CAAC;QACN,CAAC;QAID,MAAM,yBAAyB,GAAG,uCAAuC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpF,MAAM,4BAA4B,GAAa,EAAE,CAAC;QAClD,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC;YACtD,IAAI,2BAA2B,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;gBACrD,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC7F,IAAI,CAAC,8BAA8B,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;oBACzD,4BAA4B,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;QACH,CAAC;QACD,IAAI,4BAA4B,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC;YAC1E,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC;gBAC/B,IAAI,EAAE,wCAAwC;gBAC9C,KAAK,EAAE,MAAM;gBACb,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,kCAAkC,CAAC,4BAA4B,CAAC,MAAM,CAAC;gBACzH,OAAO;gBACP,KAAK,EAAE,4BAA4B,CAAC,CAAC,CAAC;gBACtC,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,0CAA0C;aAC7F,CAAC,CAAC,CAAC;QACN,CAAC;QACD,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC","sourcesContent":["// SPDX-License-Identifier: MIT\n/**\n * [BUSCA] Detector de Dependências Vulneráveis para GitHub Actions\n *\n * Detecta dependências potencialmente vulneráveis em workflows:\n * - Actions com CVEs conhecidos (base de dados de vulnerabilidades)\n * - Actions que não usam SHA pinning (facilmente exploráveis)\n * - Versões desatualizadas de actions com patches de segurança\n * - Dependências npm/yarn com versões conhecidamente vulneráveis\n * - Uso de actions de forks sem verificação\n */\n\nimport { messages } from '@core/messages';\nimport { splitLines } from '@shared/helpers';\n\nimport type { Analista, Ocorrencia } from '@';\nimport { criarOcorrencia } from '@';\n\nimport { isOrgVerificada } from './org-verified.js';\n\n// Base de dados de CVEs conhecidos para actions populares\ntype CVEEntry = {\n action: string;\n versions: string;\n cve: string;\n descricao: string;\n severidade: 'alta' | 'media' | 'baixa';\n fix: string;\n};\nconst CVES_CONHECIDOS: CVEEntry[] = [{\n action: 'actions/checkout',\n versions: '<v3',\n cve: 'CVE-2022-32197',\n descricao: 'Checkout v1/v2 não valida refs de pull request de forks',\n severidade: 'alta',\n fix: 'Atualizar para actions/checkout@v4'\n}, {\n action: 'actions/upload-artifact',\n versions: '<v4',\n cve: 'CVE-2023-34941',\n descricao: 'Upload de artifacts sem checksum pode permitir adulteração',\n severidade: 'media',\n fix: 'Atualizar para actions/upload-artifact@v4'\n}, {\n action: 'actions/download-artifact',\n versions: '<v4',\n cve: 'CVE-2023-34941',\n descricao: 'Download de artifacts sem verificação de integridade',\n severidade: 'media',\n fix: 'Atualizar para actions/download-artifact@v4'\n}, {\n action: 'actions/cache',\n versions: '<v4',\n descricao: 'Cache v1/v2/v3 com risco de restauração de conteúdo inesperado',\n cve: 'CVE-2023-22490',\n severidade: 'baixa',\n fix: 'Atualizar para actions/cache@v4'\n}, {\n action: 'actions/setup-node',\n versions: '<v4',\n cve: 'CVE-2023-32471',\n descricao: 'setup-node v1-v3 pode injetar conteúdo no GITHUB_STATE',\n severidade: 'media',\n fix: 'Atualizar para actions/setup-node@v4'\n}, {\n action: 'docker/login-action',\n versions: '<v3',\n cve: 'CVE-2023-29017',\n descricao: 'login-action v2 loga argumentos do Docker incluindo tokens',\n severidade: 'alta',\n fix: 'Atualizar para docker/login-action@v3'\n}, {\n action: 'docker/build-push-action',\n versions: '<v5',\n cve: 'CVE-2023-34941',\n descricao: 'Build sem proveniência verificável',\n severidade: 'media',\n fix: 'Atualizar para docker/build-push-action@v5'\n}, {\n action: 'actions/setup-python',\n versions: '<v5',\n cve: 'CVE-2023-39446',\n descricao: 'setup-python v4 não sanitiza variáveis de ambiente',\n severidade: 'baixa',\n fix: 'Atualizar para actions/setup-python@v5'\n}];\n\n// Actions frequentemente usadas em forks maliciosos\nconst FORK_SUSPEITO_PATTERNS = [/^[a-zA-Z0-9-]+\\/[a-zA-Z0-9-]+@[a-f0-9]{40}$/,\n// Fork com SHA longo não oficial\n/^[a-zA-Z0-9-]+-[a-zA-Z0-9-]+-[a-zA-Z0-9-]+@/ // Padrão de nome de fork suspeito\n];\nconst VERSOES_VULNERAVEIS_NPM: Record<string, {\n vulneravel: string;\n fix: string;\n}> = {\n 'serialize-javascript': {\n vulneravel: '<6.0.0',\n fix: 'Atualizar para serialize-javascript@>=6.0.0'\n },\n 'node-fetch': {\n vulneravel: '<2.6.7',\n fix: 'Atualizar para node-fetch@>=2.6.7'\n },\n 'tar': {\n vulneravel: '<6.1.11',\n fix: 'Atualizar para tar@>=6.1.11'\n },\n 'minimist': {\n vulneravel: '<1.2.6',\n fix: 'Atualizar para minimist@>=1.2.6'\n },\n 'lodash': {\n vulneravel: '<4.17.21',\n fix: 'Atualizar para lodash@>=4.17.21'\n },\n 'yaml': {\n vulneravel: '<2.0.0',\n fix: 'Atualizar para yaml@>=2.0.0'\n }\n};\nfunction verificarActionVulneravel(uses: string, linha: number, relPath: string): Ocorrencia | null {\n const match = uses.match(/^([a-zA-Z0-9-]+\\/[a-zA-Z0-9-]+)@(.+)$/);\n if (!match) return null;\n const [, actionRef, version] = match;\n\n // Verificar CVEs conhecidos\n for (const cve of CVES_CONHECIDOS) {\n if (actionRef === cve.action) {\n const versaoNum = parseInt(version.replace(/^v/, ''), 10);\n const maxVersao = parseInt(cve.versions.replace(/^<v/, ''), 10);\n if (!isNaN(versaoNum) && !isNaN(maxVersao) && versaoNum < maxVersao) {\n return criarOcorrencia({\n tipo: 'dependencia-vulneravel',\n nivel: cve.severidade === 'alta' ? 'erro' : cve.severidade === 'media' ? 'aviso' : 'info',\n mensagem: `${actionRef}@${version}: ${cve.descricao} (${cve.cve})`,\n relPath,\n linha,\n sugestao: cve.fix\n });\n }\n }\n }\n\n // Verificar fork suspeito - APENAS se NÃO for de organização verificada\n // SHA pinning em actions de orgs verificadas é boa prática de segurança\n if (!isOrgVerificada(actionRef)) {\n for (const pattern of FORK_SUSPEITO_PATTERNS) {\n if (pattern.test(uses)) {\n return criarOcorrencia({\n tipo: 'fork-suspeito',\n nivel: 'aviso',\n mensagem: messages.AnalistaGithubActionsMensagens.suspiciousActionDetected(uses),\n relPath,\n linha,\n sugestao: messages.AnalistaGithubActionsMensagens.suspiciousActionDetectedSugestao\n });\n }\n }\n }\n return null;\n}\nfunction verificarDependenciasNpm(runCommand: string, linha: number, relPath: string): Ocorrencia | null {\n for (const [dep, info] of Object.entries(VERSOES_VULNERAVEIS_NPM)) {\n // Detectar require/import de versões vulneráveis\n if (new RegExp(`${dep}@?[\\\\s'\\\"<>=]`).test(runCommand)) {\n if (runCommand.includes(`npm install ${dep}`) || runCommand.includes(`npm i ${dep}`)) {\n // Se instala sem versão específica, não sabemos a versão, mas vale avisar\n return criarOcorrencia({\n tipo: 'dependencia-npm-vulneravel',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.possibleVulnerableNpmDependency(dep),\n relPath,\n linha,\n sugestao: info.fix\n });\n }\n\n // Extrair versão do package.json se mencionado\n const versionMatch = runCommand.match(new RegExp(`${dep}@([\\\\d^~<>]+)`));\n if (versionMatch) {\n return criarOcorrencia({\n tipo: 'dependencia-npm-vulneravel',\n nivel: 'aviso',\n mensagem: `${dep}@${versionMatch[1]} pode conter vulnerabilidades conhecidas`,\n relPath,\n linha,\n sugestao: info.fix\n });\n }\n }\n }\n return null;\n}\nexport const detectorDependenciasVulneraveis: Analista = {\n nome: 'detector-dependencias-vulneraveis',\n categoria: 'workflows',\n descricao: 'Detecta dependências vulneráveis em GitHub Actions',\n test: (relPath: string): boolean => /\\.github\\/workflows\\/.*\\.ya?ml$/i.test(relPath),\n aplicar: (src: string, relPath: string): Ocorrencia[] => {\n if (!src) return [];\n const ocorrencias: Ocorrencia[] = [];\n const linhas = splitLines(src);\n for (let indice = 0; indice < linhas.length; indice++) {\n const linha = linhas[indice];\n const numeroLinha = indice + 1;\n\n // --- 1. Actions com CVEs conhecidos ---\n const usesMatch = linha.match(/uses:\\s*([a-zA-Z0-9-]+\\/[a-zA-Z0-9-]+@[\\w.]+)/);\n if (usesMatch) {\n const ocorrencia = verificarActionVulneravel(usesMatch[1], numeroLinha, relPath);\n if (ocorrencia) {\n ocorrencias.push(ocorrencia);\n }\n }\n\n // --- 2. Dependências npm vulneráveis em run commands ---\n if (linha.match(/run:\\s*['\"]?npm/)) {\n const npmOcorrencia = verificarDependenciasNpm(linha, numeroLinha, relPath);\n if (npmOcorrencia) {\n ocorrencias.push(npmOcorrencia);\n }\n }\n }\n\n // --- 3. Verificar falta de audit step em workflows com instalação de deps ---\n const hasInstallStep = /npm\\s+(install|i\\b)|yarn\\s+install|pnpm\\s+install/i.test(src);\n const hasAuditStep = /\\b(npm\\s+audit|yarn\\s+audit|pnpm\\s+audit|snyk|trivy)\\b/i.test(src);\n if (hasInstallStep && !hasAuditStep) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-sem-audit',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.workflowInstallsDepsWithoutAudit,\n relPath,\n linha: 1,\n sugestao: messages.AnalistaGithubActionsMensagens.workflowInstallsDepsWithoutAuditSugestao\n }));\n }\n\n // --- 4. Verificar se actions de checkout têm persist-credentials: true (padrão perigoso) ---\n // Reportar apenas uma vez por workflow, e ignorar workflows que claramente precisam de escrita\n const isReleaseOrDeployWorkflow = /release|deploy|publish|tag|changelog/i.test(src);\n const checkoutsWithoutPersistFalse: number[] = [];\n for (let indice = 0; indice < linhas.length; indice++) {\n if (/uses:\\s*actions\\/checkout/.test(linhas[indice])) {\n const proximasLinhas = linhas.slice(indice, Math.min(indice + 10, linhas.length)).join('\\n');\n if (!/persist-credentials:\\s*false/.test(proximasLinhas)) {\n checkoutsWithoutPersistFalse.push(indice + 1);\n }\n }\n }\n if (checkoutsWithoutPersistFalse.length > 0 && !isReleaseOrDeployWorkflow) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'checkout-sem-persist-credentials-false',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.checkoutsWithoutPersistCredentials(checkoutsWithoutPersistFalse.length),\n relPath,\n linha: checkoutsWithoutPersistFalse[0],\n sugestao: messages.AnalistaGithubActionsMensagens.checkoutsWithoutPersistCredentialsSugestao\n }));\n }\n return ocorrencias;\n }\n};"]}
@@ -1 +1 @@
1
- {"version":3,"file":"detector-workflow-accessibility.d.ts","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-workflow-accessibility.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAc,gBAAgB,EAAE,MAAM,GAAG,CAAC;AAIhE,eAAO,MAAM,8BAA8B,EAAE,QA+B5C,CAAC;AAEF,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,OAAO,GAAG,gBAAgB,EAAE,CA8BrF"}
1
+ {"version":3,"file":"detector-workflow-accessibility.d.ts","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-workflow-accessibility.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,QAAQ,EAAc,gBAAgB,EAAE,MAAM,GAAG,CAAC;AAGhE,eAAO,MAAM,8BAA8B,EAAE,QA+B5C,CAAC;AAEF,wBAAgB,+BAA+B,CAAC,QAAQ,EAAE,OAAO,GAAG,gBAAgB,EAAE,CA8BrF"}
@@ -1,5 +1,5 @@
1
- import { criarOcorrencia } from '../../../types/index.js';
2
1
  import { messages } from '../../../core/messages/index.js';
2
+ import { criarOcorrencia } from '../../../types/index.js';
3
3
  export const detectorWorkflowAcessibilidade = {
4
4
  nome: 'detector-workflow-acessibilidade',
5
5
  categoria: 'workflows',
@@ -1 +1 @@
1
- {"version":3,"file":"detector-workflow-accessibility.js","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-workflow-accessibility.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,eAAe,EAAE,MAAM,GAAG,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,MAAM,CAAC,MAAM,8BAA8B,GAAa;IACtD,IAAI,EAAE,kCAAkC;IACxC,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,uDAAuD;IAClE,IAAI,EAAE,CAAC,OAAe,EAAW,EAAE,CAAC,kCAAkC,CAAC,IAAI,CAAC,OAAO,CAAC;IACpF,OAAO,EAAE,CAAC,GAAW,EAAE,OAAe,EAAgB,EAAE;QACtD,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,MAAM,WAAW,GAAiB,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/B,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC;gBAC/B,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,OAAO;gBACd,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,sBAAsB;gBACxE,OAAO;gBACP,KAAK,EAAE,CAAC;gBACR,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,8BAA8B;aACjF,CAAC,CAAC,CAAC;QACN,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,+BAA+B,CAAC,QAAiB;IAC/D,MAAM,SAAS,GAAuB,EAAE,CAAC;IACzC,MAAM,EAAE,GAAG,QAMS,CAAC;IAErB,IAAI,CAAC,EAAE,EAAE,IAAI;QAAE,OAAO,SAAS,CAAC;IAEhC,IAAI,UAAU,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,SAAS,CAAC;IAErD,KAAK,MAAM,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,IAAI,CAAC,GAAG;YAAE,SAAS;QAEnB,IAAI,GAAG,CAAC,iBAAiB,CAAC;YAAE,UAAU,GAAG,IAAI,CAAC;IAChD,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,sBAAsB;YAC5B,SAAS,EAAE,QAAQ,CAAC,8BAA8B,CAAC,sBAAsB;YACzE,UAAU,EAAE,OAAO;YACnB,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,8BAA8B;SACjF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["// SPDX-License-Identifier: MIT\n/**\n * Detector de Acessibilidade para GitHub Actions\n *\n * Detecta problemas de acessibilidade/usabilidade em workflows:\n * - Steps sem nome descritivo\n * - Jobs sem timeout configurado\n */\n\nimport type { Analista, Ocorrencia, ProblemaWorkflow } from '@';\nimport { criarOcorrencia } from '@';\nimport { messages } from '@core/messages';\n\nexport const detectorWorkflowAcessibilidade: Analista = {\n nome: 'detector-workflow-acessibilidade',\n categoria: 'workflows',\n descricao: 'Detecta problemas de acessibilidade em GitHub Actions',\n test: (relPath: string): boolean => /\\.github\\/workflows\\/.*\\.ya?ml$/i.test(relPath),\n aplicar: (src: string, relPath: string): Ocorrencia[] => {\n if (!src) return [];\n const ocorrencias: Ocorrencia[] = [];\n const linhas = src.split('\\n');\n\n let hasTimeout = false;\n\n linhas.forEach((linha) => {\n if (/timeout-minutes/.test(linha)) {\n hasTimeout = true;\n }\n });\n\n if (!hasTimeout) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-sem-timeout',\n nivel: 'aviso',\n mensagem: messages.AnalistaGithubActionsMensagens.workflowWithoutTimeout,\n relPath,\n linha: 1,\n sugestao: messages.AnalistaGithubActionsMensagens.workflowWithoutTimeoutSugestao\n }));\n }\n\n return ocorrencias;\n }\n};\n\nexport function detectarProblemasAcessibilidade(workflow: unknown): ProblemaWorkflow[] {\n const problemas: ProblemaWorkflow[] = [];\n const wf = workflow as {\n jobs?: Record<string, {\n steps?: Array<{ name?: string; run?: string }>;\n 'timeout-minutes'?: number;\n }>;\n 'timeout-minutes'?: number;\n } | null | undefined;\n\n if (!wf?.jobs) return problemas;\n\n let hasTimeout = wf['timeout-minutes'] !== undefined;\n\n for (const [, job] of Object.entries(wf.jobs)) {\n if (!job) continue;\n\n if (job['timeout-minutes']) hasTimeout = true;\n }\n\n if (!hasTimeout) {\n problemas.push({\n tipo: 'workflow-sem-timeout',\n descricao: messages.AnalistaGithubActionsMensagens.workflowWithoutTimeout,\n severidade: 'media',\n sugestao: messages.AnalistaGithubActionsMensagens.workflowWithoutTimeoutSugestao\n });\n }\n\n return problemas;\n}\n"]}
1
+ {"version":3,"file":"detector-workflow-accessibility.js","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-workflow-accessibility.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C,OAAO,EAAE,eAAe,EAAE,MAAM,GAAG,CAAC;AAEpC,MAAM,CAAC,MAAM,8BAA8B,GAAa;IACtD,IAAI,EAAE,kCAAkC;IACxC,SAAS,EAAE,WAAW;IACtB,SAAS,EAAE,uDAAuD;IAClE,IAAI,EAAE,CAAC,OAAe,EAAW,EAAE,CAAC,kCAAkC,CAAC,IAAI,CAAC,OAAO,CAAC;IACpF,OAAO,EAAE,CAAC,GAAW,EAAE,OAAe,EAAgB,EAAE;QACtD,IAAI,CAAC,GAAG;YAAE,OAAO,EAAE,CAAC;QACpB,MAAM,WAAW,GAAiB,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/B,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,UAAU,GAAG,IAAI,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC;gBAC/B,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,OAAO;gBACd,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,sBAAsB;gBACxE,OAAO;gBACP,KAAK,EAAE,CAAC;gBACR,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,8BAA8B;aACjF,CAAC,CAAC,CAAC;QACN,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;CACF,CAAC;AAEF,MAAM,UAAU,+BAA+B,CAAC,QAAiB;IAC/D,MAAM,SAAS,GAAuB,EAAE,CAAC;IACzC,MAAM,EAAE,GAAG,QAMS,CAAC;IAErB,IAAI,CAAC,EAAE,EAAE,IAAI;QAAE,OAAO,SAAS,CAAC;IAEhC,IAAI,UAAU,GAAG,EAAE,CAAC,iBAAiB,CAAC,KAAK,SAAS,CAAC;IAErD,KAAK,MAAM,CAAC,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,IAAI,CAAC,GAAG;YAAE,SAAS;QAEnB,IAAI,GAAG,CAAC,iBAAiB,CAAC;YAAE,UAAU,GAAG,IAAI,CAAC;IAChD,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,sBAAsB;YAC5B,SAAS,EAAE,QAAQ,CAAC,8BAA8B,CAAC,sBAAsB;YACzE,UAAU,EAAE,OAAO;YACnB,QAAQ,EAAE,QAAQ,CAAC,8BAA8B,CAAC,8BAA8B;SACjF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC","sourcesContent":["// SPDX-License-Identifier: MIT\n/**\n * Detector de Acessibilidade para GitHub Actions\n *\n * Detecta problemas de acessibilidade/usabilidade em workflows:\n * - Steps sem nome descritivo\n * - Jobs sem timeout configurado\n */\n\nimport { messages } from '@core/messages';\n\nimport type { Analista, Ocorrencia, ProblemaWorkflow } from '@';\nimport { criarOcorrencia } from '@';\n\nexport const detectorWorkflowAcessibilidade: Analista = {\n nome: 'detector-workflow-acessibilidade',\n categoria: 'workflows',\n descricao: 'Detecta problemas de acessibilidade em GitHub Actions',\n test: (relPath: string): boolean => /\\.github\\/workflows\\/.*\\.ya?ml$/i.test(relPath),\n aplicar: (src: string, relPath: string): Ocorrencia[] => {\n if (!src) return [];\n const ocorrencias: Ocorrencia[] = [];\n const linhas = src.split('\\n');\n\n let hasTimeout = false;\n\n linhas.forEach((linha) => {\n if (/timeout-minutes/.test(linha)) {\n hasTimeout = true;\n }\n });\n\n if (!hasTimeout) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-sem-timeout',\n nivel: 'aviso',\n mensagem: messages.AnalistaGithubActionsMensagens.workflowWithoutTimeout,\n relPath,\n linha: 1,\n sugestao: messages.AnalistaGithubActionsMensagens.workflowWithoutTimeoutSugestao\n }));\n }\n\n return ocorrencias;\n }\n};\n\nexport function detectarProblemasAcessibilidade(workflow: unknown): ProblemaWorkflow[] {\n const problemas: ProblemaWorkflow[] = [];\n const wf = workflow as {\n jobs?: Record<string, {\n steps?: Array<{ name?: string; run?: string }>;\n 'timeout-minutes'?: number;\n }>;\n 'timeout-minutes'?: number;\n } | null | undefined;\n\n if (!wf?.jobs) return problemas;\n\n let hasTimeout = wf['timeout-minutes'] !== undefined;\n\n for (const [, job] of Object.entries(wf.jobs)) {\n if (!job) continue;\n\n if (job['timeout-minutes']) hasTimeout = true;\n }\n\n if (!hasTimeout) {\n problemas.push({\n tipo: 'workflow-sem-timeout',\n descricao: messages.AnalistaGithubActionsMensagens.workflowWithoutTimeout,\n severidade: 'media',\n sugestao: messages.AnalistaGithubActionsMensagens.workflowWithoutTimeoutSugestao\n });\n }\n\n return problemas;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"detector-workflow-security.d.ts","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-workflow-security.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,GAAG,CAAC;AAM9C,eAAO,MAAM,wBAAwB,EAAE,QA4JtC,CAAC"}
1
+ {"version":3,"file":"detector-workflow-security.d.ts","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-workflow-security.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,GAAG,CAAC;AAK9C,eAAO,MAAM,wBAAwB,EAAE,QA4JtC,CAAC"}
@@ -1,7 +1,7 @@
1
+ import { messages } from '../../../core/messages/index.js';
1
2
  import { splitLines } from '../../../shared/helpers/index.js';
2
3
  import { criarOcorrencia } from '../../../types/index.js';
3
4
  import { isOrgVerificada } from './org-verified.js';
4
- import { messages } from '../../../core/messages/index.js';
5
5
  export const detectorWorkflowSecurity = {
6
6
  nome: 'detector-workflow-security',
7
7
  categoria: 'workflows',
@@ -1 +1 @@
1
- {"version":3,"file":"detector-workflow-security.js","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-workflow-security.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\n/**\n * [BUSCA] Detector de segurança GitHub Actions\n *\n * Detecta vulnerabilidades em workflows:\n * - Script injection\n * - Missing SHA pinning\n * - Hardcoded secrets\n * - sudo usage\n * - pull_request_target\n * - Missing permissions\n */\n\nimport { splitLines } from '@shared/helpers';\n\nimport type { Analista, Ocorrencia } from '@';\nimport { criarOcorrencia } from '@';\n\nimport { isOrgVerificada } from './org-verified.js';\nimport { messages } from '@core/messages';\n\nexport const detectorWorkflowSecurity: Analista = {\n nome: 'detector-workflow-security',\n categoria: 'workflows',\n descricao: 'Detecta vulnerabilidades em GitHub Actions',\n test: (relPath: string): boolean => /\\.github\\/workflows\\/.*\\.ya?ml$/i.test(relPath),\n aplicar: (src: string, relPath: string): Ocorrencia[] => {\n if (!src) return [];\n const ocorrencias: Ocorrencia[] = [];\n const linhas = splitLines(src);\n\n const actionsSemShaPinning: Array<{ linha: number; action: string }> = [];\n\n linhas.forEach((linha, index) => {\n const numeroLinha = index + 1;\n\n if (/\\$\\{\\{\\s*github\\.event\\./.test(linha) && /run:/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-script-injection',\n nivel: 'erro',\n mensagem: messages.AnalistaGithubActionsMensagens.possibleScriptInjection,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.possibleScriptInjectionSugestao\n }));\n }\n\n const usesMatch = linha.match(/uses:\\s*([^\\s@]+)@([^\\s]+)/);\n if (usesMatch) {\n const [, actionRef, version] = usesMatch;\n if (/^v\\d+/.test(version) && !isOrgVerificada(actionRef)) {\n actionsSemShaPinning.push({ linha: numeroLinha, action: `${actionRef}@${version}` });\n }\n }\n\n if (/\\b(KEY|TOKEN|SECRET|PASSWORD)\\b.*[:=]\\s*['\"][^'\"]+['\"]/i.test(linha) && !/\\$\\{\\{/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-hardcoded-secret',\n nivel: 'erro',\n mensagem: messages.AnalistaGithubActionsMensagens.hardcodedSecret,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.hardcodedSecretSugestao\n }));\n }\n\n if (/\\bsudo\\s+/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-sudo-usage',\n nivel: 'aviso',\n mensagem: messages.AnalistaGithubActionsMensagens.sudoUsageDetected,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.sudoUsageDetectedSugestao\n }));\n }\n\n if (/\\/home\\/runner\\//.test(linha) || /\\/tmp\\//.test(linha)) {\n const isGitHubVar = /\\$\\{?\\{?\\s*(runner\\.temp|GITHUB_WORKSPACE|RUNNER_TEMP)/.test(linha);\n const isComment = linha.trim().startsWith('#');\n const isCleanupCommand = /rm\\s+-.+\\/tmp\\//.test(linha);\n if (!isGitHubVar && !isComment && !isCleanupCommand) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-hardcoded-path',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.absoluteTempPathHardcoded,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.absoluteTempPathHardcodedSugestao\n }));\n }\n }\n\n if (/echo\\s+.*::set-output\\s+name=.*secret/i.test(linha) || (/echo\\s+.*\\$(SECRET|TOKEN|KEY)/i.test(linha) && !/::add-mask::/i.test(src))) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-sensitive-output',\n nivel: 'erro',\n mensagem: messages.AnalistaGithubActionsMensagens.possibleSecretExposure,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.possibleSecretExposureSugestao\n }));\n }\n\n if (/pull_request_target:/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-pr-target',\n nivel: 'erro',\n mensagem: messages.AnalistaGithubActionsMensagens.pullRequestTargetExecutesForkCode,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.pullRequestTargetExecutesForkCodeSugestao\n }));\n }\n\n if (/workflow_run:/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-run-trigger',\n nivel: 'aviso',\n mensagem: messages.AnalistaGithubActionsMensagens.workflowRunUnsafe,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.workflowRunUnsafeSugestao\n }));\n }\n\n if (/checkout@v\\d+/.test(linha) && /fetch-depth:\\s*0/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-fetch-depth-zero',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.checkoutFetchDepthZero,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.checkoutFetchDepthZeroSugestao\n }));\n }\n });\n\n if (actionsSemShaPinning.length > 0) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-missing-sha-pinning',\n nivel: 'aviso',\n mensagem: `${actionsSemShaPinning.length} action(s) de terceiros sem pinning por SHA: ${actionsSemShaPinning.map(a => a.action).join(', ')}`,\n relPath,\n linha: 1,\n sugestao: 'Use @<commit-sha-completo> para garantir integridade da action'\n }));\n }\n\n if (!/permissions:/.test(src)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-missing-permissions',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.permissionsNotDefined,\n relPath,\n linha: 1,\n sugestao: messages.AnalistaGithubActionsMensagens.permissionsNotDefinedSugestao\n }));\n }\n\n const hasAuditStep = /\\b(npm audit|yarn audit|snyk|trivy|checkov|terrascan|gitleaks|semgrep)\\b/i.test(src);\n const isBuildOrDeploy = /\\b(npm install|yarn|pnpm|build|deploy|publish|docker build|docker push)\\b/i.test(src);\n const isSecurityWorkflow = /codeql|security-advanced|security-enhanced-code-scanning/i.test(src);\n\n if (isBuildOrDeploy && !hasAuditStep && !isSecurityWorkflow) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-missing-security-scan',\n nivel: 'aviso',\n mensagem: messages.AnalistaGithubActionsMensagens.buildDeployWithoutSecurityAudit,\n relPath,\n linha: 1,\n sugestao: messages.AnalistaGithubActionsMensagens.buildDeployWithoutSecurityAuditSugestao\n }));\n }\n\n return ocorrencias;\n }\n};\n"]}
1
+ {"version":3,"file":"detector-workflow-security.js","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-workflow-security.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: MIT\n/**\n * [BUSCA] Detector de segurança GitHub Actions\n *\n * Detecta vulnerabilidades em workflows:\n * - Script injection\n * - Missing SHA pinning\n * - Hardcoded secrets\n * - sudo usage\n * - pull_request_target\n * - Missing permissions\n */\n\nimport { messages } from '@core/messages';\nimport { splitLines } from '@shared/helpers';\n\nimport type { Analista, Ocorrencia } from '@';\nimport { criarOcorrencia } from '@';\n\nimport { isOrgVerificada } from './org-verified.js';\n\nexport const detectorWorkflowSecurity: Analista = {\n nome: 'detector-workflow-security',\n categoria: 'workflows',\n descricao: 'Detecta vulnerabilidades em GitHub Actions',\n test: (relPath: string): boolean => /\\.github\\/workflows\\/.*\\.ya?ml$/i.test(relPath),\n aplicar: (src: string, relPath: string): Ocorrencia[] => {\n if (!src) return [];\n const ocorrencias: Ocorrencia[] = [];\n const linhas = splitLines(src);\n\n const actionsSemShaPinning: Array<{ linha: number; action: string }> = [];\n\n linhas.forEach((linha, index) => {\n const numeroLinha = index + 1;\n\n if (/\\$\\{\\{\\s*github\\.event\\./.test(linha) && /run:/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-script-injection',\n nivel: 'erro',\n mensagem: messages.AnalistaGithubActionsMensagens.possibleScriptInjection,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.possibleScriptInjectionSugestao\n }));\n }\n\n const usesMatch = linha.match(/uses:\\s*([^\\s@]+)@([^\\s]+)/);\n if (usesMatch) {\n const [, actionRef, version] = usesMatch;\n if (/^v\\d+/.test(version) && !isOrgVerificada(actionRef)) {\n actionsSemShaPinning.push({ linha: numeroLinha, action: `${actionRef}@${version}` });\n }\n }\n\n if (/\\b(KEY|TOKEN|SECRET|PASSWORD)\\b.*[:=]\\s*['\"][^'\"]+['\"]/i.test(linha) && !/\\$\\{\\{/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-hardcoded-secret',\n nivel: 'erro',\n mensagem: messages.AnalistaGithubActionsMensagens.hardcodedSecret,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.hardcodedSecretSugestao\n }));\n }\n\n if (/\\bsudo\\s+/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-sudo-usage',\n nivel: 'aviso',\n mensagem: messages.AnalistaGithubActionsMensagens.sudoUsageDetected,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.sudoUsageDetectedSugestao\n }));\n }\n\n if (/\\/home\\/runner\\//.test(linha) || /\\/tmp\\//.test(linha)) {\n const isGitHubVar = /\\$\\{?\\{?\\s*(runner\\.temp|GITHUB_WORKSPACE|RUNNER_TEMP)/.test(linha);\n const isComment = linha.trim().startsWith('#');\n const isCleanupCommand = /rm\\s+-.+\\/tmp\\//.test(linha);\n if (!isGitHubVar && !isComment && !isCleanupCommand) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-hardcoded-path',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.absoluteTempPathHardcoded,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.absoluteTempPathHardcodedSugestao\n }));\n }\n }\n\n if (/echo\\s+.*::set-output\\s+name=.*secret/i.test(linha) || (/echo\\s+.*\\$(SECRET|TOKEN|KEY)/i.test(linha) && !/::add-mask::/i.test(src))) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-sensitive-output',\n nivel: 'erro',\n mensagem: messages.AnalistaGithubActionsMensagens.possibleSecretExposure,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.possibleSecretExposureSugestao\n }));\n }\n\n if (/pull_request_target:/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-pr-target',\n nivel: 'erro',\n mensagem: messages.AnalistaGithubActionsMensagens.pullRequestTargetExecutesForkCode,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.pullRequestTargetExecutesForkCodeSugestao\n }));\n }\n\n if (/workflow_run:/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-run-trigger',\n nivel: 'aviso',\n mensagem: messages.AnalistaGithubActionsMensagens.workflowRunUnsafe,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.workflowRunUnsafeSugestao\n }));\n }\n\n if (/checkout@v\\d+/.test(linha) && /fetch-depth:\\s*0/.test(linha)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-fetch-depth-zero',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.checkoutFetchDepthZero,\n relPath,\n linha: numeroLinha,\n sugestao: messages.AnalistaGithubActionsMensagens.checkoutFetchDepthZeroSugestao\n }));\n }\n });\n\n if (actionsSemShaPinning.length > 0) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-missing-sha-pinning',\n nivel: 'aviso',\n mensagem: `${actionsSemShaPinning.length} action(s) de terceiros sem pinning por SHA: ${actionsSemShaPinning.map(a => a.action).join(', ')}`,\n relPath,\n linha: 1,\n sugestao: 'Use @<commit-sha-completo> para garantir integridade da action'\n }));\n }\n\n if (!/permissions:/.test(src)) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-missing-permissions',\n nivel: 'info',\n mensagem: messages.AnalistaGithubActionsMensagens.permissionsNotDefined,\n relPath,\n linha: 1,\n sugestao: messages.AnalistaGithubActionsMensagens.permissionsNotDefinedSugestao\n }));\n }\n\n const hasAuditStep = /\\b(npm audit|yarn audit|snyk|trivy|checkov|terrascan|gitleaks|semgrep)\\b/i.test(src);\n const isBuildOrDeploy = /\\b(npm install|yarn|pnpm|build|deploy|publish|docker build|docker push)\\b/i.test(src);\n const isSecurityWorkflow = /codeql|security-advanced|security-enhanced-code-scanning/i.test(src);\n\n if (isBuildOrDeploy && !hasAuditStep && !isSecurityWorkflow) {\n ocorrencias.push(criarOcorrencia({\n tipo: 'workflow-missing-security-scan',\n nivel: 'aviso',\n mensagem: messages.AnalistaGithubActionsMensagens.buildDeployWithoutSecurityAudit,\n relPath,\n linha: 1,\n sugestao: messages.AnalistaGithubActionsMensagens.buildDeployWithoutSecurityAuditSugestao\n }));\n }\n\n return ocorrencias;\n }\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"detector-workflow-trigger-unsafe.d.ts","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-workflow-trigger-unsafe.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,GAAG,CAAC;AAQ9C,eAAO,MAAM,+BAA+B,EAAE,QAiM7C,CAAC"}
1
+ {"version":3,"file":"detector-workflow-trigger-unsafe.d.ts","sourceRoot":"","sources":["../../../../src/analysts/github-actions/detectors/detector-workflow-trigger-unsafe.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,GAAG,CAAC;AAO9C,eAAO,MAAM,+BAA+B,EAAE,QAiM7C,CAAC"}
@@ -1,7 +1,7 @@
1
+ import { messages } from '../../../core/messages/index.js';
1
2
  import { splitLines } from '../../../shared/helpers/index.js';
2
3
  import { parseDocument } from 'yaml';
3
4
  import { criarOcorrencia } from '../../../types/index.js';
4
- import { messages } from '../../../core/messages/index.js';
5
5
  const BRANCHES_PROTEGIDOS = ['main', 'master', 'production', 'release', 'prod'];
6
6
  const DANGEROUS_ACTIONS = ['actions/checkout', 'peter-evans/create-or-update-comment', 'peter-evans/create-pull-request', 'marocchino/sticky-pull-request', 'softprops/action-gh-release', 'ncipollo/release-action', 'docker/build-push-action', 'docker/login-action', 'docker/push-action', 'aws-actions/configure-aws-credentials', 'google-github-actions/auth', 'azure/login', 'hashicorp/vault-action'];
7
7
  export const detectorWorkflowTriggerInseguro = {