jenkinsjenkins-pluginsjenkins-cli

Security warnings for plugins via Jenkins CLI?


I'm trying to monitor my Jenkins instances by using the Jenkins CLI. Most important are security warnings like given in the Jenkins Security Advisories. Those are shown in the GUI in the upper right corner by red and orange warning symbols: enter image description here

I can use the CLI to list all my plugins and possible updates for these:

java -jar ./jenkins-cli.jar <host> -auth <token> list-plugins | grep -E '\([0-9].[0-9].*\)'

This returns a three columned list like

docker-commons Docker Commons Plugin 1.20 (1.21)

where 1.20 tells me the currently installed version and (1.21) tells me the currently available version.

But still I could not find a CLI-call to tell whether a listed plugin has a known vulnerability. This information seems only to be available in the GUI?


Solution

  • I found the solution on https://community.jenkins.io/t/jenkins-plugins-security-warnings/2266/2.

    It seems there's no native call to get those information. But one can curl the latest information from https://updates.jenkins.io/update-center.actual.json.

    Then you probably need to code the rest of it yourself. You find the security alerts in the warnings part of the json. In each warning you find a subsection "versions" where lastVersion probably means the last affected version by this warning. By using the (hopefully well-kept) pattern you can compare your used version to the latestVersion.

    I'm currently trying to build a usable bash-script for this task and will update my answer later on when I have finished the script but since I'm not a bash scripting guy this might take a while.

    Edit: I got it working. Maybe it's helpful for anyone else, but as I said, I'm not the bash-scripting guy.

    #!/bin/bash
    DELIMITER=";"
    #Getting all information from the Jenkins Update Center
    items=$(curl -qLs https://updates.jenkins.io/update-center.actual.json)
    
    #Getting installed plugins from Jenkins
    results=$(java -jar jenkins-cli.jar -s <host>  -auth <token> list-plugins)
    
    #and writing it to an array.
    readarray -t plugins <<<"$results"
    
    for i in "${!plugins[@]}"; do
      #keep format (with whitespaces):
      #matrix-project                     Matrix Project Plugin                                            772.v494f19991984 (785.v06b_7f47b_c631)
      formattedLine=$(echo "${plugins[$i]}");
    
      #replace 2 or more whitespaces by the delimiter.
      #matrix-project;Matrix Project Plugin;772.v494f19991984 (785.v06b_7f47b_c631)
      replacedWhitespaces=$(echo "$formattedLine" | sed "s/ \{2,\}/$DELIMITER/g")
    
      #split result into an array
      #[0]matrix-project
      #[1]Matrix Project Plugin
      #[2]772.v494f19991984 (785.v06b_7f47b_c631)
      IFS="$DELIMITER" read -r -a parts <<< "$replacedWhitespaces"
    
      #check whether there is an update available or not 
      #<=> if there is a () separated by a whitespace or not
      if [[ "${parts[2]}" =~ \ |\' ]] 
        then
          IFS=' ' read -r -a subparts <<< "${parts[2]}";
          parts[2]=$(echo "${subparts[0]}")
          parts[3]=$(echo "${subparts[1]}")
        else
          parts[3]=""
      fi
        
      echo "name: ${parts[0]}"
      echo "description: ${parts[1]}"  
      echo "Used Version: ${parts[2]}"
      echo "Latest Version: ${parts[3]}"
      echo "Vulnerabilities:"
     
      #find vulnerabilities to this plugin:
      vulnerabilities=$(echo "$items" | ./jq-win64 -c -r --arg pluginName "${parts[0]}" '.warnings[] | select(.name==$pluginName)')
     
      #separate vulnerabilities
      IFS=$'\n' res=($vulnerabilities)
      
      #get the relevant content from each vulnerability
      for r in "${!res[@]}"; do
        lastVersion=$(echo "${res[$r]}" | ./jq-win64 -r -c '.versions[0]|.lastVersion')
        id=$(echo "${res[$r]}" | ./jq-win64 -r -c '.|.id')
        message=$(echo "${res[$r]}" | ./jq-win64 -r -c '.|.message')
        url=$(echo "${res[$r]}" | ./jq-win64 -r -c '.|.url')
        echo "* <=$lastVersion: $id - $message ($url)";
      done;
      
      echo "------------------------------------------------------------"
    done