Add GitHub Security Advisory Database (#29)

* Add GitHub Security Advisory

* Update go.mod

* Fix main.go

* Exec go mod tidy

* Change travis ci

* Fix Bugs...

* Add remobe directory

* Update review

* ghsa: Remove package level state

Signed-off-by: Simarpreet Singh <simar@linux.com>

* Add retry test

* test(ghsa): remove unneeded testdata

* refactor(ghsa): rename VersionAdvisories to Versions

* refactor(ghsa): unexport members

* refactor(ghsa): fix warnings

* refactor(ghsa): replace githubql with githubv4

* refactor(ghsa): update log messages

* refactor(ghsa): update error messages

* refactor(ghsa): unexport a function

* refactor(ghsa): make it  possible to replace wait function

* Fix empty line

Co-authored-by: Simarpreet Singh <simar@linux.com>
Co-authored-by: Teppei Fukuda <knqyf263@gmail.com>
This commit is contained in:
Masahiro Fujimura 2020-02-28 15:15:34 +09:00 committed by GitHub
parent 0fcaa3e3d3
commit 11f2a4cbee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 931 additions and 7 deletions

View File

@ -80,6 +80,11 @@ jobs:
script:
- go run main.go -target photon
- stage: 'GitHub Security Advisory'
if: type = cron
script:
- go run main.go -target ghsa
- stage: 'SUSE CVRF'
if: type = cron
script:

182
ghsa/ghsa.go Normal file
View File

@ -0,0 +1,182 @@
package ghsa
import (
"context"
"fmt"
"log"
"math"
"os"
"path/filepath"
"strings"
"time"
"github.com/aquasecurity/vuln-list-update/utils"
"github.com/cheggaaa/pb"
githubql "github.com/shurcooL/githubv4"
"github.com/shurcooL/graphql"
"github.com/spf13/afero"
"golang.org/x/xerrors"
)
// https://developer.github.com/v4/enum/securityadvisoryecosystem/
type SecurityAdvisoryEcosystem string
var (
Composer SecurityAdvisoryEcosystem = "COMPOSER"
Maven SecurityAdvisoryEcosystem = "MAVEN"
Npm SecurityAdvisoryEcosystem = "NPM"
Nuget SecurityAdvisoryEcosystem = "NUGET"
Pip SecurityAdvisoryEcosystem = "PIP"
Rubygems SecurityAdvisoryEcosystem = "RUBYGEMS"
Ecosystems = []SecurityAdvisoryEcosystem{Composer, Maven, Npm, Nuget, Pip, Rubygems}
wait = func(i int) time.Duration {
sleep := math.Pow(float64(i), 2) + float64(utils.RandInt()%10)
return time.Duration(sleep) * time.Second
}
)
const (
ghsaDir = "ghsa"
retry = 5
maxResponseSize = 100
)
type Config struct {
vulnListDir string
appFs afero.Fs
retry int
client GithubClient
}
type GithubClient interface {
Query(ctx context.Context, q interface{}, variables map[string]interface{}) error
}
func NewConfig(client GithubClient) Config {
return Config{
vulnListDir: utils.VulnListDir(),
appFs: afero.NewOsFs(),
retry: retry,
client: client,
}
}
func (c Config) Update() error {
log.Print("Fetching GitHub Security Advisory")
for _, ecosystem := range Ecosystems {
err := c.update(ecosystem)
if err != nil {
return xerrors.Errorf("failed to update github security advisory ,%s: %w", ecosystem, err)
}
}
return nil
}
func (c Config) update(ecosystem SecurityAdvisoryEcosystem) error {
log.Printf("Fetching GitHub Security Advisory: %s", ecosystem)
dir := filepath.Join(c.vulnListDir, ghsaDir, strings.ToLower(string(ecosystem)))
if err := os.RemoveAll(dir); err != nil {
return xerrors.Errorf("unable to remove github security advisory directory: %w", err)
}
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
return xerrors.Errorf("failed to mkdir: %w", err)
}
ghsas, err := c.fetchGithubSecurityAdvisories(ecosystem)
if err != nil {
return xerrors.Errorf("failed to fetch github security advisory: %w", err)
}
ghsaJsonMap := make(map[string]GithubSecurityAdvisoryJson)
for _, ghsa := range ghsas {
ghsa.Package.Name = strings.TrimSpace(ghsa.Package.Name)
ghsaJson, ok := ghsaJsonMap[ghsa.Advisory.GhsaId+ghsa.Package.Name]
if ok {
va := Version{
FirstPatchedVersion: ghsa.FirstPatchedVersion,
VulnerableVersionRange: ghsa.VulnerableVersionRange,
}
ghsaJson.Versions = append(ghsaJson.Versions, va)
ghsaJsonMap[ghsa.Advisory.GhsaId+ghsa.Package.Name] = ghsaJson
} else {
ghsaJsonMap[ghsa.Advisory.GhsaId+ghsa.Package.Name] = GithubSecurityAdvisoryJson{
Severity: ghsa.Severity,
UpdatedAt: ghsa.UpdatedAt,
Package: ghsa.Package,
Advisory: ghsa.Advisory,
Versions: []Version{
{
FirstPatchedVersion: ghsa.FirstPatchedVersion,
VulnerableVersionRange: ghsa.VulnerableVersionRange,
},
},
}
}
}
bar := pb.StartNew(len(ghsaJsonMap))
for _, ghsaJson := range ghsaJsonMap {
dir := filepath.Join(c.vulnListDir, ghsaDir, strings.ToLower(string(ecosystem)), strings.Replace(ghsaJson.Package.Name, ":", "/", -1))
err := c.saveGSHA(dir, ghsaJson.Advisory.GhsaId, ghsaJson)
if err != nil {
return xerrors.Errorf("failed to save github security advisory: %w", err)
}
bar.Increment()
}
bar.Finish()
return nil
}
func (c Config) fetchGithubSecurityAdvisories(ecosystem SecurityAdvisoryEcosystem) ([]GithubSecurityAdvisory, error) {
var getVulnerabilitiesQuery GetVulnerabilitiesQuery
var ghsas []GithubSecurityAdvisory
variables := map[string]interface{}{
"ecosystem": ecosystem,
"total": graphql.Int(maxResponseSize),
"cursor": (*githubql.String)(nil),
}
for {
var err error
for i := 0; i <= c.retry; i++ {
if i > 0 {
sleep := wait(i)
log.Printf("retry after %s", sleep)
time.Sleep(sleep)
}
err = c.client.Query(context.Background(), &getVulnerabilitiesQuery, variables)
if err == nil {
break
}
}
if err != nil {
return nil, xerrors.Errorf("graphql api error: %w", err)
}
ghsas = append(ghsas, getVulnerabilitiesQuery.Nodes...)
if !getVulnerabilitiesQuery.PageInfo.HasNextPage {
break
}
variables["cursor"] = githubql.NewString(getVulnerabilitiesQuery.PageInfo.EndCursor)
}
return ghsas, nil
}
func (c Config) saveGSHA(dirName string, ghsaID string, data interface{}) error {
filePath := filepath.Join(dirName, fmt.Sprintf("%s.json", ghsaID))
if err := c.appFs.MkdirAll(dirName, os.ModePerm); err != nil {
return xerrors.Errorf("failed to create directory: %w", err)
}
fs := utils.NewFs(c.appFs)
if err := fs.WriteJSON(filePath, data); err != nil {
return xerrors.Errorf("failed to write file: %w", err)
}
return nil
}

451
ghsa/ghsa_test.go Normal file
View File

@ -0,0 +1,451 @@
package ghsa
import (
"context"
"errors"
"flag"
"fmt"
"io/ioutil"
"os"
"testing"
"time"
githubql "github.com/shurcooL/githubv4"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
var update = flag.Bool("update", false, "update golden files")
type MockClient struct {
Response map[githubql.String]GetVulnerabilitiesQuery
Error error
ErrorCount int
}
func (mc MockClient) Query(ctx context.Context, q interface{}, variables map[string]interface{}) error {
if mc.Error != nil {
return mc.Error
}
cursor := variables["cursor"].(*githubql.String)
if cursor == (*githubql.String)(nil) {
q.(*GetVulnerabilitiesQuery).SecurityVulnerabilities = mc.Response[githubql.String("")].SecurityVulnerabilities
return nil
}
q.(*GetVulnerabilitiesQuery).SecurityVulnerabilities = mc.Response[*cursor].SecurityVulnerabilities
return nil
}
func TestConfig_Update(t *testing.T) {
testCases := []struct {
name string
appFs afero.Fs
inputEcosystem SecurityAdvisoryEcosystem
goldenFiles map[string]string
inputResponse map[githubql.String]GetVulnerabilitiesQuery
expectedErrorMsg string
}{
{
name: "positive test",
appFs: afero.NewMemMapFs(),
inputEcosystem: Composer,
goldenFiles: map[string]string{
"/tmp/ghsa/composer/simplesamlphp/simplesamlphp/GHSA-2r3v-q9x3-7g46.json": "testdata/composer/simplesamlphp/simplesamlphp/GHSA-2r3v-q9x3-7g46.json",
},
inputResponse: map[githubql.String]GetVulnerabilitiesQuery{
githubql.String(""): {
SecurityVulnerabilities: SecurityVulnerabilities{
Nodes: []GithubSecurityAdvisory{
{
Severity: "LOW",
UpdatedAt: "2020-01-24T21:15:59Z",
Package: Package{
Ecosystem: "COMPOSER",
Name: "simplesamlphp/simplesamlphp",
},
Advisory: Advisory{
DatabaseId: 1883,
Id: "MDE2OlNlY3VyaXR5QWR2aXNvcnlHSFNBLTJyM3YtcTl4My03ZzQ2",
GhsaId: "GHSA-2r3v-q9x3-7g46",
References: []Reference{
{
Url: "https://github.com/simplesamlphp/simplesamlphp/security/advisories/GHSA-2r3v-q9x3-7g46",
},
},
Identifiers: []Identifier{
{
Type: "GHSA",
Value: "GHSA-2r3v-q9x3-7g46",
},
},
Description: "### Background\nSeveral scripts part of SimpleSAMLphp display a web page with links obtained from the request parameters. This allows us to enhance usability, as the users are presented with links they can follow after completing a certain action, like logging out.\n\n### Description\nThe following scripts were not checking the URLs obtained via the HTTP request before displaying them as the target of links that the user may click on:\n\n- `www/logout.php`\n- `modules/core/www/no_cookie.php`\n\nThe issue allowed attackers to display links targeting a malicious website inside a trusted site running SimpleSAMLphp, due to the lack of security checks involving the `link_href` and `retryURL` HTTP parameters, respectively. The issue was resolved by including a verification of the URLs received in the request against a white list of websites specified in the `trusted.url.domains` configuration option.\n\n### Affected versions\nAll SimpleSAMLphp versions prior to 1.14.4.\n\n### Impact\nA remote attacker could craft a link pointing to a trusted website running SimpleSAMLphp, including a parameter pointing to a malicious website, and try to fool the victim into visiting that website by clicking on a link in the page presented by SimpleSAMLphp.\n\n### Resolution\nUpgrade to the latest version.\n\n### Credit\nThis security issue was discovered and reported by John Page (hyp3rlinx).",
Origin: "UNSPECIFIED",
PublishedAt: "2020-01-24T21:27:16Z",
Severity: "LOW",
Summary: "Low severity vulnerability that affects simplesamlphp/simplesamlphp",
UpdatedAt: "2020-01-24T21:27:17Z",
WithdrawnAt: "",
},
FirstPatchedVersion: FirstPatchedVersion{
Identifier: "1.14.4",
},
VulnerableVersionRange: "\u003c 1.14.4",
},
},
PageInfo: PageInfo{
EndCursor: githubql.String(""),
HasNextPage: false,
},
},
},
},
},
{
name: "positive test multi nodes",
appFs: afero.NewMemMapFs(),
inputEcosystem: Maven,
goldenFiles: map[string]string{
"/tmp/ghsa/maven/org.apache.solr/solr-core/GHSA-2289-pqfq-6wx7.json": "testdata/maven/org.apache.solr/solr-core/GHSA-2289-pqfq-6wx7.json",
"/tmp/ghsa/maven/org.apache.qpid/qpid-broker/GHSA-269m-695x-j34p.json": "testdata/maven/org.apache.qpid/qpid-broker/GHSA-269m-695x-j34p.json",
"/tmp/ghsa/maven/org.apache.hive/hive/GHSA-2g9q-chq2-w8qw.json": "testdata/maven/org.apache.hive/hive/GHSA-2g9q-chq2-w8qw.json",
},
inputResponse: map[githubql.String]GetVulnerabilitiesQuery{
githubql.String(""): {
SecurityVulnerabilities: SecurityVulnerabilities{
Nodes: []GithubSecurityAdvisory{
{
Severity: "HIGH",
UpdatedAt: "2020-01-28T22:25:34Z",
Package: Package{
Ecosystem: "MAVEN",
Name: "org.apache.solr:solr-core",
},
Advisory: Advisory{
DatabaseId: 1892,
Id: "MDE2OlNlY3VyaXR5QWR2aXNvcnlHSFNBLTIyODktcHFmcS02d3g3",
GhsaId: "GHSA-2289-pqfq-6wx7",
References: []Reference{
{
Url: "https://nvd.nist.gov/vuln/detail/CVE-2019-12409",
},
},
Identifiers: []Identifier{
{
Type: "GHSA",
Value: "GHSA-2289-pqfq-6wx7",
},
{
Type: "CVE",
Value: "CVE-2019-12409",
},
},
Description: "The 8.1.1 and 8.2.0 releases of Apache Solr contain an insecure setting for the ENABLE_REMOTE_JMX_OPTS configuration option in the default solr.in.sh configuration file shipping with Solr. If you use the default solr.in.sh file from the affected releases, then JMX monitoring will be enabled and exposed on RMI_PORT (default=18983), without any authentication. If this port is opened for inbound traffic in your firewall, then anyone with network access to your Solr nodes will be able to access JMX, which may in turn allow them to upload malicious code for execution on the Solr server.",
Origin: "UNSPECIFIED",
PublishedAt: "2020-01-28T22:26:54Z",
Severity: "HIGH",
Summary: "High severity vulnerability that affects org.apache.solr:solr-core",
UpdatedAt: "2020-01-28T22:26:54Z",
WithdrawnAt: "",
},
FirstPatchedVersion: FirstPatchedVersion{
Identifier: "8.3.0",
},
VulnerableVersionRange: "\u003e= 8.1.1, \u003c= 8.2.0",
},
{
Severity: "MODERATE",
UpdatedAt: "2018-10-19T16:40:55Z",
Package: Package{
Ecosystem: "MAVEN",
Name: "org.apache.qpid:qpid-broker",
},
Advisory: Advisory{
DatabaseId: 888,
Id: "MDE2OlNlY3VyaXR5QWR2aXNvcnlHSFNBLTI2OW0tNjk1eC1qMzRw",
GhsaId: "GHSA-269m-695x-j34p",
References: []Reference{
{
Url: "https://nvd.nist.gov/vuln/detail/CVE-2017-15702",
},
},
Identifiers: []Identifier{
{
Type: "GHSA",
Value: "GHSA-269m-695x-j34p",
},
{
Type: "CVE",
Value: "CVE-2017-15702",
},
},
Description: "In Apache Qpid Broker-J 0.18 through 0.32, if the broker is configured with different authentication providers on different ports one of which is an HTTP port, then the broker can be tricked by a remote unauthenticated attacker connecting to the HTTP port into using an authentication provider that was configured on a different port. The attacker still needs valid credentials with the authentication provider on the spoofed port. This becomes an issue when the spoofed port has weaker authentication protection (e.g., anonymous access, default accounts) and is normally protected by firewall rules or similar which can be circumvented by this vulnerability. AMQP ports are not affected. Versions 6.0.0 and newer are not affected.",
Origin: "UNSPECIFIED",
PublishedAt: "2018-10-19T16:41:04Z",
Severity: "MODERATE",
Summary: "Moderate severity vulnerability that affects org.apache.qpid:qpid-broker",
UpdatedAt: "2019-07-03T21:02:04Z",
WithdrawnAt: "",
},
FirstPatchedVersion: FirstPatchedVersion{
Identifier: "6.0.0",
},
VulnerableVersionRange: "\u003e= 0.18, \u003c= 0.32",
},
},
PageInfo: PageInfo{
EndCursor: githubql.String("nextCursor"),
HasNextPage: true,
},
},
},
githubql.String("nextCursor"): {
SecurityVulnerabilities: SecurityVulnerabilities{
Nodes: []GithubSecurityAdvisory{
{
Severity: "MODERATE",
UpdatedAt: "2019-03-14T15:37:54Z",
Package: Package{
Ecosystem: "MAVEN",
Name: "org.apache.hive:hive",
},
Advisory: Advisory{
DatabaseId: 1293,
Id: "MDE2OlNlY3VyaXR5QWR2aXNvcnlHSFNBLTJnOXEtY2hxMi13OHF3",
GhsaId: "GHSA-2g9q-chq2-w8qw",
References: []Reference{
{
Url: "https://nvd.nist.gov/vuln/detail/CVE-2017-12625",
},
},
Identifiers: []Identifier{
{
Type: "GHSA",
Value: "GHSA-2g9q-chq2-w8qw",
},
{
Type: "CVE",
Value: "CVE-2017-12625",
},
},
Description: "Apache Hive 2.1.x before 2.1.2, 2.2.x before 2.2.1, and 2.3.x before 2.3.1 expose an interface through which masking policies can be defined on tables or views, e.g., using Apache Ranger. When a view is created over a given table, the policy enforcement does not happen correctly on the table for masked columns.",
Origin: "UNSPECIFIED",
PublishedAt: "2019-03-14T15:40:16Z",
Severity: "MODERATE",
Summary: "Moderate severity vulnerability that affects org.apache.hive:hive, org.apache.hive:hive-exec, and org.apache.hive:hive-service",
UpdatedAt: "2019-07-03T21:02:07Z",
WithdrawnAt: "",
},
FirstPatchedVersion: FirstPatchedVersion{
Identifier: "2.3.1",
},
VulnerableVersionRange: "= 2.3.0",
},
{
Severity: "MODERATE",
UpdatedAt: "2019-03-14T15:37:54Z",
Package: Package{
Ecosystem: "MAVEN",
Name: "org.apache.hive:hive",
},
Advisory: Advisory{
DatabaseId: 1293,
Id: "MDE2OlNlY3VyaXR5QWR2aXNvcnlHSFNBLTJnOXEtY2hxMi13OHF3",
GhsaId: "GHSA-2g9q-chq2-w8qw",
References: []Reference{
{
Url: "https://nvd.nist.gov/vuln/detail/CVE-2017-12625",
},
},
Identifiers: []Identifier{
{
Type: "GHSA",
Value: "GHSA-2g9q-chq2-w8qw",
},
{
Type: "CVE",
Value: "CVE-2017-12625",
},
},
Description: "Apache Hive 2.1.x before 2.1.2, 2.2.x before 2.2.1, and 2.3.x before 2.3.1 expose an interface through which masking policies can be defined on tables or views, e.g., using Apache Ranger. When a view is created over a given table, the policy enforcement does not happen correctly on the table for masked columns.",
Origin: "UNSPECIFIED",
PublishedAt: "2019-03-14T15:40:16Z",
Severity: "MODERATE",
Summary: "Moderate severity vulnerability that affects org.apache.hive:hive, org.apache.hive:hive-exec, and org.apache.hive:hive-service",
UpdatedAt: "2019-07-03T21:02:07Z",
WithdrawnAt: "",
},
FirstPatchedVersion: FirstPatchedVersion{
Identifier: "2.2.1",
},
VulnerableVersionRange: "= 2.2.0",
},
{
Severity: "MODERATE",
UpdatedAt: "2019-03-14T15:37:54Z",
Package: Package{
Ecosystem: "MAVEN",
Name: "org.apache.hive:hive",
},
Advisory: Advisory{
DatabaseId: 1293,
Id: "MDE2OlNlY3VyaXR5QWR2aXNvcnlHSFNBLTJnOXEtY2hxMi13OHF3",
GhsaId: "GHSA-2g9q-chq2-w8qw",
References: []Reference{
{
Url: "https://nvd.nist.gov/vuln/detail/CVE-2017-12625",
},
},
Identifiers: []Identifier{
{
Type: "GHSA",
Value: "GHSA-2g9q-chq2-w8qw",
},
{
Type: "CVE",
Value: "CVE-2017-12625",
},
},
Description: "Apache Hive 2.1.x before 2.1.2, 2.2.x before 2.2.1, and 2.3.x before 2.3.1 expose an interface through which masking policies can be defined on tables or views, e.g., using Apache Ranger. When a view is created over a given table, the policy enforcement does not happen correctly on the table for masked columns.",
Origin: "UNSPECIFIED",
PublishedAt: "2019-03-14T15:40:16Z",
Severity: "MODERATE",
Summary: "Moderate severity vulnerability that affects org.apache.hive:hive, org.apache.hive:hive-exec, and org.apache.hive:hive-service",
UpdatedAt: "2019-07-03T21:02:07Z",
WithdrawnAt: "",
},
FirstPatchedVersion: FirstPatchedVersion{
Identifier: "2.1.2",
},
VulnerableVersionRange: "\u003e= 2.1.0, \u003c 2.1.2",
},
},
PageInfo: PageInfo{
EndCursor: githubql.String(""),
HasNextPage: false,
},
},
},
},
expectedErrorMsg: "",
},
{
name: "read only filesystem test",
appFs: afero.NewReadOnlyFs(afero.NewOsFs()),
inputEcosystem: Composer,
goldenFiles: map[string]string{},
inputResponse: map[githubql.String]GetVulnerabilitiesQuery{
githubql.String(""): {
SecurityVulnerabilities: SecurityVulnerabilities{
Nodes: []GithubSecurityAdvisory{
{
Package: Package{
Ecosystem: "COMPOSER",
Name: "composer",
},
Advisory: Advisory{
DatabaseId: 1,
},
},
},
PageInfo: PageInfo{
EndCursor: githubql.String(""),
HasNextPage: false,
},
},
},
},
expectedErrorMsg: "failed to save github security advisory: failed to create directory: operation not permitted",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
client := MockClient{
Response: tc.inputResponse,
}
c := Config{
vulnListDir: "/tmp",
appFs: tc.appFs,
retry: 0,
client: client,
}
err := c.update(tc.inputEcosystem)
switch {
case tc.expectedErrorMsg != "":
require.NotNil(t, err, tc.name)
assert.Contains(t, err.Error(), tc.expectedErrorMsg, tc.name)
return
default:
assert.NoError(t, err, tc.name)
}
fileCount := 0
err = afero.Walk(c.appFs, "/", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
fileCount += 1
actual, err := afero.ReadFile(c.appFs, path)
assert.NoError(t, err, tc.name)
goldenPath, ok := tc.goldenFiles[path]
if !ok {
fmt.Println(path)
}
assert.True(t, ok, tc.name)
if *update {
err = ioutil.WriteFile(goldenPath, actual, 0666)
assert.NoError(t, err, tc.name)
}
expected, err := ioutil.ReadFile(goldenPath)
assert.NoError(t, err, tc.name)
assert.Equal(t, string(expected), string(actual), tc.name)
return nil
})
assert.Equal(t, len(tc.goldenFiles), fileCount, tc.name)
assert.NoError(t, err, tc.name)
})
}
}
func TestConfig_FetchGithubSecurityAdvisories(t *testing.T) {
testCases := []struct {
name string
retry int
}{
{
name: "retry test",
retry: 1,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
wait = func(i int) time.Duration { return 0 }
client := MockClient{
Error: errors.New("request error"),
}
c := Config{
vulnListDir: "/tmp",
appFs: afero.NewMemMapFs(),
retry: tc.retry,
client: client,
}
_, err := c.fetchGithubSecurityAdvisories(Pip)
assert.Error(t, err, tc.name)
})
}
}

View File

@ -0,0 +1,39 @@
{
"Severity": "LOW",
"UpdatedAt": "2020-01-24T21:15:59Z",
"Package": {
"Ecosystem": "COMPOSER",
"Name": "simplesamlphp/simplesamlphp"
},
"Advisory": {
"DatabaseId": 1883,
"Id": "MDE2OlNlY3VyaXR5QWR2aXNvcnlHSFNBLTJyM3YtcTl4My03ZzQ2",
"GhsaId": "GHSA-2r3v-q9x3-7g46",
"References": [
{
"Url": "https://github.com/simplesamlphp/simplesamlphp/security/advisories/GHSA-2r3v-q9x3-7g46"
}
],
"Identifiers": [
{
"Type": "GHSA",
"Value": "GHSA-2r3v-q9x3-7g46"
}
],
"Description": "### Background\nSeveral scripts part of SimpleSAMLphp display a web page with links obtained from the request parameters. This allows us to enhance usability, as the users are presented with links they can follow after completing a certain action, like logging out.\n\n### Description\nThe following scripts were not checking the URLs obtained via the HTTP request before displaying them as the target of links that the user may click on:\n\n- `www/logout.php`\n- `modules/core/www/no_cookie.php`\n\nThe issue allowed attackers to display links targeting a malicious website inside a trusted site running SimpleSAMLphp, due to the lack of security checks involving the `link_href` and `retryURL` HTTP parameters, respectively. The issue was resolved by including a verification of the URLs received in the request against a white list of websites specified in the `trusted.url.domains` configuration option.\n\n### Affected versions\nAll SimpleSAMLphp versions prior to 1.14.4.\n\n### Impact\nA remote attacker could craft a link pointing to a trusted website running SimpleSAMLphp, including a parameter pointing to a malicious website, and try to fool the victim into visiting that website by clicking on a link in the page presented by SimpleSAMLphp.\n\n### Resolution\nUpgrade to the latest version.\n\n### Credit\nThis security issue was discovered and reported by John Page (hyp3rlinx).",
"Origin": "UNSPECIFIED",
"PublishedAt": "2020-01-24T21:27:16Z",
"Severity": "LOW",
"Summary": "Low severity vulnerability that affects simplesamlphp/simplesamlphp",
"UpdatedAt": "2020-01-24T21:27:17Z",
"WithdrawnAt": ""
},
"Versions": [
{
"FirstPatchedVersion": {
"Identifier": "1.14.4"
},
"VulnerableVersionRange": "\u003c 1.14.4"
}
]
}

View File

@ -0,0 +1,55 @@
{
"Severity": "MODERATE",
"UpdatedAt": "2019-03-14T15:37:54Z",
"Package": {
"Ecosystem": "MAVEN",
"Name": "org.apache.hive:hive"
},
"Advisory": {
"DatabaseId": 1293,
"Id": "MDE2OlNlY3VyaXR5QWR2aXNvcnlHSFNBLTJnOXEtY2hxMi13OHF3",
"GhsaId": "GHSA-2g9q-chq2-w8qw",
"References": [
{
"Url": "https://nvd.nist.gov/vuln/detail/CVE-2017-12625"
}
],
"Identifiers": [
{
"Type": "GHSA",
"Value": "GHSA-2g9q-chq2-w8qw"
},
{
"Type": "CVE",
"Value": "CVE-2017-12625"
}
],
"Description": "Apache Hive 2.1.x before 2.1.2, 2.2.x before 2.2.1, and 2.3.x before 2.3.1 expose an interface through which masking policies can be defined on tables or views, e.g., using Apache Ranger. When a view is created over a given table, the policy enforcement does not happen correctly on the table for masked columns.",
"Origin": "UNSPECIFIED",
"PublishedAt": "2019-03-14T15:40:16Z",
"Severity": "MODERATE",
"Summary": "Moderate severity vulnerability that affects org.apache.hive:hive, org.apache.hive:hive-exec, and org.apache.hive:hive-service",
"UpdatedAt": "2019-07-03T21:02:07Z",
"WithdrawnAt": ""
},
"Versions": [
{
"FirstPatchedVersion": {
"Identifier": "2.3.1"
},
"VulnerableVersionRange": "= 2.3.0"
},
{
"FirstPatchedVersion": {
"Identifier": "2.2.1"
},
"VulnerableVersionRange": "= 2.2.0"
},
{
"FirstPatchedVersion": {
"Identifier": "2.1.2"
},
"VulnerableVersionRange": "\u003e= 2.1.0, \u003c 2.1.2"
}
]
}

View File

@ -0,0 +1,43 @@
{
"Severity": "MODERATE",
"UpdatedAt": "2018-10-19T16:40:55Z",
"Package": {
"Ecosystem": "MAVEN",
"Name": "org.apache.qpid:qpid-broker"
},
"Advisory": {
"DatabaseId": 888,
"Id": "MDE2OlNlY3VyaXR5QWR2aXNvcnlHSFNBLTI2OW0tNjk1eC1qMzRw",
"GhsaId": "GHSA-269m-695x-j34p",
"References": [
{
"Url": "https://nvd.nist.gov/vuln/detail/CVE-2017-15702"
}
],
"Identifiers": [
{
"Type": "GHSA",
"Value": "GHSA-269m-695x-j34p"
},
{
"Type": "CVE",
"Value": "CVE-2017-15702"
}
],
"Description": "In Apache Qpid Broker-J 0.18 through 0.32, if the broker is configured with different authentication providers on different ports one of which is an HTTP port, then the broker can be tricked by a remote unauthenticated attacker connecting to the HTTP port into using an authentication provider that was configured on a different port. The attacker still needs valid credentials with the authentication provider on the spoofed port. This becomes an issue when the spoofed port has weaker authentication protection (e.g., anonymous access, default accounts) and is normally protected by firewall rules or similar which can be circumvented by this vulnerability. AMQP ports are not affected. Versions 6.0.0 and newer are not affected.",
"Origin": "UNSPECIFIED",
"PublishedAt": "2018-10-19T16:41:04Z",
"Severity": "MODERATE",
"Summary": "Moderate severity vulnerability that affects org.apache.qpid:qpid-broker",
"UpdatedAt": "2019-07-03T21:02:04Z",
"WithdrawnAt": ""
},
"Versions": [
{
"FirstPatchedVersion": {
"Identifier": "6.0.0"
},
"VulnerableVersionRange": "\u003e= 0.18, \u003c= 0.32"
}
]
}

View File

@ -0,0 +1,43 @@
{
"Severity": "HIGH",
"UpdatedAt": "2020-01-28T22:25:34Z",
"Package": {
"Ecosystem": "MAVEN",
"Name": "org.apache.solr:solr-core"
},
"Advisory": {
"DatabaseId": 1892,
"Id": "MDE2OlNlY3VyaXR5QWR2aXNvcnlHSFNBLTIyODktcHFmcS02d3g3",
"GhsaId": "GHSA-2289-pqfq-6wx7",
"References": [
{
"Url": "https://nvd.nist.gov/vuln/detail/CVE-2019-12409"
}
],
"Identifiers": [
{
"Type": "GHSA",
"Value": "GHSA-2289-pqfq-6wx7"
},
{
"Type": "CVE",
"Value": "CVE-2019-12409"
}
],
"Description": "The 8.1.1 and 8.2.0 releases of Apache Solr contain an insecure setting for the ENABLE_REMOTE_JMX_OPTS configuration option in the default solr.in.sh configuration file shipping with Solr. If you use the default solr.in.sh file from the affected releases, then JMX monitoring will be enabled and exposed on RMI_PORT (default=18983), without any authentication. If this port is opened for inbound traffic in your firewall, then anyone with network access to your Solr nodes will be able to access JMX, which may in turn allow them to upload malicious code for execution on the Solr server.",
"Origin": "UNSPECIFIED",
"PublishedAt": "2020-01-28T22:26:54Z",
"Severity": "HIGH",
"Summary": "High severity vulnerability that affects org.apache.solr:solr-core",
"UpdatedAt": "2020-01-28T22:26:54Z",
"WithdrawnAt": ""
},
"Versions": [
{
"FirstPatchedVersion": {
"Identifier": "8.3.0"
},
"VulnerableVersionRange": "\u003e= 8.1.1, \u003c= 8.2.0"
}
]
}

75
ghsa/types.go Normal file
View File

@ -0,0 +1,75 @@
package ghsa
import githubql "github.com/shurcooL/githubv4"
type GetVulnerabilitiesQuery struct {
SecurityVulnerabilities `graphql:"securityVulnerabilities(ecosystem: $ecosystem, first: $total, after: $cursor)"`
}
type SecurityVulnerabilities struct {
Nodes []GithubSecurityAdvisory
PageInfo PageInfo
}
type PageInfo struct {
EndCursor githubql.String
HasNextPage bool
}
type GithubSecurityAdvisory struct {
Severity string
UpdatedAt string
Package Package
Advisory Advisory
FirstPatchedVersion FirstPatchedVersion
VulnerableVersionRange string
}
type GitHubClient struct {
ApiKey string
}
type Package struct {
Ecosystem string
Name string
}
type Advisory struct {
DatabaseId int
Id string
GhsaId string
References []Reference
Identifiers []Identifier
Description string
Origin string
PublishedAt string
Severity string
Summary string
UpdatedAt string
WithdrawnAt string
}
type Identifier struct {
Type string
Value string
}
type Reference struct {
Url string
}
type FirstPatchedVersion struct {
Identifier string
}
type Version struct {
FirstPatchedVersion FirstPatchedVersion
VulnerableVersionRange string
}
type GithubSecurityAdvisoryJson struct {
Severity string
UpdatedAt string
Package Package
Advisory Advisory
Versions []Version
}

3
go.mod
View File

@ -16,10 +16,13 @@ require (
github.com/mattn/go-runewidth v0.0.4 // indirect
github.com/parnurzeal/gorequest v0.2.16
github.com/pkg/errors v0.8.0 // indirect
github.com/shurcooL/githubv4 v0.0.0-20191127044304-8f68eb5628d0
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f
github.com/simplereach/timeutils v1.2.0 // indirect
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
github.com/spf13/afero v1.2.2
github.com/stretchr/testify v1.4.0
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/sys v0.0.0-20190412213103-97732733099d // indirect
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7
gopkg.in/VividCortex/ewma.v1 v1.1.1 // indirect

15
go.sum
View File

@ -1,3 +1,4 @@
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/araddon/dateparse v0.0.0-20190426192744-0d74ffceef83 h1:ukTLOeMC0aVxbJWVg6hOsVJ0VPIo8w++PbNsze/pqF8=
github.com/araddon/dateparse v0.0.0-20190426192744-0d74ffceef83/go.mod h1:SLqhdZcd+dF3TEVL2RMoob5bBP5R1P1qkox+HtCBgGI=
github.com/cheggaaa/pb v2.0.7+incompatible h1:gLKifR1UkZ/kLkda5gC0K6c8g+jU2sINPtBeOiNlMhU=
@ -10,6 +11,8 @@ github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f h1:AUj1VoZUfhP
github.com/elazarl/goproxy/ext v0.0.0-20190421051319-9d40249d3c2f/go.mod h1:gNh8nYJoAm43RfaxurUnxr+N1PwuFV3ZMl/efxlIlY8=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E=
@ -38,6 +41,10 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/shurcooL/githubv4 v0.0.0-20191127044304-8f68eb5628d0 h1:T9uus1QvcPgeLShS30YOnnzk3r9Vvygp45muhlrufgY=
github.com/shurcooL/githubv4 v0.0.0-20191127044304-8f68eb5628d0/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXkPI6mQ4o9DQ0+FKW41hTbunoXZCTqk=
github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg=
github.com/simplereach/timeutils v1.2.0 h1:btgOAlu9RW6de2r2qQiONhjgxdAG7BL6je0G6J/yPnA=
github.com/simplereach/timeutils v1.2.0/go.mod h1:VVbQDfN/FHRZa1LSqcwo4kNZ62OOyqLLGQKYB3pB0Q8=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
@ -52,8 +59,14 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
@ -63,6 +76,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/VividCortex/ewma.v1 v1.1.1 h1:tWHEKkKq802K/JT9RiqGCBU5fW3raAPnJGTE9ostZvg=
gopkg.in/VividCortex/ewma.v1 v1.1.1/go.mod h1:TekXuFipeiHWiAlO1+wSS23vTcyFau5u3rxXUSXj710=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

23
main.go
View File

@ -1,6 +1,7 @@
package main
import (
"context"
"flag"
"fmt"
"log"
@ -9,12 +10,15 @@ import (
"strings"
"time"
"github.com/aquasecurity/vuln-list-update/amazon"
githubql "github.com/shurcooL/githubv4"
"golang.org/x/oauth2"
"golang.org/x/xerrors"
"github.com/aquasecurity/vuln-list-update/alpine"
"github.com/aquasecurity/vuln-list-update/amazon"
susecvrf "github.com/aquasecurity/vuln-list-update/cvrf/suse"
"github.com/aquasecurity/vuln-list-update/debian"
"github.com/aquasecurity/vuln-list-update/ghsa"
"github.com/aquasecurity/vuln-list-update/git"
"github.com/aquasecurity/vuln-list-update/nvd"
debianoval "github.com/aquasecurity/vuln-list-update/oval/debian"
@ -24,8 +28,6 @@ import (
"github.com/aquasecurity/vuln-list-update/redhat"
"github.com/aquasecurity/vuln-list-update/ubuntu"
"github.com/aquasecurity/vuln-list-update/utils"
"golang.org/x/xerrors"
)
const (
@ -35,7 +37,7 @@ const (
)
var (
target = flag.String("target", "", "update target (nvd, alpine, redhat, redhat-oval, debian, debian-oval, ubuntu, amazon, oracle-oval, suse-cvrf, photon)")
target = flag.String("target", "", "update target (nvd, alpine, redhat, redhat-oval, debian, debian-oval, ubuntu, amazon, oracle-oval, suse-cvrf, photon, ghsa)")
years = flag.String("years", "", "update years (only redhat)")
)
@ -146,6 +148,17 @@ func run() error {
return xerrors.Errorf("error in Photon update: %w", err)
}
commitMsg = "Photon Security Advisories"
case "ghsa":
src := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: githubToken},
)
httpClient := oauth2.NewClient(context.Background(), src)
gc := ghsa.NewConfig(githubql.NewClient(httpClient))
if err := gc.Update(); err != nil {
return xerrors.Errorf("error in GitHub Security Advisory update: %w", err)
}
commitMsg = "GitHub Security Advisory"
default:
return xerrors.New("unknown target")
}

View File

@ -103,7 +103,7 @@ func TrimSpaceNewline(str string) string {
func FetchURL(url, apikey string, retry int) (res []byte, err error) {
for i := 0; i <= retry; i++ {
if i > 0 {
wait := math.Pow(float64(i), 2) + float64(randInt()%10)
wait := math.Pow(float64(i), 2) + float64(RandInt()%10)
log.Printf("retry after %f seconds\n", wait)
time.Sleep(time.Duration(time.Duration(wait) * time.Second))
}
@ -115,7 +115,7 @@ func FetchURL(url, apikey string, retry int) (res []byte, err error) {
return nil, xerrors.Errorf("failed to fetch URL: %w", err)
}
func randInt() int {
func RandInt() int {
seed, _ := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
return int(seed.Int64())
}