Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NVSHAS-8842 add support for new amazon linux versions #49

Merged
merged 1 commit into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 43 additions & 30 deletions updater/fetchers/amazon/amazon.go
Original file line number Diff line number Diff line change
Expand Up @@ -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},
}
)

Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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)

Expand Down Expand Up @@ -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 {
Expand All @@ -229,39 +230,51 @@ func parseAlasPage(name, body, plain string, pkgs []string, net updater.NetInter
}
plain = strings.ReplaceAll(plain, "<br />", " ")
plain = strings.ReplaceAll(plain, "&nbsp;", " ")

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
}
}
}

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)
}
114 changes: 114 additions & 0 deletions updater/fetchers/amazon/amazon_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package amazon

import (
"testing"

"github.com/k3a/html2text"
)

var htmlBody = `
<!doctype html>
<html>
<body class="Site">
<main class="Site-content">
<div class="container">
<nav class="navbar navbar-fixed-top navbar-inverse" style="background-color: #000000" id="bs-navbar">
<a style="font-size: 20px; color: #FF9900" class="navbar-brand" href="/"><b>Amazon Linux Security Center</b></a>
<ul class="nav navbar-nav navbar-right" style="color: #ff9900">
<li style="background-color: #333333;"> <a style="color: #FFFFFF" href="/index.html">Amazon Linux 1</a> </li><li style="background-color: #333333;"> <a style="color: #FFFFFF" href="/alas2.html">Amazon Linux 2</a> </li><li style="background-color: #FF9900;"> <a style="color: #000000" href="/alas2023.html">Amazon Linux 2023</a> </li><li style="background-color: #333333;"> <a style="color: #FFFFFF" href="/announcements.html">Announcements</a> </li><li style="background-color: #333333;"> <a style="color: #FFFFFF" href="/faqs.html">FAQs</a> </li>
</ul>
</nav>
</div>
<div style='min-height: 523px; margin-top:80px;' class='nine columns content-with-nav' role='main'>
<section>
<div class='title'>
<h1 id='ALAS2023-2023-368'>ALAS2023-2023-368</h1>
</div>
<div class='text'>
<hr class='mid-pad'>
<span class='alas-info'>
<b>Amazon Linux 2023 Security Advisory:</b> ALAS-2023-368
</span><br />
<span class='alas-info'><b>Advisory Release Date:</b> 2023-09-27 21:06 Pacific</span><br />
<span class='alas-info'><b>Advisory Updated Date:</b> 2023-10-03 20:50 Pacific</span><br />
<div id='severity' class='alas-info'>
<b>Severity:</b>
<span class='date'>
<span class='bulletin-type'>
<i class='fas fa-exclamation-triangle'></i>
</span>
</span>
Important<br />
</div>
<div id='references'>
<b>References:</b>
<a href='/cve/html/CVE-2023-38039.html' target='_blank' rel='noopener noreferrer'>CVE-2023-38039&nbsp;</a>
<br />
<a href="../../faqs.html">FAQs regarding Amazon Linux ALAS/CVE Severity</a>
</div>
<hr class='mid-pad'>
<div id='issue_overview'>
<b>Issue Overview:</b>
<p>HTTP headers eat all memory</p><p>NOTE: https://www.openwall.com/lists/oss-security/2023/09/13/1<br />NOTE: https://curl.se/docs/CVE-2023-38039.html<br />NOTE: Introduced by: https://github.com/curl/curl/commit/7c8c723682d524ac9580b9ca3b71419163cb5660 (curl-7_83_0)<br />NOTE: Experimental tag removed in: https://github.com/curl/curl/commit/4d94fac9f0d1dd02b8308291e4c47651142dc28b (curl-7_84_0)<br />NOTE: Fixed by: https://github.com/curl/curl/commit/3ee79c1674fd6f99e8efca52cd7510e08b766770 (curl-8_3_0) (CVE-2023-38039)</p>
</div>
<div id='affected_packages' class='alas-info'>
<br />
<b>Affected Packages:</b>
<br />
<p>curl</p>
</div>
<div id='issue_correction'>
<br />
<b>Issue Correction:</b>
<br />Run <i>dnf update curl --releasever 2023.2.20231002</i> to update your system.<br /></div>
<br />
<div id='new_packages'>
<b>New Packages:</b><pre>aarch64:<br />&nbsp;&nbsp;&nbsp; libcurl-debuginfo-8.3.0-1.amzn2023.0.1.aarch64<br />&nbsp;&nbsp;&nbsp; java-1.8.0-amazon-corretto-1.8.0_402.b08-1.amzn2023.aarch64<br />&nbsp;&nbsp;&nbsp; libcurl-minimal-debuginfo-8.3.0-1.amzn2023.0.1.aarch64<br />&nbsp;&nbsp;&nbsp; curl-8.3.0-1.amzn2023.0.1.aarch64<br />&nbsp;&nbsp;&nbsp; curl-minimal-8.3.0-1.amzn2023.0.1.aarch64<br />&nbsp;&nbsp;&nbsp; curl-debuginfo-8.3.0-1.amzn2023.0.1.aarch64<br />&nbsp;&nbsp;&nbsp; curl-minimal-debuginfo-8.3.0-1.amzn2023.0.1.aarch64<br />&nbsp;&nbsp;&nbsp; curl-debugsource-8.3.0-1.amzn2023.0.1.aarch64<br />&nbsp;&nbsp;&nbsp; libcurl-minimal-8.3.0-1.amzn2023.0.1.aarch64<br />&nbsp;&nbsp;&nbsp; libcurl-8.3.0-1.amzn2023.0.1.aarch64<br />&nbsp;&nbsp;&nbsp; libcurl-devel-8.3.0-1.amzn2023.0.1.aarch64<br /><br />src:<br />&nbsp;&nbsp;&nbsp; curl-8.3.0-1.amzn2023.0.1.src<br /><br />x86_64:<br />&nbsp;&nbsp;&nbsp; curl-minimal-debuginfo-8.3.0-1.amzn2023.0.1.x86_64<br />&nbsp;&nbsp;&nbsp; curl-debuginfo-8.3.0-1.amzn2023.0.1.x86_64<br />&nbsp;&nbsp;&nbsp; libcurl-minimal-8.3.0-1.amzn2023.0.1.x86_64<br />&nbsp;&nbsp;&nbsp; curl-minimal-8.3.0-1.amzn2023.0.1.x86_64<br />&nbsp;&nbsp;&nbsp; curl-debugsource-8.3.0-1.amzn2023.0.1.x86_64<br />&nbsp;&nbsp;&nbsp; libcurl-debuginfo-8.3.0-1.amzn2023.0.1.x86_64<br />&nbsp;&nbsp;&nbsp; curl-8.3.0-1.amzn2023.0.1.x86_64<br />&nbsp;&nbsp;&nbsp; libcurl-minimal-debuginfo-8.3.0-1.amzn2023.0.1.x86_64<br />&nbsp;&nbsp;&nbsp; libcurl-8.3.0-1.amzn2023.0.1.x86_64<br />&nbsp;&nbsp;&nbsp; libcurl-devel-8.3.0-1.amzn2023.0.1.x86_64<br />&nbsp;&nbsp;&nbsp; kernel-debuginfo-common-i686-4.14.336-180.562.amzn1.i686<br /></pre></div>
</div>
</html>`

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)
}
}
}
Loading