From f8d2b43fd139a1fb91520a8180b300cc10b8a63f Mon Sep 17 00:00:00 2001 From: Roberto T <61755417+RobertGlobant20@users.noreply.github.com> Date: Wed, 9 Aug 2023 07:59:59 -0700 Subject: [PATCH] DYN-6049 Github Actions Security Fix2 (#14237) For preventing code injection in the issue github.event.issue.title and github.event.issue.body, I've removed parameters passed to ps scripts and declare the environment variables in yaml files, so in this way the ps script have access to env variables without receiving parameters. Also in the issues_workflow.yaml I've introduced a new validation that if the issue_title contains special characters like ";{}"" then the job will be canceled. Finally I've added several comments for making more clear the purpose of each step. --- .github/scripts/get_issue_json_body.ps1 | 5 ++- .github/scripts/issue_analyzer.ps1 | 8 ++--- .github/scripts/issue_body_cleaner.ps1 | 4 +-- .github/scripts/title_analyzer.ps1 | 8 ++--- .github/workflows/Issues_workflow.yaml | 38 ++++++++++++++++----- .github/workflows/issue_type_predicter.yaml | 15 ++++---- 6 files changed, 50 insertions(+), 28 deletions(-) diff --git a/.github/scripts/get_issue_json_body.ps1 b/.github/scripts/get_issue_json_body.ps1 index 871d6d12618..253d386dc24 100644 --- a/.github/scripts/get_issue_json_body.ps1 +++ b/.github/scripts/get_issue_json_body.ps1 @@ -1,4 +1,7 @@ -param([int]$issueNumber, [string]$issueTitle, [string]$issueDescription) +param([int]$issueNumber) + +$issueTitle = $env:ISSUE_TITLE +$issueDescription = $env:parsed_issue_body $json_object = @{ Number = $issueNumber diff --git a/.github/scripts/issue_analyzer.ps1 b/.github/scripts/issue_analyzer.ps1 index 9ab041de302..30fe1cff7ef 100644 --- a/.github/scripts/issue_analyzer.ps1 +++ b/.github/scripts/issue_analyzer.ps1 @@ -1,10 +1,9 @@ - -#--Params-- +#--Params-- #issueTemplateFile: Name of the template file including extension (ex: ISSUE_TEMPLATE.md) #issueContent: Body of the issue to be analyzed #acceptableEmptyFields: Amount of fields from the template that can be missing information # in the issue (1 if unspecified) -param([string]$issueTemplateFile, [string]$issueContent, [int]$acceptableEmptyFields = 1) +param([string]$issueTemplateFile, [int]$acceptableEmptyFields = 1) #Loads the requiered functions . .\.github\scripts\issue_comparator.ps1 @@ -12,6 +11,7 @@ param([string]$issueTemplateFile, [string]$issueContent, [int]$acceptableEmptyFi #--Processing-- $issueTemplate = Get-Content -Raw -Path .github\$issueTemplateFile +$issueContent = $env:ISSUE_BODY #Parse the template and issue $parsed_issue_content = Get_Parsed_Issue $issueContent @@ -47,4 +47,4 @@ if (($analysis_result -eq " ") -or ($missingFields -le $acceptableEmptyFields)) #--Output-- #"Valid" if the issue has the necessary information # or string with section titles if information is missing -$analysis_result +$analysis_result \ No newline at end of file diff --git a/.github/scripts/issue_body_cleaner.ps1 b/.github/scripts/issue_body_cleaner.ps1 index 69633b2b8c1..b4b233a3591 100644 --- a/.github/scripts/issue_body_cleaner.ps1 +++ b/.github/scripts/issue_body_cleaner.ps1 @@ -1,5 +1,3 @@ -param([string]$issueContent) - #Loads the requiered functions . .\.github\scripts\issue_parser.ps1 @@ -24,6 +22,8 @@ function RemoveSpecialCharacters($InputString) return $InputString } +$issueContent = $env:ISSUE_BODY_PARSED + $TitleFilters = @("Dynamo version".ToLower(), "Operating system".ToLower(), "Stack Trace".ToLower()) diff --git a/.github/scripts/title_analyzer.ps1 b/.github/scripts/title_analyzer.ps1 index 8056ec6ee74..8f2d99bab9a 100644 --- a/.github/scripts/title_analyzer.ps1 +++ b/.github/scripts/title_analyzer.ps1 @@ -1,12 +1,10 @@ -#--Params-- -#issueTitle: Title of the issue -param([string]$issueTitle) - #Contains a collection of {Label, Keywords}. #"label" is the label to be use if specific "keywords" are found on a section $labelsData = .\.github\LabelsKeywordsConfig.ps1 $label = 'undefined' +$issueTitle = $env:ISSUE_TITLE_PARSED + #Iterates over the posible labels foreach ($labelData in $labelsData) { #Iterates over the different keywords for the specific label @@ -20,6 +18,6 @@ foreach ($labelData in $labelsData) { #Response if($label -ne 'undefined') - { Write-Output ($label) } + { Write-Output ($label)} else { Write-Output ('Valid') } diff --git a/.github/workflows/Issues_workflow.yaml b/.github/workflows/Issues_workflow.yaml index 285d228f20b..81760d6ede3 100644 --- a/.github/workflows/Issues_workflow.yaml +++ b/.github/workflows/Issues_workflow.yaml @@ -12,26 +12,48 @@ jobs: #and then checked on step two to know if adding any labels is necessary. #The initial 'undefined' value will be overridden when the script runs. content_analysis_response: undefined + ISSUE_TITLE: ${{github.event.issue.title}} + ISSUE_BODY: ${{github.event.issue.body}} outputs: result: ${{env.content_analysis_response}} steps: - uses: actions/checkout@v2 + + #Detect if the issue_title follows the regex expression + - name: Check Issue Title + uses: actions-ecosystem/action-regex-match@v2 + id: regex-match + with: + text: ${{github.event.issue.title}} + regex: '^[A-Za-z0-9 _.]*$' + flags: g + + #If the regex output is '' means that the issue title contains special chars + - name: Exit Job + if: ${{ steps.regex-match.outputs.match == '' }} + run: | + echo "Bad Issue Title Format" + exit 1 + + #Remove the " character in the issue title and replaced with - - name: Remove conflicting chars - env: - ISSUE_TITLE: ${{github.event.issue.title}} uses: frabert/replace-string-action@v1.2 id: remove_quotations with: pattern: "\"" - string: ${{env.ISSUE_TITLE}} + string: ${{env.ISSUE_TITLE}} replace-with: '-' flags: g + + #According to the issue_title returns a specific label - name: Check Information + id: check-info env: ISSUE_TITLE_PARSED: ${{steps.remove_quotations.outputs.replaced}} - id: check-info run: | - echo "content_analysis_response=$(pwsh .\\.github\\scripts\\title_analyzer.ps1 "${{ env.ISSUE_TITLE_PARSED }}" )" >> $GITHUB_ENV + echo "content_analysis_response=$(pwsh .\\.github\\scripts\\title_analyzer.ps1)" >> $GITHUB_ENV + + #labels the issue based in the text returned in content_analysis_response var - name: Label issue if: env.content_analysis_response != 'Valid' #Uses DYNAMOBOTTOKEN to allow interaction between repos @@ -101,11 +123,11 @@ jobs: #Checks for missing information inside the issue content - name: Check Information - env: - ISSUE_TITLE_PARSED: ${{steps.remove_quotations.outputs.replaced}} id: check-info + env: + ISSUE_BODY: ${{ steps.remove_quotations.outputs.replaced }} run: | - echo "analysis_response=$(pwsh .\\.github\\scripts\\issue_analyzer.ps1 "${{ env.template }}" "${{ env.ISSUE_TITLE_PARSED }}" "${{ env.acceptable_missing_info }}" )" >> $GITHUB_ENV + echo "analysis_response=$(pwsh .\\.github\\scripts\\issue_analyzer.ps1 "${{ env.template }}" "${{ env.acceptable_missing_info }}" )" >> $GITHUB_ENV #Closes the issue if the analysis response is "Empty" - name: Close issue diff --git a/.github/workflows/issue_type_predicter.yaml b/.github/workflows/issue_type_predicter.yaml index 55a98a6c830..7526fa5ec16 100644 --- a/.github/workflows/issue_type_predicter.yaml +++ b/.github/workflows/issue_type_predicter.yaml @@ -36,12 +36,12 @@ jobs: #Checks for missing information inside the issue content - name: Check Information - env: - ISSUE_BODY_PARSED: ${{steps.remove_quotations.outputs.replaced}} id: check-info + env: + ISSUE_BODY: ${{ steps.remove_quotations.outputs.replaced }} + ISSUE_TITLE: ${{ github.event.issue.title }} run: | - ls -la - echo "analysis_response=$(pwsh .\\.github\\scripts\\issue_analyzer.ps1 "${{ env.template }}" "${{ env.ISSUE_BODY_PARSED }}" "${{ env.acceptable_missing_info }}" )" >> $GITHUB_ENV + echo "analysis_response=$(pwsh .\\.github\\scripts\\issue_analyzer.ps1 "${{ env.template }}" "${{ env.acceptable_missing_info }}" )" >> $GITHUB_ENV #Remove sections in the issue body like "Dynamo version", "Stack Trace" because won't be used to predict the issue type - name: Clean Issue Body @@ -50,19 +50,18 @@ jobs: if: env.analysis_response == 'Valid' id: clean-issue-body run: | - echo "parsed_issue_body="$(pwsh .\\.github\\scripts\\issue_body_cleaner.ps1 "${{ env.ISSUE_BODY_PARSED }}" )"" >> $GITHUB_ENV + echo "parsed_issue_body="$(pwsh .\\.github\\scripts\\issue_body_cleaner.ps1 )"" >> $GITHUB_ENV #The IssuesTypePredicter program receives as a parameter a json string with the issue content, then It's creating the json string in this section based in the issue body - name: Create Issue JSON String env: ISSUE_NUMBER: ${{github.event.issue.number}} - ISSUE_TITLE: ${{github.event.issue.title}} - ISSUE_BODY: ${{env.parsed_issue_body}} + ISSUE_TITLE: ${{github.event.issue.title}} if: env.analysis_response == 'Valid' id: create-issue-json run: | mkdir IssuesTypePredicter - echo "issue_json_string="$(pwsh .\\.github\\scripts\\get_issue_json_body.ps1 "$ISSUE_NUMBER" "$ISSUE_TITLE" "$ISSUE_BODY" )"" >> $GITHUB_ENV + echo "issue_json_string="$(pwsh .\\.github\\scripts\\get_issue_json_body.ps1 "$ISSUE_NUMBER")"" >> $GITHUB_ENV #Now checkout the IssuesTypePredicter source code from the repo https://github.com/DynamoDS/IssuesTypePredicter - name: Checkout IssuesTypePredicter