diff --git a/updater/fetchers/amazon/amazon.go b/updater/fetchers/amazon/amazon.go
index e2c6dac..d8f7050 100644
--- a/updater/fetchers/amazon/amazon.go
+++ b/updater/fetchers/amazon/amazon.go
@@ -34,7 +34,7 @@ var (
ovals []ovalInfo = []ovalInfo{
ovalInfo{"amazon/alas.rss.gz", "Amazon Linux", 1},
ovalInfo{"amazon/alas2.rss.gz", "Amazon Linux 2", 2},
- // ovalInfo{"amazon/alas2022.rss.gz", "Amazon Linux 2022"},
+ ovalInfo{"amazon/alas2023.rss.gz", "Amazon Linux 2023", 2023},
}
)
@@ -141,7 +141,7 @@ func (u *AmazonFetcher) fetchOvalFeed(o *ovalInfo, net updater.NetInterface) ([]
Link: item.Link,
}
- switch tokens[1] {
+ switch strings.ToLower(tokens[1]) {
case "(critical):":
vuln.FeedRating = "Critical"
vuln.Severity = common.Critical
@@ -157,9 +157,15 @@ func (u *AmazonFetcher) fetchOvalFeed(o *ovalInfo, net updater.NetInterface) ([]
cves := strings.Split(item.CVEs, " ")
vuln.CVEs = make([]common.CVE, len(cves))
- for i, cve := range cves {
- vuln.CVEs[i].Name = strings.TrimRight(cve, ",")
+ count := 0
+ for _, cve := range cves {
+ name := strings.TrimRight(cve, ",\n ")
+ if name != "" {
+ vuln.CVEs[count].Name = name
+ count++
+ }
}
+ vuln.CVEs = vuln.CVEs[:count]
vuln.IssuedDate, _ = time.Parse(time.RFC1123, item.Issued)
vuln.LastModDate, _ = time.Parse(time.RFC1123, item.LastMod)
@@ -170,15 +176,10 @@ func (u *AmazonFetcher) fetchOvalFeed(o *ovalInfo, net updater.NetInterface) ([]
vuln.LastModDate = vuln.IssuedDate
}
- pkgs := make([]string, len(tokens)-2)
- for i, token := range tokens[2:] {
- pkgs[i] = strings.TrimRight(token, ",")
- }
-
- if desc, vers, err := getAlas(vuln.Name, vuln.Link, pkgs, net); err != nil {
+ if desc, vers, err := getAlas(vuln.Name, vuln.Link, net); err != nil {
log.WithFields(log.Fields{"cve": vuln.Name, "error": err}).Warn("Failed to parse amazon CVE page")
} else if len(vers) == 0 {
- log.WithFields(log.Fields{"cve": vuln.Name, "pkgs": pkgs}).Warn("Failed to parse amazon CVE page, no package version")
+ log.WithFields(log.Fields{"cve": vuln.Name}).Warn("Failed to parse amazon CVE page, no package versions")
} else {
vuln.Description = strings.TrimSpace(desc)
@@ -211,7 +212,7 @@ func (u *AmazonFetcher) fetchOvalFeed(o *ovalInfo, net updater.NetInterface) ([]
func (u *AmazonFetcher) Clean() {
}
-func parseAlasPage(name, body, plain string, pkgs []string, net updater.NetInterface) (string, map[string]string, error) {
+func parseAlasPage(name, body, plain string) (string, map[string]string, error) {
var description string
if a := strings.Index(plain, "Issue Overview:"); a > 0 {
if b := strings.Index(plain, "Affected Packages:"); b > 0 {
@@ -229,27 +230,39 @@ func parseAlasPage(name, body, plain string, pkgs []string, net updater.NetInter
}
plain = strings.ReplaceAll(plain, "
", " ")
plain = strings.ReplaceAll(plain, " ", " ")
-
strs := strings.Split(plain, " ")
- var arch string
+
for _, str := range strs {
str = strings.TrimSpace(str)
- if strings.HasSuffix(str, ":") {
- arch = fmt.Sprintf(".%s", str[:len(str)-1])
- } else if arch != "" {
- if s := strings.Index(str, arch); s > 0 {
- for _, pkg := range pkgs {
- if strings.HasPrefix(str, pkg) {
- version := str[len(pkg)+1 : s]
- if verRegexp.MatchString(version) {
- pkgVers[pkg] = version
- }
- }
- }
- if len(pkgVers) == len(pkgs) {
- return description, pkgVers, nil
+ pkgName := ""
+ if strings.HasSuffix(str, ":") || str == "" {
+ //arch = fmt.Sprintf(".%s", str[:len(str)-1])
+ //skip arch line
+ continue
+ } else {
+ //Find name by locating beginning of version
+ versionStart := regexp.MustCompile(`[a-z+]-[0-9]`)
+ alternateVersionStart := regexp.MustCompile(`[0-9]-[0-9]`)
+ lastDotIndex := strings.LastIndex(str, ".")
+ versionStartIndex := versionStart.FindAllStringIndex(str, -1)
+ if versionStartIndex == nil {
+ versionStartIndex = alternateVersionStart.FindAllStringIndex(str, -1)
+ if versionStartIndex == nil {
+ log.WithFields(log.Fields{"name": name, "str": str}).Warning("Failed to find version start index for ALAS page")
+ continue
}
+ //use first match rather than last for this case
+ pkgName = str[:versionStartIndex[0][0]+1]
+ version := str[versionStartIndex[0][0]+2 : lastDotIndex]
+ pkgVers[pkgName] = version
+ continue
}
+ pkgName = str[:versionStartIndex[len(versionStartIndex)-1][0]+1]
+ //Find version by taking characters between start of version and last "."
+ version := str[versionStartIndex[len(versionStartIndex)-1][0]+2 : lastDotIndex]
+ //arch := str[lastDotIndex:]
+
+ pkgVers[pkgName] = version
}
}
}
@@ -257,11 +270,11 @@ func parseAlasPage(name, body, plain string, pkgs []string, net updater.NetInter
return description, pkgVers, nil
}
-func getAlas(name, link string, pkgs []string, net updater.NetInterface) (string, map[string]string, error) {
+func getAlas(name, link string, net updater.NetInterface) (string, map[string]string, error) {
body, plain, err := net.DownloadHTMLPage(link)
if err != nil {
return "", nil, err
}
- return parseAlasPage(name, body, plain, pkgs, net)
+ return parseAlasPage(name, body, plain)
}
diff --git a/updater/fetchers/amazon/amazon_test.go b/updater/fetchers/amazon/amazon_test.go
new file mode 100644
index 0000000..e716dd4
--- /dev/null
+++ b/updater/fetchers/amazon/amazon_test.go
@@ -0,0 +1,114 @@
+package amazon
+
+import (
+ "testing"
+
+ "github.com/k3a/html2text"
+)
+
+var htmlBody = `
+
+
+
+
+
+
+
+
+
ALAS2023-2023-368
+
+
+
+
+
+ Amazon Linux 2023 Security Advisory: ALAS-2023-368
+
+
Advisory Release Date: 2023-09-27 21:06 Pacific
+
Advisory Updated Date: 2023-10-03 20:50 Pacific
+
+
+ Severity:
+
+
+
+
+
+ Important
+
+
+
+
+
+
+
Issue Overview:
+
HTTP headers eat all memory
NOTE: https://www.openwall.com/lists/oss-security/2023/09/13/1
NOTE: https://curl.se/docs/CVE-2023-38039.html
NOTE: Introduced by: https://github.com/curl/curl/commit/7c8c723682d524ac9580b9ca3b71419163cb5660 (curl-7_83_0)
NOTE: Experimental tag removed in: https://github.com/curl/curl/commit/4d94fac9f0d1dd02b8308291e4c47651142dc28b (curl-7_84_0)
NOTE: Fixed by: https://github.com/curl/curl/commit/3ee79c1674fd6f99e8efca52cd7510e08b766770 (curl-8_3_0) (CVE-2023-38039)
+
+
+
+
+
Affected Packages:
+
+
curl
+
+
+
+
+
+ Issue Correction:
+
Run dnf update curl --releasever 2023.2.20231002 to update your system.
+
+
+
New Packages:aarch64:
libcurl-debuginfo-8.3.0-1.amzn2023.0.1.aarch64
java-1.8.0-amazon-corretto-1.8.0_402.b08-1.amzn2023.aarch64
libcurl-minimal-debuginfo-8.3.0-1.amzn2023.0.1.aarch64
curl-8.3.0-1.amzn2023.0.1.aarch64
curl-minimal-8.3.0-1.amzn2023.0.1.aarch64
curl-debuginfo-8.3.0-1.amzn2023.0.1.aarch64
curl-minimal-debuginfo-8.3.0-1.amzn2023.0.1.aarch64
curl-debugsource-8.3.0-1.amzn2023.0.1.aarch64
libcurl-minimal-8.3.0-1.amzn2023.0.1.aarch64
libcurl-8.3.0-1.amzn2023.0.1.aarch64
libcurl-devel-8.3.0-1.amzn2023.0.1.aarch64
src:
curl-8.3.0-1.amzn2023.0.1.src
x86_64:
curl-minimal-debuginfo-8.3.0-1.amzn2023.0.1.x86_64
curl-debuginfo-8.3.0-1.amzn2023.0.1.x86_64
libcurl-minimal-8.3.0-1.amzn2023.0.1.x86_64
curl-minimal-8.3.0-1.amzn2023.0.1.x86_64
curl-debugsource-8.3.0-1.amzn2023.0.1.x86_64
libcurl-debuginfo-8.3.0-1.amzn2023.0.1.x86_64
curl-8.3.0-1.amzn2023.0.1.x86_64
libcurl-minimal-debuginfo-8.3.0-1.amzn2023.0.1.x86_64
libcurl-8.3.0-1.amzn2023.0.1.x86_64
libcurl-devel-8.3.0-1.amzn2023.0.1.x86_64
kernel-debuginfo-common-i686-4.14.336-180.562.amzn1.i686
+
+`
+
+func TestParseAlasPage(t *testing.T) {
+ expectedLen := 12
+ expectedVersions := map[string]string{
+ "libcurl-debuginfo": "8.3.0-1.amzn2023.0.1",
+ "java-1.8.0-amazon-corretto": "1.8.0_402.b08-1.amzn2023",
+ "libcurl-minimal-debuginfo": "8.3.0-1.amzn2023.0.1",
+ "curl": "8.3.0-1.amzn2023.0.1",
+ "curl-minimal": "8.3.0-1.amzn2023.0.1",
+ "curl-debuginfo": "8.3.0-1.amzn2023.0.1",
+ "curl-minimal-debuginfo": "8.3.0-1.amzn2023.0.1",
+ "curl-debugsource": "8.3.0-1.amzn2023.0.1",
+ "libcurl-minimal": "8.3.0-1.amzn2023.0.1",
+ "libcurl": "8.3.0-1.amzn2023.0.1",
+ "libcurl-devel": "8.3.0-1.amzn2023.0.1",
+ "kernel-debuginfo-common-i686": "4.14.336-180.562.amzn1",
+ }
+ plain := html2text.HTML2Text(string(htmlBody))
+ _, vers, err := parseAlasPage("ALAS-2023-368", htmlBody, plain)
+ if err != nil {
+ t.Errorf("Error during parseAlasPage:%v\n", err)
+ }
+
+ //check length of version map
+ if len(vers) != expectedLen {
+ t.Errorf("Expected length of parseAlasPage:%v , returned length:%v\n", expectedLen, len(vers))
+ }
+ //Check contents of version map
+ for key, value := range expectedVersions {
+ val, ok := vers[key]
+ if ok {
+ if val != value {
+ t.Errorf("parseAlasPage vers key:%s, value:%s, does not match expected value:%s,\n", key, val, value)
+ }
+ } else {
+ t.Errorf("Missing key in vers from parseAlasPage:%s\n", key)
+ }
+ }
+}