index,vul_code,is_vulnerable,programming_language,method_name,file_name,repo_url,repo_owner,committer,committer_date,commit_msg,cwe_id,cwe_name,cwe_description,cwe_url,cve_id,patch 1,"private HandshakeMessage createServerHandshakeMessage( HandshakeType type, byte[] buffer) { ClientContext context = (ClientContext)this.context; switch (type) { case HandshakeType.HelloRequest: if (context.HandshakeState != HandshakeState.Started) { context.HandshakeState = HandshakeState.None; } else { this.SendAlert( AlertLevel.Warning, AlertDescription.NoRenegotiation); } return null; case HandshakeType.ServerHello: return new TlsServerHello(this.context, buffer); case HandshakeType.Certificate: return new TlsServerCertificate(this.context, buffer); case HandshakeType.ServerKeyExchange: return new TlsServerKeyExchange(this.context, buffer); case HandshakeType.CertificateRequest: return new TlsServerCertificateRequest(this.context, buffer); case HandshakeType.ServerHelloDone: return new TlsServerHelloDone(this.context, buffer); case HandshakeType.Finished: return new TlsServerFinished(this.context, buffer); default: throw new TlsException( AlertDescription.UnexpectedMessage, String.Format(CultureInfo.CurrentUICulture, ""Unknown server handshake message received ({0})"", type.ToString())); } }",True,Go,Mono.Security.Protocol.Tls::ClientRecordProtocol::createServerHandshakeMessage,ClientRecordProtocol.cs,https://github.com/mono/mono,mono,Miguel de Icaza,2015-03-06 10:34:14-05:00,TLS protocol: add handshake state validation,CWE-295,Improper Certificate Validation,"The product does not validate, or incorrectly validates, a certificate.",https://cwe.mitre.org/data/definitions/295.html,CVE-2015-2318,"private HandshakeMessage createServerHandshakeMessage( HandshakeType type, byte[] buffer) { ClientContext context = (ClientContext)this.context; var last = context.LastHandshakeMsg; switch (type) { case HandshakeType.HelloRequest: if (context.HandshakeState != HandshakeState.Started) { context.HandshakeState = HandshakeState.None; } else { this.SendAlert( AlertLevel.Warning, AlertDescription.NoRenegotiation); } return null; case HandshakeType.ServerHello: if (last != HandshakeType.HelloRequest) break; return new TlsServerHello(this.context, buffer); case HandshakeType.Certificate: if (last != HandshakeType.ServerHello) break; return new TlsServerCertificate(this.context, buffer); case HandshakeType.ServerKeyExchange: if (last == HandshakeType.Certificate && context.Current.Cipher.IsExportable) return new TlsServerKeyExchange(this.context, buffer); break; case HandshakeType.CertificateRequest: if (last == HandshakeType.ServerKeyExchange || last == HandshakeType.Certificate) return new TlsServerCertificateRequest(this.context, buffer); break; case HandshakeType.ServerHelloDone: if (last == HandshakeType.CertificateRequest || last == HandshakeType.Certificate || last == HandshakeType.ServerHello) return new TlsServerHelloDone(this.context, buffer); break; case HandshakeType.Finished: bool check = context.AbbreviatedHandshake ? (last == HandshakeType.ServerHello) : (last == HandshakeType.ServerHelloDone); if (check && context.ChangeCipherSpecDone) { context.ChangeCipherSpecDone = false; return new TlsServerFinished (this.context, buffer); } break; default: throw new TlsException( AlertDescription.UnexpectedMessage, String.Format(CultureInfo.CurrentUICulture, ""Unknown server handshake message received ({0})"", type.ToString())); } throw new TlsException (AlertDescription.HandshakeFailiure, String.Format (""Protocol error, unexpected protocol transition from {0} to {1}"", last, type)); }" 2,"private HandshakeMessage createClientHandshakeMessage( HandshakeType type, byte[] buffer) { switch (type) { case HandshakeType.ClientHello: return new TlsClientHello(this.context, buffer); case HandshakeType.Certificate: return new TlsClientCertificate(this.context, buffer); case HandshakeType.ClientKeyExchange: return new TlsClientKeyExchange(this.context, buffer); case HandshakeType.CertificateVerify: return new TlsClientCertificateVerify(this.context, buffer); case HandshakeType.Finished: return new TlsClientFinished(this.context, buffer); default: throw new TlsException( AlertDescription.UnexpectedMessage, String.Format(CultureInfo.CurrentUICulture, ""Unknown server handshake message received ({0})"", type.ToString())); } }",True,Go,Mono.Security.Protocol.Tls::ServerRecordProtocol::createClientHandshakeMessage,ServerRecordProtocol.cs,https://github.com/mono/mono,mono,Miguel de Icaza,2015-03-06 10:34:14-05:00,TLS protocol: add handshake state validation,CWE-295,Improper Certificate Validation,"The product does not validate, or incorrectly validates, a certificate.",https://cwe.mitre.org/data/definitions/295.html,CVE-2015-2318,"private HandshakeMessage createClientHandshakeMessage( HandshakeType type, byte[] buffer) { var last = context.LastHandshakeMsg; switch (type) { case HandshakeType.ClientHello: return new TlsClientHello(this.context, buffer); case HandshakeType.Certificate: if (last != HandshakeType.ClientHello) break; cert = new TlsClientCertificate(this.context, buffer); return cert; case HandshakeType.ClientKeyExchange: if (last == HandshakeType.ClientHello || last == HandshakeType.Certificate) return new TlsClientKeyExchange(this.context, buffer); break; case HandshakeType.CertificateVerify: if (last == HandshakeType.ClientKeyExchange && cert != null) return new TlsClientCertificateVerify(this.context, buffer); break; case HandshakeType.Finished: bool check = (cert == null) ? (last == HandshakeType.ClientKeyExchange) : (last == HandshakeType.CertificateVerify); if (check && context.ChangeCipherSpecDone) { context.ChangeCipherSpecDone = false; return new TlsClientFinished(this.context, buffer); } break; default: throw new TlsException(AlertDescription.UnexpectedMessage, String.Format(CultureInfo.CurrentUICulture, ""Unknown server handshake message received ({0})"", type.ToString())); break; } throw new TlsException (AlertDescription.HandshakeFailiure, String.Format (""Protocol error, unexpected protocol transition from {0} to {1}"", last, type)); }" 8,"private HandshakeMessage createServerHandshakeMessage( HandshakeType type, byte[] buffer) { ClientContext context = (ClientContext)this.context; var last = context.LastHandshakeMsg; switch (type) { case HandshakeType.HelloRequest: if (context.HandshakeState != HandshakeState.Started) { context.HandshakeState = HandshakeState.None; } else { this.SendAlert( AlertLevel.Warning, AlertDescription.NoRenegotiation); } return null; case HandshakeType.ServerHello: if (last != HandshakeType.HelloRequest) break; return new TlsServerHello(this.context, buffer); case HandshakeType.Certificate: if (last != HandshakeType.ServerHello) break; return new TlsServerCertificate(this.context, buffer); case HandshakeType.ServerKeyExchange: if (last == HandshakeType.Certificate && context.Current.Cipher.IsExportable) return new TlsServerKeyExchange(this.context, buffer); break; case HandshakeType.CertificateRequest: if (last == HandshakeType.ServerKeyExchange || last == HandshakeType.Certificate) return new TlsServerCertificateRequest(this.context, buffer); break; case HandshakeType.ServerHelloDone: if (last == HandshakeType.CertificateRequest || last == HandshakeType.Certificate || last == HandshakeType.ServerHello) return new TlsServerHelloDone(this.context, buffer); break; case HandshakeType.Finished: bool check = context.AbbreviatedHandshake ? (last == HandshakeType.ServerHello) : (last == HandshakeType.ServerHelloDone); if (check && context.ChangeCipherSpecDone) { context.ChangeCipherSpecDone = false; return new TlsServerFinished (this.context, buffer); } break; default: throw new TlsException( AlertDescription.UnexpectedMessage, String.Format(CultureInfo.CurrentUICulture, ""Unknown server handshake message received ({0})"", type.ToString())); } throw new TlsException (AlertDescription.HandshakeFailiure, String.Format (""Protocol error, unexpected protocol transition from {0} to {1}"", last, type)); }",True,Go,Mono.Security.Protocol.Tls::ClientRecordProtocol::createServerHandshakeMessage,ClientRecordProtocol.cs,https://github.com/mono/mono,mono,Miguel de Icaza,2015-03-06 10:35:27-05:00,"Remove the EXPORT ciphers and related code path That was still useful in 2003/2004 but the technical and legal landscape changed a lot since then. Removing the old, limited key size, cipher suites also allow removed additional parts of the code that deals with them.",CWE-295,Improper Certificate Validation,"The product does not validate, or incorrectly validates, a certificate.",https://cwe.mitre.org/data/definitions/295.html,CVE-2015-2319,"func canonicalMIMEHeaderKey(a []byte) string { for _, c := range a { if validHeaderFieldByte(c) { continue } return string(a) } upper := true for i, c := range a { if upper && 'a' <= c && c <= 'z' { c -= toLower } else if !upper && 'A' <= c && c <= 'Z' { c += toLower } a[i] = c upper = c == '-' } if v := commonHeader[string(a)]; v != """" { return v } return string(a) }" 11,"func canonicalMIMEHeaderKey(a []byte) string { upper := true for i, c := range a { if c == ' ' { c = '-' } else if upper && 'a' <= c && c <= 'z' { c -= toLower } else if !upper && 'A' <= c && c <= 'Z' { c += toLower } a[i] = c upper = c == '-' } if v := commonHeader[string(a)]; v != """" { return v } return string(a) }",True,Go,canonicalMIMEHeaderKey,reader.go,https://github.com/golang/go,golang,Brad Fitzpatrick,2015-06-30 17:59:02+00:00,"net/textproto: don't treat spaces as hyphens in header keys This was originally done in https://codereview.appspot.com/5690059 (Feb 2012) to deal with bad response headers coming back from webcams, but it presents a potential security problem with HTTP request smuggling for request headers containing ""Content Length"" instead of ""Content-Length"". Part of overall HTTP hardening for request smuggling. See RFC 7230. Thanks to Régis Leroy for the report. Change-Id: I92b17fb637c9171c5774ea1437979ae2c17ca88a Reviewed-on: https://go-review.googlesource.com/11772 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot ",CWE-444,Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling'),"The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.",https://cwe.mitre.org/data/definitions/444.html,CVE-2015-5739,"func TestReadMIMEHeaderNonCompliant(t *testing.T) { r := reader(""Foo: bar\r\n"" + ""Content-Language: en\r\n"" + ""SID : 0\r\n"" + ""Audio Mode : None\r\n"" + ""Privilege : 127\r\n\r\n"") m, err := r.ReadMIMEHeader() want := MIMEHeader{ ""Foo"": {""bar""}, ""Content-Language"": {""en""}, ""Sid"": {""0""}, ""Audio Mode"": {""None""}, ""Privilege"": {""127""}, } if !reflect.DeepEqual(m, want) || err != nil { t.Fatalf(""ReadMIMEHeader =\n%v, %v; want:\n%v"", m, err, want) } }" 15,"func TestReadMIMEHeaderNonCompliant(t *testing.T) { r := reader(""Foo: bar\r\n"" + ""Content-Language: en\r\n"" + ""SID : 0\r\n"" + ""Audio Mode : None\r\n"" + ""Privilege : 127\r\n\r\n"") m, err := r.ReadMIMEHeader() want := MIMEHeader{ ""Foo"": {""bar""}, ""Content-Language"": {""en""}, ""Sid"": {""0""}, ""Audio-Mode"": {""None""}, ""Privilege"": {""127""}, } if !reflect.DeepEqual(m, want) || err != nil { t.Fatalf(""ReadMIMEHeader =\n%v, %v; want:\n%v"", m, err, want) } }",True,Go,TestReadMIMEHeaderNonCompliant,reader_test.go,https://github.com/golang/go,golang,Brad Fitzpatrick,2015-06-30 17:59:02+00:00,"net/textproto: don't treat spaces as hyphens in header keys This was originally done in https://codereview.appspot.com/5690059 (Feb 2012) to deal with bad response headers coming back from webcams, but it presents a potential security problem with HTTP request smuggling for request headers containing ""Content Length"" instead of ""Content-Length"". Part of overall HTTP hardening for request smuggling. See RFC 7230. Thanks to Régis Leroy for the report. Change-Id: I92b17fb637c9171c5774ea1437979ae2c17ca88a Reviewed-on: https://go-review.googlesource.com/11772 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot ",CWE-444,Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling'),"The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.",https://cwe.mitre.org/data/definitions/444.html,CVE-2015-5739,"func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) { contentLens := header[""Content-Length""] isRequest := !isResponse if noBodyExpected(requestMethod) { if isRequest && len(contentLens) > 0 && !(len(contentLens) == 1 && contentLens[0] == ""0"") { return 0, fmt.Errorf(""http: method cannot contain a Content-Length; got %q"", contentLens) } return 0, nil } if status/100 == 1 { return 0, nil } switch status { case 204, 304: return 0, nil } if len(contentLens) > 1 { return 0, errors.New(""http: message cannot contain multiple Content-Length headers"") } if chunked(te) { return -1, nil } var cl string if len(contentLens) == 1 { cl = strings.TrimSpace(contentLens[0]) } if cl != """" { n, err := parseContentLength(cl) if err != nil { return -1, err } return n, nil } else { header.Del(""Content-Length"") } if !isResponse { return 0, nil } return -1, nil }" 19,"func TestReadRequest_BadConnectHost(t *testing.T) { data := []byte(""CONNECT []%20%48%54%54%50%2f%31%2e%31%0a%4d%79%48%65%61%64%65%72%3a%20%31%32%33%0a%0a HTTP/1.0\n\n"") r, err := ReadRequest(bufio.NewReader(bytes.NewReader(data))) if err == nil { t.Fatal(""Got unexpected request = %#v"", r) } }",True,Go,TestReadRequest_BadConnectHost,readrequest_test.go,https://github.com/golang/go,golang,Brad Fitzpatrick,2015-06-30 22:56:30+00:00,"net/http: harden Server against request smuggling See RFC 7230. Thanks to Régis Leroy for the report. Change-Id: Ic1779bc2180900430d4d7a4938cac04ed73c304c Reviewed-on: https://go-review.googlesource.com/11810 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick ",CWE-444,Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling'),"The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.",https://cwe.mitre.org/data/definitions/444.html,CVE-2015-5740,"func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) { contentLens := header[""Content-Length""] isRequest := !isResponse if noBodyExpected(requestMethod) { if isRequest && len(contentLens) > 0 && !(len(contentLens) == 1 && contentLens[0] == ""0"") { return 0, fmt.Errorf(""http: method cannot contain a Content-Length; got %q"", contentLens) } return 0, nil } if status/100 == 1 { return 0, nil } switch status { case 204, 304: return 0, nil } if len(contentLens) > 1 { return 0, errors.New(""http: message cannot contain multiple Content-Length headers"") } if chunked(te) { return -1, nil } var cl string if len(contentLens) == 1 { cl = strings.TrimSpace(contentLens[0]) } if cl != """" { n, err := parseContentLength(cl) if err != nil { return -1, err } return n, nil } else { header.Del(""Content-Length"") } if !isResponse { return 0, nil } return -1, nil }" 20,"func TestReadRequest_BadConnectHost(t *testing.T) { data := []byte(""CONNECT []%20%48%54%54%50%2f%31%2e%31%0a%4d%79%48%65%61%64%65%72%3a%20%31%32%33%0a%0a HTTP/1.0\n\n"") r, err := ReadRequest(bufio.NewReader(bytes.NewReader(data))) if err == nil { t.Fatal(""Got unexpected request = %#v"", r) } }",True,Go,TestReadRequest_BadConnectHost,readrequest_test.go,https://github.com/golang/go,golang,Brad Fitzpatrick,2015-06-30 22:56:30+00:00,"net/http: harden Server against request smuggling See RFC 7230. Thanks to Régis Leroy for the report. Change-Id: Ic1779bc2180900430d4d7a4938cac04ed73c304c Reviewed-on: https://go-review.googlesource.com/11810 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick ",CWE-444,Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling'),"The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.",https://cwe.mitre.org/data/definitions/444.html,CVE-2015-5741,"func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) { contentLens := header[""Content-Length""] isRequest := !isResponse if noBodyExpected(requestMethod) { if isRequest && len(contentLens) > 0 && !(len(contentLens) == 1 && contentLens[0] == ""0"") { return 0, fmt.Errorf(""http: method cannot contain a Content-Length; got %q"", contentLens) } return 0, nil } if status/100 == 1 { return 0, nil } switch status { case 204, 304: return 0, nil } if len(contentLens) > 1 { return 0, errors.New(""http: message cannot contain multiple Content-Length headers"") } if chunked(te) { return -1, nil } var cl string if len(contentLens) == 1 { cl = strings.TrimSpace(contentLens[0]) } if cl != """" { n, err := parseContentLength(cl) if err != nil { return -1, err } return n, nil } else { header.Del(""Content-Length"") } if !isResponse { return 0, nil } return -1, nil }" 29,"func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) { if noBodyExpected(requestMethod) { return 0, nil } if status/100 == 1 { return 0, nil } switch status { case 204, 304: return 0, nil } if chunked(te) { return -1, nil } cl := strings.TrimSpace(header.get(""Content-Length"")) if cl != """" { n, err := parseContentLength(cl) if err != nil { return -1, err } return n, nil } else { header.Del(""Content-Length"") } if !isResponse && requestMethod == ""GET"" { return 0, nil } return -1, nil }",True,Go,fixLength,transfer.go,https://github.com/golang/go,golang,Brad Fitzpatrick,2015-06-30 22:56:30+00:00,"net/http: harden Server against request smuggling See RFC 7230. Thanks to Régis Leroy for the report. Change-Id: Ic1779bc2180900430d4d7a4938cac04ed73c304c Reviewed-on: https://go-review.googlesource.com/11810 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick ",CWE-444,Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling'),"The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.",https://cwe.mitre.org/data/definitions/444.html,CVE-2015-5740,"func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) { contentLens := header[""Content-Length""] isRequest := !isResponse if noBodyExpected(requestMethod) { if isRequest && len(contentLens) > 0 && !(len(contentLens) == 1 && contentLens[0] == ""0"") { return 0, fmt.Errorf(""http: method cannot contain a Content-Length; got %q"", contentLens) } return 0, nil } if status/100 == 1 { return 0, nil } switch status { case 204, 304: return 0, nil } if len(contentLens) > 1 { return 0, errors.New(""http: message cannot contain multiple Content-Length headers"") } if chunked(te) { return -1, nil } var cl string if len(contentLens) == 1 { cl = strings.TrimSpace(contentLens[0]) } if cl != """" { n, err := parseContentLength(cl) if err != nil { return -1, err } return n, nil } else { header.Del(""Content-Length"") } if !isResponse { return 0, nil } return -1, nil }" 30,"func fixLength(isResponse bool, status int, requestMethod string, header Header, te []string) (int64, error) { if noBodyExpected(requestMethod) { return 0, nil } if status/100 == 1 { return 0, nil } switch status { case 204, 304: return 0, nil } if chunked(te) { return -1, nil } cl := strings.TrimSpace(header.get(""Content-Length"")) if cl != """" { n, err := parseContentLength(cl) if err != nil { return -1, err } return n, nil } else { header.Del(""Content-Length"") } if !isResponse && requestMethod == ""GET"" { return 0, nil } return -1, nil }",True,Go,fixLength,transfer.go,https://github.com/golang/go,golang,Brad Fitzpatrick,2015-06-30 22:56:30+00:00,"net/http: harden Server against request smuggling See RFC 7230. Thanks to Régis Leroy for the report. Change-Id: Ic1779bc2180900430d4d7a4938cac04ed73c304c Reviewed-on: https://go-review.googlesource.com/11810 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick ",CWE-444,Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling'),"The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.",https://cwe.mitre.org/data/definitions/444.html,CVE-2015-5741,"func fixTransferEncoding(isResponse bool, requestMethod string, header Header) ([]string, error) { raw, present := header[""Transfer-Encoding""] if !present { return nil, nil } isRequest := !isResponse delete(header, ""Transfer-Encoding"") encodings := strings.Split(raw[0], "","") te := make([]string, 0, len(encodings)) for _, encoding := range encodings { encoding = strings.ToLower(strings.TrimSpace(encoding)) if encoding == ""identity"" { break } if encoding != ""chunked"" { return nil, &badStringError{""unsupported transfer encoding"", encoding} } te = te[0 : len(te)+1] te[len(te)-1] = encoding } if len(te) > 1 { return nil, &badStringError{""too many transfer encodings"", strings.Join(te, "","")} } if len(te) > 0 { if len(header[""Content-Length""]) > 0 { if isRequest { return nil, errors.New(""http: invalid Content-Length with Transfer-Encoding"") } delete(header, ""Content-Length"") } return te, nil } return nil, nil }" 31,"func fixTransferEncoding(requestMethod string, header Header) ([]string, error) { raw, present := header[""Transfer-Encoding""] if !present { return nil, nil } delete(header, ""Transfer-Encoding"") encodings := strings.Split(raw[0], "","") te := make([]string, 0, len(encodings)) for _, encoding := range encodings { encoding = strings.ToLower(strings.TrimSpace(encoding)) if encoding == ""identity"" { break } if encoding != ""chunked"" { return nil, &badStringError{""unsupported transfer encoding"", encoding} } te = te[0 : len(te)+1] te[len(te)-1] = encoding } if len(te) > 1 { return nil, &badStringError{""too many transfer encodings"", strings.Join(te, "","")} } if len(te) > 0 { delete(header, ""Content-Length"") return te, nil } return nil, nil }",True,Go,fixTransferEncoding,transfer.go,https://github.com/golang/go,golang,Brad Fitzpatrick,2015-06-30 22:56:30+00:00,"net/http: harden Server against request smuggling See RFC 7230. Thanks to Régis Leroy for the report. Change-Id: Ic1779bc2180900430d4d7a4938cac04ed73c304c Reviewed-on: https://go-review.googlesource.com/11810 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick ",CWE-444,Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling'),"The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.",https://cwe.mitre.org/data/definitions/444.html,CVE-2015-5740,"func fixTransferEncoding(isResponse bool, requestMethod string, header Header) ([]string, error) { raw, present := header[""Transfer-Encoding""] if !present { return nil, nil } isRequest := !isResponse delete(header, ""Transfer-Encoding"") encodings := strings.Split(raw[0], "","") te := make([]string, 0, len(encodings)) for _, encoding := range encodings { encoding = strings.ToLower(strings.TrimSpace(encoding)) if encoding == ""identity"" { break } if encoding != ""chunked"" { return nil, &badStringError{""unsupported transfer encoding"", encoding} } te = te[0 : len(te)+1] te[len(te)-1] = encoding } if len(te) > 1 { return nil, &badStringError{""too many transfer encodings"", strings.Join(te, "","")} } if len(te) > 0 { if len(header[""Content-Length""]) > 0 { if isRequest { return nil, errors.New(""http: invalid Content-Length with Transfer-Encoding"") } delete(header, ""Content-Length"") } return te, nil } return nil, nil }" 32,"func fixTransferEncoding(requestMethod string, header Header) ([]string, error) { raw, present := header[""Transfer-Encoding""] if !present { return nil, nil } delete(header, ""Transfer-Encoding"") encodings := strings.Split(raw[0], "","") te := make([]string, 0, len(encodings)) for _, encoding := range encodings { encoding = strings.ToLower(strings.TrimSpace(encoding)) if encoding == ""identity"" { break } if encoding != ""chunked"" { return nil, &badStringError{""unsupported transfer encoding"", encoding} } te = te[0 : len(te)+1] te[len(te)-1] = encoding } if len(te) > 1 { return nil, &badStringError{""too many transfer encodings"", strings.Join(te, "","")} } if len(te) > 0 { delete(header, ""Content-Length"") return te, nil } return nil, nil }",True,Go,fixTransferEncoding,transfer.go,https://github.com/golang/go,golang,Brad Fitzpatrick,2015-06-30 22:56:30+00:00,"net/http: harden Server against request smuggling See RFC 7230. Thanks to Régis Leroy for the report. Change-Id: Ic1779bc2180900430d4d7a4938cac04ed73c304c Reviewed-on: https://go-review.googlesource.com/11810 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick ",CWE-444,Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling'),"The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.",https://cwe.mitre.org/data/definitions/444.html,CVE-2015-5741,"func fixTransferEncoding(isResponse bool, requestMethod string, header Header) ([]string, error) { raw, present := header[""Transfer-Encoding""] if !present { return nil, nil } isRequest := !isResponse delete(header, ""Transfer-Encoding"") encodings := strings.Split(raw[0], "","") te := make([]string, 0, len(encodings)) for _, encoding := range encodings { encoding = strings.ToLower(strings.TrimSpace(encoding)) if encoding == ""identity"" { break } if encoding != ""chunked"" { return nil, &badStringError{""unsupported transfer encoding"", encoding} } te = te[0 : len(te)+1] te[len(te)-1] = encoding } if len(te) > 1 { return nil, &badStringError{""too many transfer encodings"", strings.Join(te, "","")} } if len(te) > 0 { if len(header[""Content-Length""]) > 0 { if isRequest { return nil, errors.New(""http: invalid Content-Length with Transfer-Encoding"") } delete(header, ""Content-Length"") } return te, nil } return nil, nil }" 33,"func readTransfer(msg interface{}, r *bufio.Reader) (err error) { t := &transferReader{RequestMethod: ""GET""} isResponse := false switch rr := msg.(type) { case *Response: t.Header = rr.Header t.StatusCode = rr.StatusCode t.ProtoMajor = rr.ProtoMajor t.ProtoMinor = rr.ProtoMinor t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header, true) isResponse = true if rr.Request != nil { t.RequestMethod = rr.Request.Method } case *Request: t.Header = rr.Header t.ProtoMajor = rr.ProtoMajor t.ProtoMinor = rr.ProtoMinor t.StatusCode = 200 t.Close = rr.Close default: panic(""unexpected type"") } if t.ProtoMajor == 0 && t.ProtoMinor == 0 { t.ProtoMajor, t.ProtoMinor = 1, 1 } t.TransferEncoding, err = fixTransferEncoding(t.RequestMethod, t.Header) if err != nil { return err } realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding) if err != nil { return err } if isResponse && t.RequestMethod == ""HEAD"" { if n, err := parseContentLength(t.Header.get(""Content-Length"")); err != nil { return err } else { t.ContentLength = n } } else { t.ContentLength = realLength } t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding) if err != nil { return err } switch msg.(type) { case *Response: if realLength == -1 && !chunked(t.TransferEncoding) && bodyAllowedForStatus(t.StatusCode) { t.Close = true } } switch { case chunked(t.TransferEncoding): if noBodyExpected(t.RequestMethod) { t.Body = eofReader } else { t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close} } case realLength == 0: t.Body = eofReader case realLength > 0: t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close} default: if t.Close { t.Body = &body{src: r, closing: t.Close} } else { t.Body = eofReader } } switch rr := msg.(type) { case *Request: rr.Body = t.Body rr.ContentLength = t.ContentLength rr.TransferEncoding = t.TransferEncoding rr.Close = t.Close rr.Trailer = t.Trailer case *Response: rr.Body = t.Body rr.ContentLength = t.ContentLength rr.TransferEncoding = t.TransferEncoding rr.Close = t.Close rr.Trailer = t.Trailer } return nil }",True,Go,readTransfer,transfer.go,https://github.com/golang/go,golang,Brad Fitzpatrick,2015-06-30 22:56:30+00:00,"net/http: harden Server against request smuggling See RFC 7230. Thanks to Régis Leroy for the report. Change-Id: Ic1779bc2180900430d4d7a4938cac04ed73c304c Reviewed-on: https://go-review.googlesource.com/11810 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick ",CWE-444,Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling'),"The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.",https://cwe.mitre.org/data/definitions/444.html,CVE-2015-5740,"func fixTransferEncoding(isResponse bool, requestMethod string, header Header) ([]string, error) { raw, present := header[""Transfer-Encoding""] if !present { return nil, nil } isRequest := !isResponse delete(header, ""Transfer-Encoding"") encodings := strings.Split(raw[0], "","") te := make([]string, 0, len(encodings)) for _, encoding := range encodings { encoding = strings.ToLower(strings.TrimSpace(encoding)) if encoding == ""identity"" { break } if encoding != ""chunked"" { return nil, &badStringError{""unsupported transfer encoding"", encoding} } te = te[0 : len(te)+1] te[len(te)-1] = encoding } if len(te) > 1 { return nil, &badStringError{""too many transfer encodings"", strings.Join(te, "","")} } if len(te) > 0 { if len(header[""Content-Length""]) > 0 { if isRequest { return nil, errors.New(""http: invalid Content-Length with Transfer-Encoding"") } delete(header, ""Content-Length"") } return te, nil } return nil, nil }" 34,"func readTransfer(msg interface{}, r *bufio.Reader) (err error) { t := &transferReader{RequestMethod: ""GET""} isResponse := false switch rr := msg.(type) { case *Response: t.Header = rr.Header t.StatusCode = rr.StatusCode t.ProtoMajor = rr.ProtoMajor t.ProtoMinor = rr.ProtoMinor t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header, true) isResponse = true if rr.Request != nil { t.RequestMethod = rr.Request.Method } case *Request: t.Header = rr.Header t.ProtoMajor = rr.ProtoMajor t.ProtoMinor = rr.ProtoMinor t.StatusCode = 200 t.Close = rr.Close default: panic(""unexpected type"") } if t.ProtoMajor == 0 && t.ProtoMinor == 0 { t.ProtoMajor, t.ProtoMinor = 1, 1 } t.TransferEncoding, err = fixTransferEncoding(t.RequestMethod, t.Header) if err != nil { return err } realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding) if err != nil { return err } if isResponse && t.RequestMethod == ""HEAD"" { if n, err := parseContentLength(t.Header.get(""Content-Length"")); err != nil { return err } else { t.ContentLength = n } } else { t.ContentLength = realLength } t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding) if err != nil { return err } switch msg.(type) { case *Response: if realLength == -1 && !chunked(t.TransferEncoding) && bodyAllowedForStatus(t.StatusCode) { t.Close = true } } switch { case chunked(t.TransferEncoding): if noBodyExpected(t.RequestMethod) { t.Body = eofReader } else { t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close} } case realLength == 0: t.Body = eofReader case realLength > 0: t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close} default: if t.Close { t.Body = &body{src: r, closing: t.Close} } else { t.Body = eofReader } } switch rr := msg.(type) { case *Request: rr.Body = t.Body rr.ContentLength = t.ContentLength rr.TransferEncoding = t.TransferEncoding rr.Close = t.Close rr.Trailer = t.Trailer case *Response: rr.Body = t.Body rr.ContentLength = t.ContentLength rr.TransferEncoding = t.TransferEncoding rr.Close = t.Close rr.Trailer = t.Trailer } return nil }",True,Go,readTransfer,transfer.go,https://github.com/golang/go,golang,Brad Fitzpatrick,2015-06-30 22:56:30+00:00,"net/http: harden Server against request smuggling See RFC 7230. Thanks to Régis Leroy for the report. Change-Id: Ic1779bc2180900430d4d7a4938cac04ed73c304c Reviewed-on: https://go-review.googlesource.com/11810 Reviewed-by: Russ Cox Run-TryBot: Brad Fitzpatrick ",CWE-444,Inconsistent Interpretation of HTTP Requests ('HTTP Request/Response Smuggling'),"The product acts as an intermediary HTTP agent (such as a proxy or firewall) in the data flow between two entities such as a client and server, but it does not interpret malformed HTTP requests or responses in ways that are consistent with how the messages will be processed by those entities that are at the ultimate destination.",https://cwe.mitre.org/data/definitions/444.html,CVE-2015-5741,"func readTransfer(msg interface{}, r *bufio.Reader) (err error) { t := &transferReader{RequestMethod: ""GET""} isResponse := false switch rr := msg.(type) { case *Response: t.Header = rr.Header t.StatusCode = rr.StatusCode t.ProtoMajor = rr.ProtoMajor t.ProtoMinor = rr.ProtoMinor t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header, true) isResponse = true if rr.Request != nil { t.RequestMethod = rr.Request.Method } case *Request: t.Header = rr.Header t.RequestMethod = rr.Method t.ProtoMajor = rr.ProtoMajor t.ProtoMinor = rr.ProtoMinor t.StatusCode = 200 t.Close = rr.Close default: panic(""unexpected type"") } if t.ProtoMajor == 0 && t.ProtoMinor == 0 { t.ProtoMajor, t.ProtoMinor = 1, 1 } t.TransferEncoding, err = fixTransferEncoding(isResponse, t.RequestMethod, t.Header) if err != nil { return err } realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding) if err != nil { return err } if isResponse && t.RequestMethod == ""HEAD"" { if n, err := parseContentLength(t.Header.get(""Content-Length"")); err != nil { return err } else { t.ContentLength = n } } else { t.ContentLength = realLength } t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding) if err != nil { return err } switch msg.(type) { case *Response: if realLength == -1 && !chunked(t.TransferEncoding) && bodyAllowedForStatus(t.StatusCode) { t.Close = true } } switch { case chunked(t.TransferEncoding): if noBodyExpected(t.RequestMethod) { t.Body = eofReader } else { t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close} } case realLength == 0: t.Body = eofReader case realLength > 0: t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close} default: if t.Close { t.Body = &body{src: r, closing: t.Close} } else { t.Body = eofReader } } switch rr := msg.(type) { case *Request: rr.Body = t.Body rr.ContentLength = t.ContentLength rr.TransferEncoding = t.TransferEncoding rr.Close = t.Close rr.Trailer = t.Trailer case *Response: rr.Body = t.Body rr.ContentLength = t.ContentLength rr.TransferEncoding = t.TransferEncoding rr.Close = t.Close rr.Trailer = t.Trailer } return nil }" 41,"func TestToFromBig(t *testing.T) { for i, test := range toFromBigTests { n, _ := new(big.Int).SetString(test, 16) var x p224FieldElement p224FromBig(&x, n) m := p224ToBig(&x) if n.Cmp(m) != 0 { t.Errorf(""#%d: %x != %x"", i, n, m) } q := p224AlternativeToBig(&x) if n.Cmp(q) != 0 { t.Errorf(""#%d: %x != %x (alternative)"", i, n, m) } } }",True,Go,TestToFromBig,p224_test.go,https://github.com/golang/go,golang,Roland Shoemaker,2021-01-21 18:52:19+00:00,"crypto/elliptic: fix P-224 field reduction This patch fixes two independent bugs in p224Contract, the function that performs the final complete reduction in the P-224 field. Incorrect outputs due to these bugs were observable from a high-level P224().ScalarMult() call. The first bug was in the calculation of out3GT. That mask was supposed to be all ones if the third limb of the value is greater than the third limb of P (out[3] > 0xffff000). Instead, it was also set if they are equal. That meant that if the third limb was equal, the value was always considered greater than or equal to P, even when the three bottom limbs were all zero. There is exactly one affected value, P - 1, which would trigger the subtraction by P even if it's lower than P already. The second bug was more easily hit, and is the one that caused the known high-level incorrect output: after the conditional subtraction by P, a potential underflow of the lowest limb was not handled. Any values that trigger the subtraction by P (values between P and 2^224-1, and P - 1 due to the bug above) but have a zero lowest limb would produce invalid outputs. Those conditions apply to the intermediate representation before the subtraction, so they are hard to trace to precise inputs. This patch also adds a test suite for the P-224 field arithmetic, including a custom fuzzer that automatically explores potential edge cases by combining limb values that have various meanings in the code. contractMatchesBigInt in TestP224Contract finds the second bug in less than a second without being tailored to it, and could eventually find the first one too by combining 0, (1 << 28) - 1, and the difference of (1 << 28) and (1 << 12). The incorrect P224().ScalarMult() output was found by the elliptic-curve-differential-fuzzer project running on OSS-Fuzz and reported by Philippe Antoine (Catena cyber). Fixes CVE-2021-3114 Fixes #43786 Change-Id: I50176602d544de3da854270d66a293bcaca57ad7 Reviewed-on: https://go-review.googlesource.com/c/go/+/284779 Run-TryBot: Roland Shoemaker TryBot-Result: Go Bot Trust: Ian Lance Taylor Trust: Roland Shoemaker Reviewed-by: Filippo Valsorda ",CWE-682,Incorrect Calculation,The product performs a calculation that generates incorrect or unintended results that are later used in security-critical decisions or resource management.,https://cwe.mitre.org/data/definitions/682.html,CVE-2021-3114,"func readTransfer(msg interface{}, r *bufio.Reader) (err error) { t := &transferReader{RequestMethod: ""GET""} isResponse := false switch rr := msg.(type) { case *Response: t.Header = rr.Header t.StatusCode = rr.StatusCode t.ProtoMajor = rr.ProtoMajor t.ProtoMinor = rr.ProtoMinor t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header, true) isResponse = true if rr.Request != nil { t.RequestMethod = rr.Request.Method } case *Request: t.Header = rr.Header t.RequestMethod = rr.Method t.ProtoMajor = rr.ProtoMajor t.ProtoMinor = rr.ProtoMinor t.StatusCode = 200 t.Close = rr.Close default: panic(""unexpected type"") } if t.ProtoMajor == 0 && t.ProtoMinor == 0 { t.ProtoMajor, t.ProtoMinor = 1, 1 } t.TransferEncoding, err = fixTransferEncoding(isResponse, t.RequestMethod, t.Header) if err != nil { return err } realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding) if err != nil { return err } if isResponse && t.RequestMethod == ""HEAD"" { if n, err := parseContentLength(t.Header.get(""Content-Length"")); err != nil { return err } else { t.ContentLength = n } } else { t.ContentLength = realLength } t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding) if err != nil { return err } switch msg.(type) { case *Response: if realLength == -1 && !chunked(t.TransferEncoding) && bodyAllowedForStatus(t.StatusCode) { t.Close = true } } switch { case chunked(t.TransferEncoding): if noBodyExpected(t.RequestMethod) { t.Body = eofReader } else { t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close} } case realLength == 0: t.Body = eofReader case realLength > 0: t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close} default: if t.Close { t.Body = &body{src: r, closing: t.Close} } else { t.Body = eofReader } } switch rr := msg.(type) { case *Request: rr.Body = t.Body rr.ContentLength = t.ContentLength rr.TransferEncoding = t.TransferEncoding rr.Close = t.Close rr.Trailer = t.Trailer case *Response: rr.Body = t.Body rr.ContentLength = t.ContentLength rr.TransferEncoding = t.TransferEncoding rr.Close = t.Close rr.Trailer = t.Trailer } return nil }" 43,"func p224AlternativeToBig(in *p224FieldElement) *big.Int { ret := new(big.Int) tmp := new(big.Int) for i := uint(0); i < 8; i++ { tmp.SetInt64(int64(in[i])) tmp.Lsh(tmp, 28*i) ret.Add(ret, tmp) } ret.Mod(ret, p224.P) return ret }",True,Go,p224AlternativeToBig,p224_test.go,https://github.com/golang/go,golang,Roland Shoemaker,2021-01-21 18:52:19+00:00,"crypto/elliptic: fix P-224 field reduction This patch fixes two independent bugs in p224Contract, the function that performs the final complete reduction in the P-224 field. Incorrect outputs due to these bugs were observable from a high-level P224().ScalarMult() call. The first bug was in the calculation of out3GT. That mask was supposed to be all ones if the third limb of the value is greater than the third limb of P (out[3] > 0xffff000). Instead, it was also set if they are equal. That meant that if the third limb was equal, the value was always considered greater than or equal to P, even when the three bottom limbs were all zero. There is exactly one affected value, P - 1, which would trigger the subtraction by P even if it's lower than P already. The second bug was more easily hit, and is the one that caused the known high-level incorrect output: after the conditional subtraction by P, a potential underflow of the lowest limb was not handled. Any values that trigger the subtraction by P (values between P and 2^224-1, and P - 1 due to the bug above) but have a zero lowest limb would produce invalid outputs. Those conditions apply to the intermediate representation before the subtraction, so they are hard to trace to precise inputs. This patch also adds a test suite for the P-224 field arithmetic, including a custom fuzzer that automatically explores potential edge cases by combining limb values that have various meanings in the code. contractMatchesBigInt in TestP224Contract finds the second bug in less than a second without being tailored to it, and could eventually find the first one too by combining 0, (1 << 28) - 1, and the difference of (1 << 28) and (1 << 12). The incorrect P224().ScalarMult() output was found by the elliptic-curve-differential-fuzzer project running on OSS-Fuzz and reported by Philippe Antoine (Catena cyber). Fixes CVE-2021-3114 Fixes #43786 Change-Id: I50176602d544de3da854270d66a293bcaca57ad7 Reviewed-on: https://go-review.googlesource.com/c/go/+/284779 Run-TryBot: Roland Shoemaker TryBot-Result: Go Bot Trust: Ian Lance Taylor Trust: Roland Shoemaker Reviewed-by: Filippo Valsorda ",CWE-682,Incorrect Calculation,The product performs a calculation that generates incorrect or unintended results that are later used in security-critical decisions or resource management.,https://cwe.mitre.org/data/definitions/682.html,CVE-2021-3114,"func readTransfer(msg interface{}, r *bufio.Reader) (err error) { t := &transferReader{RequestMethod: ""GET""} isResponse := false switch rr := msg.(type) { case *Response: t.Header = rr.Header t.StatusCode = rr.StatusCode t.ProtoMajor = rr.ProtoMajor t.ProtoMinor = rr.ProtoMinor t.Close = shouldClose(t.ProtoMajor, t.ProtoMinor, t.Header, true) isResponse = true if rr.Request != nil { t.RequestMethod = rr.Request.Method } case *Request: t.Header = rr.Header t.RequestMethod = rr.Method t.ProtoMajor = rr.ProtoMajor t.ProtoMinor = rr.ProtoMinor t.StatusCode = 200 t.Close = rr.Close default: panic(""unexpected type"") } if t.ProtoMajor == 0 && t.ProtoMinor == 0 { t.ProtoMajor, t.ProtoMinor = 1, 1 } t.TransferEncoding, err = fixTransferEncoding(isResponse, t.RequestMethod, t.Header) if err != nil { return err } realLength, err := fixLength(isResponse, t.StatusCode, t.RequestMethod, t.Header, t.TransferEncoding) if err != nil { return err } if isResponse && t.RequestMethod == ""HEAD"" { if n, err := parseContentLength(t.Header.get(""Content-Length"")); err != nil { return err } else { t.ContentLength = n } } else { t.ContentLength = realLength } t.Trailer, err = fixTrailer(t.Header, t.TransferEncoding) if err != nil { return err } switch msg.(type) { case *Response: if realLength == -1 && !chunked(t.TransferEncoding) && bodyAllowedForStatus(t.StatusCode) { t.Close = true } } switch { case chunked(t.TransferEncoding): if noBodyExpected(t.RequestMethod) { t.Body = eofReader } else { t.Body = &body{src: internal.NewChunkedReader(r), hdr: msg, r: r, closing: t.Close} } case realLength == 0: t.Body = eofReader case realLength > 0: t.Body = &body{src: io.LimitReader(r, realLength), closing: t.Close} default: if t.Close { t.Body = &body{src: r, closing: t.Close} } else { t.Body = eofReader } } switch rr := msg.(type) { case *Request: rr.Body = t.Body rr.ContentLength = t.ContentLength rr.TransferEncoding = t.TransferEncoding rr.Close = t.Close rr.Trailer = t.Trailer case *Response: rr.Body = t.Body rr.ContentLength = t.ContentLength rr.TransferEncoding = t.TransferEncoding rr.Close = t.Close rr.Trailer = t.Trailer } return nil }" 54,func (c *proxiedConn) RemoteAddr() net.Addr { if c.remoteAddr != nil { return c.remoteAddr } return c.RemoteAddr() },True,Go,RemoteAddr,conn.go,https://github.com/btcsuite/go-socks,btcsuite,David Hill,2013-08-07 20:04:56-04:00,fix potential infinite loops in both LocalAddr and RemoteAddr,CWE-835,Loop with Unreachable Exit Condition ('Infinite Loop'),"The product contains an iteration or loop with an exit condition that cannot be reached, i.e., an infinite loop.",https://cwe.mitre.org/data/definitions/835.html,CVE-2013-10005,"func p224AlternativeToBig(in *p224FieldElement) *big.Int { ret := new(big.Int) tmp := new(big.Int) for i := len(in) - 1; i >= 0; i-- { ret.Lsh(ret, 28) tmp.SetInt64(int64(in[i])) ret.Add(ret, tmp) } ret.Mod(ret, P224().Params().P) return ret }" 55,"func Uncompress(in, out []byte) (err error) { read := int(C.LZ4_uncompress(p(in), p(out), clen(out))) if read != len(in) { err = fmt.Errorf(""uncompress read %d bytes should have read %d"", read, len(in)) } return }",True,Go,Uncompress,lz4.go,https://github.com/cloudflare/golz4,cloudflare,John Graham-Cumming,2014-07-11 08:47:35-07:00,"Use LZ4_decompress_safe instead of LZ4_uncompress LZ4_uncompress is deprecated and has security problems.",CWE-787,Out-of-bounds Write,"The product writes data past the end, or before the beginning, of the intended buffer.",https://cwe.mitre.org/data/definitions/787.html,CVE-2014-125026,func (c *proxiedConn) LocalAddr() net.Addr { if c.boundAddr != nil { return c.boundAddr } return c.conn.LocalAddr() } 57,"func VerifyPassphrase(passphrase string, keylen_bytes int, target_key []byte) (result bool, err error) { target_master_key := target_key[:keylen_bytes] salt := target_key[keylen_bytes:48] var N, r, p int32 err = binary.Read(bytes.NewReader(target_key[48:52]), binary.LittleEndian, &N) if err != nil { log.Fatalf(""binary.Read failed for N: %s\n"", err) return } err = binary.Read(bytes.NewReader(target_key[52:56]), binary.LittleEndian, &r) if err != nil { log.Fatalf(""binary.Read failed for r: %s\n"", err) return } err = binary.Read(bytes.NewReader(target_key[56:60]), binary.LittleEndian, &p) if err != nil { log.Fatalf(""binary.Read failed for p: %s\n"", err) return } var source_master_key []byte source_master_key, err = scrypt.Key([]byte(passphrase), salt, int(N), int(r), int(p), keylen_bytes) if err != nil { log.Fatalf(""Error in encrypting passphrase: %s\n"", err) return } target_hash := target_key[60:] hash_digest := sha256.New() _, err = hash_digest.Write(target_key[:60]) if err != nil { log.Fatalf(""hash_digest.Write failed: %s\n"", err) return } source_hash := hash_digest.Sum(nil) result = bytes.Equal(source_master_key, target_master_key) && bytes.Equal(target_hash, source_hash) return }",True,Go,VerifyPassphrase,scrypt.go,https://github.com/agnivade/easy-scrypt,agnivade,Agniva De Sarker,2014-10-10 15:50:08-07:00,"Preventing timing attacks - By using ConstantTimeCompare Reviewed by: Testing: Tickets: Backport:",CWE-208,Observable Timing Discrepancy,"Two separate operations in a product require different amounts of time to complete, in a way that is observable to an actor and reveals security-relevant information about the state of the product, such as whether a particular operation was successful or not.",https://cwe.mitre.org/data/definitions/208.html,CVE-2014-125055,func (c *proxiedConn) RemoteAddr() net.Addr { if c.remoteAddr != nil { return c.remoteAddr } return c.conn.RemoteAddr() } 60,"func GetIssues(uid, rid, pid, mid int64, page int, isClosed bool, labelIds, sortType string) ([]Issue, error) { sess := x.Limit(20, (page-1)*20) if rid > 0 { sess.Where(""repo_id=?"", rid).And(""is_closed=?"", isClosed) } else { sess.Where(""is_closed=?"", isClosed) } if uid > 0 { sess.And(""assignee_id=?"", uid) } else if pid > 0 { sess.And(""poster_id=?"", pid) } if mid > 0 { sess.And(""milestone_id=?"", mid) } if len(labelIds) > 0 { for _, label := range strings.Split(labelIds, "","") { sess.And(""label_ids like '%$"" + label + ""|%'"") } } switch sortType { case ""oldest"": sess.Asc(""created"") case ""recentupdate"": sess.Desc(""updated"") case ""leastupdate"": sess.Asc(""updated"") case ""mostcomment"": sess.Desc(""num_comments"") case ""leastcomment"": sess.Asc(""num_comments"") case ""priority"": sess.Desc(""priority"") default: sess.Desc(""created"") } var issues []Issue err := sess.Find(&issues) return issues, err }",True,Go,GetIssues,issue.go,https://github.com/gogits/gogs,gogits,Unknwon,2014-10-25 07:50:19-04:00,Safe work,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2014-8681,"func Uncompress(in, out []byte) (error) { if int(C.LZ4_decompress_safe(p(in), p(out), clen(in), clen(out))) < 0 { return errors.New(""Malformed compression stream"") } return nil }" 63,"func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) { opt.Keyword = strings.TrimSpace(opt.Keyword) if len(opt.Keyword) == 0 { return repos, nil } opt.Keyword = strings.Split(opt.Keyword, "" "")[0] if len(opt.Keyword) == 0 { return repos, nil } opt.Keyword = strings.ToLower(opt.Keyword) repos = make([]*Repository, 0, opt.Limit) sess := x.Limit(opt.Limit) if opt.Uid > 0 { sess.Where(""owner_id=?"", opt.Uid) } sess.And(""lower_name like '%"" + opt.Keyword + ""%'"").Find(&repos) return repos, err }",True,Go,SearchRepositoryByName,repo.go,https://github.com/gogits/gogs,gogits,Unknwon,2014-10-25 07:50:19-04:00,Safe work,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2014-8681,"func VerifyPassphrase(passphrase string, keylen_bytes int, target_key []byte) (result bool, err error) { target_master_key := target_key[:keylen_bytes] salt := target_key[keylen_bytes:48] var N, r, p int32 err = binary.Read(bytes.NewReader(target_key[48:52]), binary.LittleEndian, &N) if err != nil { log.Fatalf(""binary.Read failed for N: %s\n"", err) return } err = binary.Read(bytes.NewReader(target_key[52:56]), binary.LittleEndian, &r) if err != nil { log.Fatalf(""binary.Read failed for r: %s\n"", err) return } err = binary.Read(bytes.NewReader(target_key[56:60]), binary.LittleEndian, &p) if err != nil { log.Fatalf(""binary.Read failed for p: %s\n"", err) return } var source_master_key []byte source_master_key, err = scrypt.Key([]byte(passphrase), salt, int(N), int(r), int(p), keylen_bytes) if err != nil { log.Fatalf(""Error in encrypting passphrase: %s\n"", err) return } target_hash := target_key[60:] hash_digest := sha256.New() _, err = hash_digest.Write(target_key[:60]) if err != nil { log.Fatalf(""hash_digest.Write failed: %s\n"", err) return } source_hash := hash_digest.Sum(nil) key_comp := subtle.ConstantTimeCompare(source_master_key, target_master_key) != 0 hash_comp := subtle.ConstantTimeCompare(target_hash, source_hash) != 0 result = key_comp && hash_comp return }" 64,"func SearchUserByName(opt SearchOption) (us []*User, err error) { opt.Keyword = strings.TrimSpace(opt.Keyword) if len(opt.Keyword) == 0 { return us, nil } opt.Keyword = strings.Split(opt.Keyword, "" "")[0] if len(opt.Keyword) == 0 { return us, nil } opt.Keyword = strings.ToLower(opt.Keyword) us = make([]*User, 0, opt.Limit) err = x.Limit(opt.Limit).Where(""type=0"").And(""lower_name like '%"" + opt.Keyword + ""%'"").Find(&us) return us, err }",True,Go,SearchUserByName,user.go,https://github.com/gogits/gogs,gogits,Unknwon,2014-10-25 07:50:19-04:00,Safe work,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2014-8681,"func GetIssues(uid, rid, pid, mid int64, page int, isClosed bool, labelIds, sortType string) ([]Issue, error) { sess := x.Limit(20, (page-1)*20) if rid > 0 { sess.Where(""repo_id=?"", rid).And(""is_closed=?"", isClosed) } else { sess.Where(""is_closed=?"", isClosed) } if uid > 0 { sess.And(""assignee_id=?"", uid) } else if pid > 0 { sess.And(""poster_id=?"", pid) } if mid > 0 { sess.And(""milestone_id=?"", mid) } if len(labelIds) > 0 { for _, label := range strings.Split(labelIds, "","") { if com.StrTo(label).MustInt() > 0 { sess.And(""label_ids like '%$"" + label + ""|%'"") } } } switch sortType { case ""oldest"": sess.Asc(""created"") case ""recentupdate"": sess.Desc(""updated"") case ""leastupdate"": sess.Asc(""updated"") case ""mostcomment"": sess.Desc(""num_comments"") case ""leastcomment"": sess.Asc(""num_comments"") case ""priority"": sess.Desc(""priority"") default: sess.Desc(""created"") } var issues []Issue err := sess.Find(&issues) return issues, err }" 68,"func checkVersion() { data, err := ioutil.ReadFile(path.Join(setting.StaticRootPath, ""templates/.VERSION"")) if err != nil { log.Fatal(4, ""Fail to read 'templates/.VERSION': %v"", err) } if string(data) != setting.AppVer { log.Fatal(4, ""Binary and template file version does not match, did you forget to recompile?"") } macaronVer := git.MustParseVersion(strings.Join(strings.Split(macaron.Version(), ""."")[:3], ""."")) if macaronVer.LessThan(git.MustParseVersion(""0.2.3"")) { log.Fatal(4, ""Package macaron version is too old, did you forget to update?(github.com/Unknwon/macaron)"") } i18nVer := git.MustParseVersion(i18n.Version()) if i18nVer.LessThan(git.MustParseVersion(""0.0.2"")) { log.Fatal(4, ""Package i18n version is too old, did you forget to update?(github.com/macaron-contrib/i18n)"") } sessionVer := git.MustParseVersion(session.Version()) if sessionVer.LessThan(git.MustParseVersion(""0.0.3"")) { log.Fatal(4, ""Package session version is too old, did you forget to update?(github.com/macaron-contrib/session)"") } }",True,Go,checkVersion,web.go,https://github.com/gogits/gogs,gogits,Unknwon,2014-11-04 11:37:15-05:00,fix session API broken and SQL pretection,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2014-8682,"func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) { opt.Keyword = FilterSQLInject(opt.Keyword) if len(opt.Keyword) == 0 { return repos, nil } opt.Keyword = strings.ToLower(opt.Keyword) repos = make([]*Repository, 0, opt.Limit) sess := x.Limit(opt.Limit) if opt.Uid > 0 { sess.Where(""owner_id=?"", opt.Uid) } if !opt.Private { sess.And(""is_private=false"") } sess.And(""lower_name like '%"" + opt.Keyword + ""%'"").Find(&repos) return repos, err }" 70,"func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) { opt.Keyword = FilterSQLInject(opt.Keyword) if len(opt.Keyword) == 0 { return repos, nil } opt.Keyword = strings.ToLower(opt.Keyword) repos = make([]*Repository, 0, opt.Limit) sess := x.Limit(opt.Limit) if opt.Uid > 0 { sess.Where(""owner_id=?"", opt.Uid) } if !opt.Private { sess.And(""is_private=false"") } sess.And(""lower_name like '%"" + opt.Keyword + ""%'"").Find(&repos) return repos, err }",True,Go,SearchRepositoryByName,repo.go,https://github.com/gogits/gogs,gogits,Unknwon,2014-11-04 11:37:15-05:00,fix session API broken and SQL pretection,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2014-8682,"func SearchUserByName(opt SearchOption) (us []*User, err error) { opt.Keyword = FilterSQLInject(opt.Keyword) if len(opt.Keyword) == 0 { return us, nil } opt.Keyword = strings.ToLower(opt.Keyword) us = make([]*User, 0, opt.Limit) err = x.Limit(opt.Limit).Where(""type=0"").And(""lower_name like '%"" + opt.Keyword + ""%'"").Find(&us) return us, err }" 71,"func SearchUserByName(opt SearchOption) (us []*User, err error) { opt.Keyword = FilterSQLInject(opt.Keyword) if len(opt.Keyword) == 0 { return us, nil } opt.Keyword = strings.ToLower(opt.Keyword) us = make([]*User, 0, opt.Limit) err = x.Limit(opt.Limit).Where(""type=0"").And(""lower_name like '%"" + opt.Keyword + ""%'"").Find(&us) return us, err }",True,Go,SearchUserByName,user.go,https://github.com/gogits/gogs,gogits,Unknwon,2014-11-04 11:37:15-05:00,fix session API broken and SQL pretection,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2014-8682,"func checkVersion() { data, err := ioutil.ReadFile(path.Join(setting.StaticRootPath, ""templates/.VERSION"")) if err != nil { log.Fatal(4, ""Fail to read 'templates/.VERSION': %v"", err) } if string(data) != setting.AppVer { log.Fatal(4, ""Binary and template file version does not match, did you forget to recompile?"") } macaronVer := git.MustParseVersion(strings.Join(strings.Split(macaron.Version(), ""."")[:3], ""."")) if macaronVer.LessThan(git.MustParseVersion(""0.2.3"")) { log.Fatal(4, ""Package macaron version is too old, did you forget to update?(github.com/Unknwon/macaron)"") } i18nVer := git.MustParseVersion(i18n.Version()) if i18nVer.LessThan(git.MustParseVersion(""0.0.2"")) { log.Fatal(4, ""Package i18n version is too old, did you forget to update?(github.com/macaron-contrib/i18n)"") } sessionVer := git.MustParseVersion(session.Version()) if sessionVer.LessThan(git.MustParseVersion(""0.0.5"")) { log.Fatal(4, ""Package session version is too old, did you forget to update?(github.com/macaron-contrib/session)"") } }" 73,"func newSessionService() { SessionProvider = Cfg.MustValueRange(""session"", ""PROVIDER"", ""memory"", []string{""memory"", ""file"", ""redis"", ""mysql""}) SessionConfig = new(session.Config) SessionConfig.ProviderConfig = strings.Trim(Cfg.MustValue(""session"", ""PROVIDER_CONFIG""), ""\"" "") SessionConfig.CookieName = Cfg.MustValue(""session"", ""COOKIE_NAME"", ""i_like_gogits"") SessionConfig.CookiePath = AppSubUrl SessionConfig.Secure = Cfg.MustBool(""session"", ""COOKIE_SECURE"") SessionConfig.EnableSetCookie = Cfg.MustBool(""session"", ""ENABLE_SET_COOKIE"", true) SessionConfig.Gclifetime = Cfg.MustInt64(""session"", ""GC_INTERVAL_TIME"", 86400) SessionConfig.Maxlifetime = Cfg.MustInt64(""session"", ""SESSION_LIFE_TIME"", 86400) SessionConfig.SessionIDHashFunc = Cfg.MustValueRange(""session"", ""SESSION_ID_HASHFUNC"", ""sha1"", []string{""sha1"", ""sha256"", ""md5""}) SessionConfig.SessionIDHashKey = Cfg.MustValue(""session"", ""SESSION_ID_HASHKEY"", string(com.RandomCreateBytes(16))) if SessionProvider == ""file"" { os.MkdirAll(path.Dir(SessionConfig.ProviderConfig), os.ModePerm) } log.Info(""Session Service Enabled"") }",True,Go,newSessionService,setting.go,https://github.com/gogits/gogs,gogits,Unknwon,2014-11-04 11:37:15-05:00,fix session API broken and SQL pretection,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2014-8682,"func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) { opt.Keyword = FilterSQLInject(opt.Keyword) if len(opt.Keyword) == 0 { return repos, nil } opt.Keyword = strings.ToLower(opt.Keyword) repos = make([]*Repository, 0, opt.Limit) sess := x.Limit(opt.Limit) if opt.Uid > 0 { sess.Where(""owner_id=?"", opt.Uid) } if !opt.Private { sess.And(""is_private=false"") } sess.And(""lower_name like ?"", ""%""+opt.Keyword+""%"").Find(&repos) return repos, err }" 74,"func main() { log.Println(""[i] Server started"") db, err := sql.Open(""postgres"", ""user=appread dbname='quantifiedSelf' sslmode=disable"") failOnError(err, ""Error connecting to database"") defer db.Close() http.HandleFunc(""/data/all/"", func(w http.ResponseWriter, r *http.Request) { var output string err := db.QueryRow(`SELECT json_agg(r) FROM (SELECT * FROM trello.cards) r;`).Scan(&output) if err != nil { log.Println(""Error retriving from DB, "", err) w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(w, ""Error retriving from DB, "", err) return } fmt.Fprint(w, output) }) r := mux.NewRouter() r.HandleFunc(""/api"", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, ""dla;jfkdlsajflkdsa;jfk;ldsajfklds;a"") }) r.HandleFunc(""/api/totals/last/{num}"", func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) var output string query := fmt.Sprintf(`SELECT json_agg(r) FROM (select EXTRACT(epoch FROM day) as day, end_of_day_total from trello.dailytallies order by day DESC limit %s) r;`, vars[""num""]) err := db.QueryRow(query).Scan(&output) if err != nil { log.Println(""Error retriving from DB, "", err) w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(w, ""Error retriving from DB, "", err) return } w.Header().Set(""Content-Type"", ""application/json"") fmt.Fprint(w, output) }) r.HandleFunc(""/api/diffs/last/{num}"", func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) var output string query := fmt.Sprintf(`SELECT json_agg(r) FROM (select EXTRACT(epoch FROM day) as day, up_count, down_count, finished_count from trello.dailytallies order by day DESC limit %s) r;`, vars[""num""]) err := db.QueryRow(query).Scan(&output) if err != nil { log.Println(""Error retriving from DB, "", err) w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(w, ""Error retriving from DB, "", err) return } w.Header().Set(""Content-Type"", ""application/json"") fmt.Fprint(w, output) }) r.PathPrefix(""/"").Handler(http.FileServer(http.Dir(""../ui""))) http.Handle(""/"", r) log.Println(""[i] Serving on "", servport, ""\n\tWaiting..."") log.Fatal(http.ListenAndServe(servport, nil)) log.Println(""[i] Shutting down..."") }",True,Go,main,srv.go,https://github.com/Fumon/trello-octometric,Fumon,Jade Bilkey,2015-01-25 13:04:04-05:00,Fixed sql injection,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10023,"func SearchUserByName(opt SearchOption) (us []*User, err error) { opt.Keyword = FilterSQLInject(opt.Keyword) if len(opt.Keyword) == 0 { return us, nil } opt.Keyword = strings.ToLower(opt.Keyword) us = make([]*User, 0, opt.Limit) err = x.Limit(opt.Limit).Where(""type=0"").And(""lower_name like ?"", ""%""+opt.Keyword+""%"").Find(&us) return us, err }" 78,"func (f *FileStorage) storagePathFor(contentID string) string { return path.Join(f.path, contentID) }",True,Go,storagePathFor,file_storage.go,https://github.com/hoffie/larasync,hoffie,Christian Hoffmann,2015-01-20 23:21:00+01:00,repository/content: fix potential (authenticated) path traversal (#195),CWE-22,Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'),"The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.",https://cwe.mitre.org/data/definitions/22.html,CVE-2015-10024,"func main() { log.Println(""[i] Server started"") db, err := sql.Open(""postgres"", ""user=appread dbname='quantifiedSelf' sslmode=disable"") failOnError(err, ""Error connecting to database"") defer db.Close() http.HandleFunc(""/data/all/"", func(w http.ResponseWriter, r *http.Request) { var output string err := db.QueryRow(`SELECT json_agg(r) FROM (SELECT * FROM trello.cards) r;`).Scan(&output) if err != nil { log.Println(""Error retriving from DB, "", err) w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(w, ""Error retriving from DB, "", err) return } fmt.Fprint(w, output) }) r := mux.NewRouter() r.HandleFunc(""/api"", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, ""dla;jfkdlsajflkdsa;jfk;ldsajfklds;a"") }) r.HandleFunc(""/api/totals/last/{num}"", func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) var output string query := `SELECT json_agg(r) FROM (select EXTRACT(epoch FROM day) as day, end_of_day_total from trello.dailytallies order by day DESC limit $1) r;` err := db.QueryRow(query, vars[""num""]).Scan(&output) if err != nil { log.Println(""Error retriving from DB, "", err) w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(w, ""Error retriving from DB, "", err) return } w.Header().Set(""Content-Type"", ""application/json"") fmt.Fprint(w, output) }) r.HandleFunc(""/api/diffs/last/{num}"", func(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) var output string query := `SELECT json_agg(r) FROM (select EXTRACT(epoch FROM day) as day, up_count, down_count, finished_count from trello.dailytallies order by day DESC limit $1) r;` err := db.QueryRow(query, vars[""num""]).Scan(&output) if err != nil { log.Println(""Error retriving from DB, "", err) w.WriteHeader(http.StatusInternalServerError) fmt.Fprintln(w, ""Error retriving from DB, "", err) return } w.Header().Set(""Content-Type"", ""application/json"") fmt.Fprint(w, output) }) r.PathPrefix(""/"").Handler(http.FileServer(http.Dir(""../ui""))) http.Handle(""/"", r) log.Println(""[i] Serving on "", servport, ""\n\tWaiting..."") log.Fatal(http.ListenAndServe(servport, nil)) log.Println(""[i] Shutting down..."") }" 79,"func (f *FileStorage) Set(contentID string, reader io.Reader) error { blobStoragePath := f.storagePathFor(contentID) writer, err := atomic.NewStandardWriter(blobStoragePath, defaultFilePerms) if err != nil { return err } _, err = io.Copy(writer, reader) if err != nil { writer.Abort() writer.Close() return err } err = writer.Close() if err != nil { return err } return nil }",True,Go,Set,file_storage.go,https://github.com/hoffie/larasync,hoffie,Christian Hoffmann,2015-01-20 23:21:00+01:00,repository/content: fix potential (authenticated) path traversal (#195),CWE-22,Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'),"The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.",https://cwe.mitre.org/data/definitions/22.html,CVE-2015-10024,"func (f *FileStorage) storagePathFor(contentID string) (string, error) { p := path.Join(f.path, contentID) p = filepath.Clean(p) root := f.path if !strings.HasPrefix(p, root) { return """", ErrInvalidPath } return p, nil }" 80,"func (f *FileStorage) Exists(contentID string) bool { _, err := os.Stat(f.storagePathFor(contentID)) if err != nil { return !os.IsNotExist(err) } return true }",True,Go,Exists,file_storage.go,https://github.com/hoffie/larasync,hoffie,Christian Hoffmann,2015-01-20 23:21:00+01:00,repository/content: fix potential (authenticated) path traversal (#195),CWE-22,Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'),"The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.",https://cwe.mitre.org/data/definitions/22.html,CVE-2015-10024,"func (f *FileStorage) Set(contentID string, reader io.Reader) error { blobStoragePath, err := f.storagePathFor(contentID) if err != nil { return err } writer, err := atomic.NewStandardWriter(blobStoragePath, defaultFilePerms) if err != nil { return err } _, err = io.Copy(writer, reader) if err != nil { writer.Abort() writer.Close() return err } err = writer.Close() if err != nil { return err } return nil }" 82,func (f *FileStorage) Delete(contentID string) error { return os.Remove(f.storagePathFor(contentID)) },True,Go,Delete,file_storage.go,https://github.com/hoffie/larasync,hoffie,Christian Hoffmann,2015-01-20 23:21:00+01:00,repository/content: fix potential (authenticated) path traversal (#195),CWE-22,Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'),"The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.",https://cwe.mitre.org/data/definitions/22.html,CVE-2015-10024,"func (f *FileStorage) Exists(contentID string) bool { p, err := f.storagePathFor(contentID) if err != nil { return false } _, err = os.Stat(p) if err != nil { return !os.IsNotExist(err) } return true }" 85,"func (f *FileStorage) Get(contentID string) (io.ReadCloser, error) { if f.Exists(contentID) { return os.Open(f.storagePathFor(contentID)) } return nil, os.ErrNotExist }",True,Go,Get,file_storage.go,https://github.com/hoffie/larasync,hoffie,Christian Hoffmann,2015-01-20 23:21:00+01:00,repository/content: fix potential (authenticated) path traversal (#195),CWE-22,Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'),"The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.",https://cwe.mitre.org/data/definitions/22.html,CVE-2015-10024,"func (f *FileStorage) Delete(contentID string) error { p, err := f.storagePathFor(contentID) if err != nil { return err } return os.Remove(p) }" 88,"func getCredentials(request *http.Request) (userName string, password string) { if cookie, err := request.Cookie(""Credentials""); err == nil { cookieValue := make(map[string]string) if err = cookieHandler.Decode(""Credentials"", cookie.Value, &cookieValue); err == nil { userName = cookieValue[""user""] password = cookieValue[""passwd""] } } return userName, password }",True,Go,getCredentials,auth.go,https://github.com/gophergala/sqldump,gophergala,micha-p,2015-01-25 02:26:19+01:00,Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10044,"func (f *FileStorage) Get(contentID string) (io.ReadCloser, error) { if !f.Exists(contentID) { return nil, os.ErrNotExist } p, err := f.storagePathFor(contentID) if err != nil { return nil, err } return os.Open(p) }" 92,"func clearCredentials(w http.ResponseWriter) { cookie := &http.Cookie{ Name: ""Credentials"", Value: """", Path: ""/"", MaxAge: -1, } http.SetCookie(w, cookie) }",True,Go,clearCredentials,auth.go,https://github.com/gophergala/sqldump,gophergala,micha-p,2015-01-25 02:26:19+01:00,Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10044,"func getCredentials(request *http.Request) (userName string, password string, host string, port string) { if cookie, err := request.Cookie(""Datasource""); err == nil { cookieValue := make(map[string]string) if err = cookieHandler.Decode(""Datasource"", cookie.Value, &cookieValue); err == nil { userName = cookieValue[""user""] password = cookieValue[""passwd""] host = cookieValue[""host""] port = cookieValue[""port""] } } return userName, password, host, port }" 94,"func setCredentials(userName string, pw string, w http.ResponseWriter) { value := map[string]string{ ""user"": userName, ""passwd"": pw, } if encoded, err := cookieHandler.Encode(""Credentials"", value); err == nil { cookie := &http.Cookie{ Name: ""Credentials"", Value: encoded, Path: ""/"", } http.SetCookie(w, cookie) } }",True,Go,setCredentials,auth.go,https://github.com/gophergala/sqldump,gophergala,micha-p,2015-01-25 02:26:19+01:00,Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10044,"func clearCredentials(w http.ResponseWriter) { cookie := &http.Cookie{ Name: ""Datasource"", Value: """", Path: ""/"", MaxAge: -1, } http.SetCookie(w, cookie) }" 95,"func loginHandler(w http.ResponseWriter, request *http.Request) { user := request.FormValue(""user"") pass := request.FormValue(""password"") if user != """" && pass != """" { setCredentials(user, pass, w) } http.Redirect(w, request, ""/"", 302) }",True,Go,loginHandler,auth.go,https://github.com/gophergala/sqldump,gophergala,micha-p,2015-01-25 02:26:19+01:00,Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10044,"func setCredentials( w http.ResponseWriter, userName string, pw string, host string, port string) { value := map[string]string{ ""user"": userName, ""passwd"": pw, ""host"": host, ""port"": port, } if encoded, err := cookieHandler.Encode(""Datasource"", value); err == nil { cookie := &http.Cookie{ Name: ""Datasource"", Value: encoded, Path: ""/"", } http.SetCookie(w, cookie) } }" 97,"func dsn(user string, pw string, db string) string { return user + "":"" + pw + ""@tcp("" + host + "":"" + port + "")/"" + db }",True,Go,dsn,aux.go,https://github.com/gophergala/sqldump,gophergala,micha-p,2015-01-25 02:26:19+01:00,Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10044,"func loginHandler(w http.ResponseWriter, request *http.Request) { user := request.FormValue(""user"") pass := request.FormValue(""password"") host := request.FormValue(""host"") port := request.FormValue(""port"") if user != """" && pass != """" { setCredentials(w, user, pass, host, port) } http.Redirect(w, request, ""/"", 302) }" 99,"func dumprecord(w http.ResponseWriter, r *http.Request, parray []string) { database := parray[0] table := parray[1] rec, err := strconv.Atoi(parray[2]) checkY(err) user, pw := getCredentials(r) conn, err := sql.Open(""mysql"", dsn(user, pw, database)) checkY(err) defer conn.Close() statement, err := conn.Prepare(""select * from ?"") checkY(err) rows, err := statement.Query(table) checkY(err) defer rows.Close() columns, err := rows.Columns() checkY(err) raw := make([]interface{}, len(columns)) val := make([]interface{}, len(columns)) for i := range val { raw[i] = &val[i] } var n int = 1 rowLoop: for rows.Next() { if n == rec { err = rows.Scan(raw...) checkY(err) fmt.Fprintln(w, ""

"") for i, col := range val { if col != nil { fmt.Fprintln(w, columns[i], "":"", string(col.([]byte)), ""
"") } } fmt.Fprintln(w, ""

"") break rowLoop } n = n + 1 } }",True,Go,dumprecord,dump.go,https://github.com/gophergala/sqldump,gophergala,micha-p,2015-01-25 02:26:19+01:00,Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10044,"func dsn(user string, pw string, host string, port string, db string) string { return user + "":"" + pw + ""@tcp("" + host + "":"" + port + "")/"" + db }" 100,"func dumpdb(w http.ResponseWriter, r *http.Request, parray []string) { user, pw := getCredentials(r) database := parray[0] conn, err := sql.Open(""mysql"", dsn(user, pw, database)) checkY(err) defer conn.Close() statement, err := conn.Prepare(""show tables"") checkY(err) rows, err := statement.Query() checkY(err) defer rows.Close() var n int = 1 for rows.Next() { var field string rows.Scan(&field) fmt.Fprint(w, linkDeeper(r.URL.Path, field, ""T[""+strconv.Itoa(n)+""]"")) fmt.Fprintln(w, "" "", field, ""
"") n = n + 1 } }",True,Go,dumpdb,dump.go,https://github.com/gophergala/sqldump,gophergala,micha-p,2015-01-25 02:26:19+01:00,Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10044,"func dumprecord(w http.ResponseWriter, r *http.Request, parray []string) { database := parray[0] table := parray[1] rec, err := strconv.Atoi(parray[2]) checkY(err) user, pw, h, p := getCredentials(r) conn, err := sql.Open(""mysql"", dsn(user, pw, h, p, database)) checkY(err) defer conn.Close() statement, err := conn.Prepare(""select * from "" + template.HTMLEscapeString(table)) checkY(err) rows, err := statement.Query() checkY(err) defer rows.Close() columns, err := rows.Columns() checkY(err) raw := make([]interface{}, len(columns)) val := make([]interface{}, len(columns)) for i := range val { raw[i] = &val[i] } var n int = 1 rowLoop: for rows.Next() { if n == rec { err = rows.Scan(raw...) checkY(err) fmt.Fprintln(w, ""

"") for i, col := range val { if col != nil { fmt.Fprintln(w, columns[i], "":"", string(col.([]byte)), ""
"") } } fmt.Fprintln(w, ""

"") break rowLoop } n = n + 1 } }" 103,"func dumptable(w http.ResponseWriter, r *http.Request, parray []string) { user, pw := getCredentials(r) database := parray[0] table := parray[1] conn, err := sql.Open(""mysql"", dsn(user, pw, database)) checkY(err) defer conn.Close() statement, err := conn.Prepare(""select * from ?"") checkY(err) rows, err := statement.Query(table) checkY(err) defer rows.Close() cols, err := rows.Columns() checkY(err) fmt.Fprintln(w, ""

""+""# ""+strings.Join(cols, "" "")+""

"") raw := make([]interface{}, len(cols)) val := make([]interface{}, len(cols)) for i := range val { raw[i] = &val[i] } var n int = 1 for rows.Next() { fmt.Fprint(w, linkDeeper(r.URL.Path, strconv.Itoa(n), strconv.Itoa(n))) err = rows.Scan(raw...) checkY(err) for _, col := range val { if col != nil { fmt.Fprintf(w, ""%s "", string(col.([]byte))) } } fmt.Fprintln(w, ""
"") n = n + 1 } }",True,Go,dumptable,dump.go,https://github.com/gophergala/sqldump,gophergala,micha-p,2015-01-25 02:26:19+01:00,Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10044,"func dumpdb(w http.ResponseWriter, r *http.Request, parray []string) { user, pw, h, p := getCredentials(r) database := parray[0] conn, err := sql.Open(""mysql"", dsn(user, pw, h, p, database)) checkY(err) defer conn.Close() statement, err := conn.Prepare(""show tables"") checkY(err) rows, err := statement.Query() checkY(err) defer rows.Close() var n int = 1 for rows.Next() { var field string rows.Scan(&field) fmt.Fprint(w, linkDeeper(r.URL.Path, field, ""T[""+strconv.Itoa(n)+""]"")) fmt.Fprintln(w, "" "", field, ""
"") n = n + 1 } }" 105,"func home(w http.ResponseWriter, r *http.Request) { user, pw := getCredentials(r) conn, err := sql.Open(""mysql"", dsn(user, pw, database)) checkY(err) defer conn.Close() statement, err := conn.Prepare(""show databases"") checkY(err) rows, err := statement.Query() checkY(err) defer rows.Close() var n int = 1 for rows.Next() { var field string rows.Scan(&field) fmt.Fprint(w, linkDeeper("""", field, ""DB[""+strconv.Itoa(n)+""]"")) fmt.Fprintln(w, "" "", field, ""
"") n = n + 1 } }",True,Go,home,dump.go,https://github.com/gophergala/sqldump,gophergala,micha-p,2015-01-25 02:26:19+01:00,Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10044,"func dumptable(w http.ResponseWriter, r *http.Request, parray []string) { user, pw, h, p := getCredentials(r) database := parray[0] table := parray[1] conn, err := sql.Open(""mysql"", dsn(user, pw, h, p, database)) checkY(err) defer conn.Close() statement, err := conn.Prepare(""select * from "" + template.HTMLEscapeString(table)) checkY(err) rows, err := statement.Query() checkY(err) defer rows.Close() cols, err := rows.Columns() checkY(err) fmt.Fprintln(w, ""

""+""# ""+strings.Join(cols, "" "")+""

"") raw := make([]interface{}, len(cols)) val := make([]interface{}, len(cols)) for i := range val { raw[i] = &val[i] } var n int = 1 for rows.Next() { fmt.Fprint(w, linkDeeper(r.URL.Path, strconv.Itoa(n), strconv.Itoa(n))) err = rows.Scan(raw...) checkY(err) for _, col := range val { if col != nil { fmt.Fprintf(w, ""%s "", string(col.([]byte))) } } fmt.Fprintln(w, ""
"") n = n + 1 } }" 106,"func indexHandler(w http.ResponseWriter, r *http.Request) { u, _ := getCredentials(r) if u != """" { fmt.Fprintln(w, ""

"", u, ""

"") pathHandler(w, r) } else { loginPageHandler(w, r) } }",True,Go,indexHandler,sqldump.go,https://github.com/gophergala/sqldump,gophergala,micha-p,2015-01-25 02:26:19+01:00,Protection against sql injection doesnt work with ? for table. Using HTMLEscapeString instead,CWE-89,Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection'),"The product constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.",https://cwe.mitre.org/data/definitions/89.html,CVE-2015-10044,"func home(w http.ResponseWriter, r *http.Request) { user, pw, h , p := getCredentials(r) conn, err := sql.Open(""mysql"", dsn(user, pw, h, p, database)) checkY(err) defer conn.Close() statement, err := conn.Prepare(""show databases"") checkY(err) rows, err := statement.Query() checkY(err) defer rows.Close() var n int = 1 for rows.Next() { var field string rows.Scan(&field) fmt.Fprint(w, linkDeeper("""", field, ""DB[""+strconv.Itoa(n)+""]"")) fmt.Fprintln(w, "" "", field, ""
"") n = n + 1 } }" 108,"func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how string) error { convert := func(path string, fi os.FileInfo, err error) (e error) { uid, gid, err := GetOwner(path) if err != nil { return err } var newuid, newgid int switch how { case ""in"": newuid, newgid = set.ShiftIntoNs(uid, gid) case ""out"": newuid, newgid = set.ShiftFromNs(uid, gid) } if testmode { fmt.Printf(""I would shift %q to %d %d\n"", path, newuid, newgid) } else { err = os.Lchown(path, int(newuid), int(newgid)) if err == nil { m := fi.Mode() if m&os.ModeSymlink == 0 { err = os.Chmod(path, m) if err != nil { fmt.Printf(""Error resetting mode on %q, continuing\n"", path) } } } } return nil } if !PathExists(dir) { return fmt.Errorf(""No such file or directory: %q"", dir) } return filepath.Walk(dir, convert) }",True,Go,doUidshiftIntoContainer,idmapset_linux.go,https://github.com/lxc/lxd,lxc,Stéphane Graber,2015-10-04 16:58:56+01:00,"CVE-2015-1340: Fix race condition between fchown and chmod in idmapset Shifting a container filesystem in an environment where a user can modify the container's filesystem as it's being shifted (for example if the LXD server's / was shared over the network) would allow them to make use of a race (TOCTOU) between the chown and chmod operations, allowing for an arbitrary path to be chmod-ed rather than the planned container path. The fix is to use a file descriptor to the entry being processed, validate that the entry itself is sane and then interact with the fd. This is CVE-2015-1340 Reported-by: Seth Arnold Signed-off-by: Stéphane Graber ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2015-1340,"func indexHandler(w http.ResponseWriter, r *http.Request) { user , _ , host , port := getCredentials(r) if user != """" { fmt.Fprintln(w, ""

"", user + ""@"" + host + "":"" + port, ""

"") pathHandler(w, r) } else { loginPageHandler(w, r) } }" 112,"func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, messageSockPair, logFilePair filePair) (*setnsProcess, error) { cmd.Env = append(cmd.Env, ""_LIBCONTAINER_INITTYPE=""+string(initSetns)) state, err := c.currentState() if err != nil { return nil, fmt.Errorf(""unable to get container state: %w"", err) } data, err := c.bootstrapData(0, state.NamespacePaths) if err != nil { return nil, err } proc := &setnsProcess{ cmd: cmd, cgroupPaths: state.CgroupPaths, rootlessCgroups: c.config.RootlessCgroups, intelRdtPath: state.IntelRdtPath, messageSockPair: messageSockPair, logFilePair: logFilePair, manager: c.cgroupManager, config: c.newInitConfig(p), process: p, bootstrapData: data, initProcessPid: state.InitProcessPid, } if len(p.SubCgroupPaths) > 0 { if add, ok := p.SubCgroupPaths[""""]; ok { for k := range proc.cgroupPaths { proc.cgroupPaths[k] = path.Join(proc.cgroupPaths[k], add) } proc.initProcessPid = 0 } else { for ctrl, add := range p.SubCgroupPaths { if val, ok := proc.cgroupPaths[ctrl]; ok { proc.cgroupPaths[ctrl] = path.Join(val, add) } else { return nil, fmt.Errorf(""unknown controller %s in SubCgroupPaths"", ctrl) } } } } return proc, nil }",True,Go,newSetnsProcess,container_linux.go,https://github.com/opencontainers/runc,opencontainers,Rodrigo Campos,2021-10-12 15:13:45+02:00,"Open bind mount sources from the host userns The source of the bind mount might not be accessible in a different user namespace because a component of the source path might not be traversed under the users and groups mapped inside the user namespace. This caused errors such as the following: # time=""2020-06-22T13:48:26Z"" level=error msg=""container_linux.go:367: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:58: mounting \""/tmp/busyboxtest/source-inaccessible/dir\"" to rootfs at \""/tmp/inaccessible\"" caused: stat /tmp/busyboxtest/source-inaccessible/dir: permission denied"" To solve this problem, this patch performs the following: 1. in nsexec.c, it opens the source path in the host userns (so we have the right permissions to open it) but in the container mntns (so the kernel cross mntns mount check let us mount it later: https://github.com/torvalds/linux/blob/v5.8/fs/namespace.c#L2312). 2. in nsexec.c, it passes the file descriptors of the source to the child process with SCM_RIGHTS. 3. In runc-init in Golang, it finishes the mounts while inside the userns even without access to the some components of the source paths. Passing the fds with SCM_RIGHTS is necessary because once the child process is in the container mntns, it is already in the container userns so it cannot temporarily join the host mntns. This patch uses the existing mechanism with _LIBCONTAINER_* environment variables to pass the file descriptors from runc to runc init. This patch uses the existing mechanism with the Netlink-style bootstrap to pass information about the list of source mounts to nsexec.c. Rootless containers don't use this bind mount sources fdpassing mechanism because we can't setns() to the target mntns in a rootless container (we don't have the privileges when we are in the host userns). This patch takes care of using O_CLOEXEC on mount fds, and close them early. Fixes: #2484. Signed-off-by: Alban Crequy Signed-off-by: Rodrigo Campos Co-authored-by: Rodrigo Campos ",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2021-43784,"func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how string) error { dir = strings.TrimRight(dir, ""/"") convert := func(path string, fi os.FileInfo, err error) (e error) { uid, gid, err := GetOwner(path) if err != nil { return err } var newuid, newgid int switch how { case ""in"": newuid, newgid = set.ShiftIntoNs(uid, gid) case ""out"": newuid, newgid = set.ShiftFromNs(uid, gid) } if testmode { fmt.Printf(""I would shift %q to %d %d\n"", path, newuid, newgid) } else { err = ShiftOwner(dir, path, int(newuid), int(newgid)) if err != nil { return err } } return nil } if !PathExists(dir) { return fmt.Errorf(""No such file or directory: %q"", dir) } return filepath.Walk(dir, convert) }" 113,"func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, messageSockPair, logFilePair filePair) (*initProcess, error) { cmd.Env = append(cmd.Env, ""_LIBCONTAINER_INITTYPE=""+string(initStandard)) nsMaps := make(map[configs.NamespaceType]string) for _, ns := range c.config.Namespaces { if ns.Path != """" { nsMaps[ns.Type] = ns.Path } } _, sharePidns := nsMaps[configs.NEWPID] data, err := c.bootstrapData(c.config.Namespaces.CloneFlags(), nsMaps) if err != nil { return nil, err } init := &initProcess{ cmd: cmd, messageSockPair: messageSockPair, logFilePair: logFilePair, manager: c.cgroupManager, intelRdtManager: c.intelRdtManager, config: c.newInitConfig(p), container: c, process: p, bootstrapData: data, sharePidns: sharePidns, } c.initProcess = init return init, nil }",True,Go,newInitProcess,container_linux.go,https://github.com/opencontainers/runc,opencontainers,Rodrigo Campos,2021-10-12 15:13:45+02:00,"Open bind mount sources from the host userns The source of the bind mount might not be accessible in a different user namespace because a component of the source path might not be traversed under the users and groups mapped inside the user namespace. This caused errors such as the following: # time=""2020-06-22T13:48:26Z"" level=error msg=""container_linux.go:367: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:58: mounting \""/tmp/busyboxtest/source-inaccessible/dir\"" to rootfs at \""/tmp/inaccessible\"" caused: stat /tmp/busyboxtest/source-inaccessible/dir: permission denied"" To solve this problem, this patch performs the following: 1. in nsexec.c, it opens the source path in the host userns (so we have the right permissions to open it) but in the container mntns (so the kernel cross mntns mount check let us mount it later: https://github.com/torvalds/linux/blob/v5.8/fs/namespace.c#L2312). 2. in nsexec.c, it passes the file descriptors of the source to the child process with SCM_RIGHTS. 3. In runc-init in Golang, it finishes the mounts while inside the userns even without access to the some components of the source paths. Passing the fds with SCM_RIGHTS is necessary because once the child process is in the container mntns, it is already in the container userns so it cannot temporarily join the host mntns. This patch uses the existing mechanism with _LIBCONTAINER_* environment variables to pass the file descriptors from runc to runc init. This patch uses the existing mechanism with the Netlink-style bootstrap to pass information about the list of source mounts to nsexec.c. Rootless containers don't use this bind mount sources fdpassing mechanism because we can't setns() to the target mntns in a rootless container (we don't have the privileges when we are in the host userns). This patch takes care of using O_CLOEXEC on mount fds, and close them early. Fixes: #2484. Signed-off-by: Alban Crequy Signed-off-by: Rodrigo Campos Co-authored-by: Rodrigo Campos ",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2021-43784,"func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, messageSockPair, logFilePair filePair) (*setnsProcess, error) { cmd.Env = append(cmd.Env, ""_LIBCONTAINER_INITTYPE=""+string(initSetns)) state, err := c.currentState() if err != nil { return nil, fmt.Errorf(""unable to get container state: %w"", err) } data, err := c.bootstrapData(0, state.NamespacePaths, initSetns) if err != nil { return nil, err } proc := &setnsProcess{ cmd: cmd, cgroupPaths: state.CgroupPaths, rootlessCgroups: c.config.RootlessCgroups, intelRdtPath: state.IntelRdtPath, messageSockPair: messageSockPair, logFilePair: logFilePair, manager: c.cgroupManager, config: c.newInitConfig(p), process: p, bootstrapData: data, initProcessPid: state.InitProcessPid, } if len(p.SubCgroupPaths) > 0 { if add, ok := p.SubCgroupPaths[""""]; ok { for k := range proc.cgroupPaths { proc.cgroupPaths[k] = path.Join(proc.cgroupPaths[k], add) } proc.initProcessPid = 0 } else { for ctrl, add := range p.SubCgroupPaths { if val, ok := proc.cgroupPaths[ctrl]; ok { proc.cgroupPaths[ctrl] = path.Join(val, add) } else { return nil, fmt.Errorf(""unknown controller %s in SubCgroupPaths"", ctrl) } } } } return proc, nil }" 115,"func (c *linuxContainer) makeCriuRestoreMountpoints(m *configs.Mount) error { switch m.Device { case ""cgroup"": return nil case ""bind"": if err := prepareBindMount(m, c.config.Rootfs); err != nil { return err } default: dest, err := securejoin.SecureJoin(c.config.Rootfs, m.Destination) if err != nil { return err } if err := checkProcMount(c.config.Rootfs, dest, """"); err != nil { return err } if err := os.MkdirAll(dest, 0o755); err != nil { return err } } return nil }",True,Go,makeCriuRestoreMountpoints,container_linux.go,https://github.com/opencontainers/runc,opencontainers,Rodrigo Campos,2021-10-12 15:13:45+02:00,"Open bind mount sources from the host userns The source of the bind mount might not be accessible in a different user namespace because a component of the source path might not be traversed under the users and groups mapped inside the user namespace. This caused errors such as the following: # time=""2020-06-22T13:48:26Z"" level=error msg=""container_linux.go:367: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:58: mounting \""/tmp/busyboxtest/source-inaccessible/dir\"" to rootfs at \""/tmp/inaccessible\"" caused: stat /tmp/busyboxtest/source-inaccessible/dir: permission denied"" To solve this problem, this patch performs the following: 1. in nsexec.c, it opens the source path in the host userns (so we have the right permissions to open it) but in the container mntns (so the kernel cross mntns mount check let us mount it later: https://github.com/torvalds/linux/blob/v5.8/fs/namespace.c#L2312). 2. in nsexec.c, it passes the file descriptors of the source to the child process with SCM_RIGHTS. 3. In runc-init in Golang, it finishes the mounts while inside the userns even without access to the some components of the source paths. Passing the fds with SCM_RIGHTS is necessary because once the child process is in the container mntns, it is already in the container userns so it cannot temporarily join the host mntns. This patch uses the existing mechanism with _LIBCONTAINER_* environment variables to pass the file descriptors from runc to runc init. This patch uses the existing mechanism with the Netlink-style bootstrap to pass information about the list of source mounts to nsexec.c. Rootless containers don't use this bind mount sources fdpassing mechanism because we can't setns() to the target mntns in a rootless container (we don't have the privileges when we are in the host userns). This patch takes care of using O_CLOEXEC on mount fds, and close them early. Fixes: #2484. Signed-off-by: Alban Crequy Signed-off-by: Rodrigo Campos Co-authored-by: Rodrigo Campos ",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2021-43784,"func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, messageSockPair, logFilePair filePair) (*initProcess, error) { cmd.Env = append(cmd.Env, ""_LIBCONTAINER_INITTYPE=""+string(initStandard)) nsMaps := make(map[configs.NamespaceType]string) for _, ns := range c.config.Namespaces { if ns.Path != """" { nsMaps[ns.Type] = ns.Path } } _, sharePidns := nsMaps[configs.NEWPID] data, err := c.bootstrapData(c.config.Namespaces.CloneFlags(), nsMaps, initStandard) if err != nil { return nil, err } if c.shouldSendMountSources() { mountFds := make([]int, len(c.config.Mounts)) for i, m := range c.config.Mounts { if !m.IsBind() { mountFds[i] = -1 continue } cmd.ExtraFiles = append(cmd.ExtraFiles, messageSockPair.child) mountFds[i] = stdioFdCount + len(cmd.ExtraFiles) - 1 } mountFdsJson, err := json.Marshal(mountFds) if err != nil { return nil, fmt.Errorf(""Error creating _LIBCONTAINER_MOUNT_FDS: %w"", err) } cmd.Env = append(cmd.Env, ""_LIBCONTAINER_MOUNT_FDS=""+string(mountFdsJson), ) } init := &initProcess{ cmd: cmd, messageSockPair: messageSockPair, logFilePair: logFilePair, manager: c.cgroupManager, intelRdtManager: c.intelRdtManager, config: c.newInitConfig(p), container: c, process: p, bootstrapData: data, sharePidns: sharePidns, } c.initProcess = init return init, nil }" 119,"func newContainerInit(t initType, pipe *os.File, consoleSocket *os.File, fifoFd, logFd int) (initer, error) { var config *initConfig if err := json.NewDecoder(pipe).Decode(&config); err != nil { return nil, err } if err := populateProcessEnvironment(config.Env); err != nil { return nil, err } switch t { case initSetns: return &linuxSetnsInit{ pipe: pipe, consoleSocket: consoleSocket, config: config, logFd: logFd, }, nil case initStandard: return &linuxStandardInit{ pipe: pipe, consoleSocket: consoleSocket, parentPid: unix.Getppid(), config: config, fifoFd: fifoFd, logFd: logFd, }, nil } return nil, fmt.Errorf(""unknown init type %q"", t) }",True,Go,newContainerInit,init_linux.go,https://github.com/opencontainers/runc,opencontainers,Rodrigo Campos,2021-10-12 15:13:45+02:00,"Open bind mount sources from the host userns The source of the bind mount might not be accessible in a different user namespace because a component of the source path might not be traversed under the users and groups mapped inside the user namespace. This caused errors such as the following: # time=""2020-06-22T13:48:26Z"" level=error msg=""container_linux.go:367: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:58: mounting \""/tmp/busyboxtest/source-inaccessible/dir\"" to rootfs at \""/tmp/inaccessible\"" caused: stat /tmp/busyboxtest/source-inaccessible/dir: permission denied"" To solve this problem, this patch performs the following: 1. in nsexec.c, it opens the source path in the host userns (so we have the right permissions to open it) but in the container mntns (so the kernel cross mntns mount check let us mount it later: https://github.com/torvalds/linux/blob/v5.8/fs/namespace.c#L2312). 2. in nsexec.c, it passes the file descriptors of the source to the child process with SCM_RIGHTS. 3. In runc-init in Golang, it finishes the mounts while inside the userns even without access to the some components of the source paths. Passing the fds with SCM_RIGHTS is necessary because once the child process is in the container mntns, it is already in the container userns so it cannot temporarily join the host mntns. This patch uses the existing mechanism with _LIBCONTAINER_* environment variables to pass the file descriptors from runc to runc init. This patch uses the existing mechanism with the Netlink-style bootstrap to pass information about the list of source mounts to nsexec.c. Rootless containers don't use this bind mount sources fdpassing mechanism because we can't setns() to the target mntns in a rootless container (we don't have the privileges when we are in the host userns). This patch takes care of using O_CLOEXEC on mount fds, and close them early. Fixes: #2484. Signed-off-by: Alban Crequy Signed-off-by: Rodrigo Campos Co-authored-by: Rodrigo Campos ",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2021-43784,"func (c *linuxContainer) makeCriuRestoreMountpoints(m *configs.Mount) error { switch m.Device { case ""cgroup"": return nil case ""bind"": if err := prepareBindMount(m, c.config.Rootfs, nil); err != nil { return err } default: dest, err := securejoin.SecureJoin(c.config.Rootfs, m.Destination) if err != nil { return err } if err := checkProcMount(c.config.Rootfs, dest, """"); err != nil { return err } if err := os.MkdirAll(dest, 0o755); err != nil { return err } } return nil }" 124,"return utils.WithProcfd(rootfs, m.Destination, func(procfd string) error { return mount(m.Source, m.Destination, procfd, m.Device, uintptr(m.Flags|unix.MS_REMOUNT), """") })",True,Go,error,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Rodrigo Campos,2021-10-12 15:13:45+02:00,"Open bind mount sources from the host userns The source of the bind mount might not be accessible in a different user namespace because a component of the source path might not be traversed under the users and groups mapped inside the user namespace. This caused errors such as the following: # time=""2020-06-22T13:48:26Z"" level=error msg=""container_linux.go:367: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:58: mounting \""/tmp/busyboxtest/source-inaccessible/dir\"" to rootfs at \""/tmp/inaccessible\"" caused: stat /tmp/busyboxtest/source-inaccessible/dir: permission denied"" To solve this problem, this patch performs the following: 1. in nsexec.c, it opens the source path in the host userns (so we have the right permissions to open it) but in the container mntns (so the kernel cross mntns mount check let us mount it later: https://github.com/torvalds/linux/blob/v5.8/fs/namespace.c#L2312). 2. in nsexec.c, it passes the file descriptors of the source to the child process with SCM_RIGHTS. 3. In runc-init in Golang, it finishes the mounts while inside the userns even without access to the some components of the source paths. Passing the fds with SCM_RIGHTS is necessary because once the child process is in the container mntns, it is already in the container userns so it cannot temporarily join the host mntns. This patch uses the existing mechanism with _LIBCONTAINER_* environment variables to pass the file descriptors from runc to runc init. This patch uses the existing mechanism with the Netlink-style bootstrap to pass information about the list of source mounts to nsexec.c. Rootless containers don't use this bind mount sources fdpassing mechanism because we can't setns() to the target mntns in a rootless container (we don't have the privileges when we are in the host userns). This patch takes care of using O_CLOEXEC on mount fds, and close them early. Fixes: #2484. Signed-off-by: Alban Crequy Signed-off-by: Rodrigo Campos Co-authored-by: Rodrigo Campos ",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2021-43784,"func newContainerInit(t initType, pipe *os.File, consoleSocket *os.File, fifoFd, logFd int, mountFds []int) (initer, error) { var config *initConfig if err := json.NewDecoder(pipe).Decode(&config); err != nil { return nil, err } if err := populateProcessEnvironment(config.Env); err != nil { return nil, err } switch t { case initSetns: if mountFds != nil { return nil, errors.New(""mountFds must be nil. Can't mount while doing runc exec."") } return &linuxSetnsInit{ pipe: pipe, consoleSocket: consoleSocket, config: config, logFd: logFd, }, nil case initStandard: return &linuxStandardInit{ pipe: pipe, consoleSocket: consoleSocket, parentPid: unix.Getppid(), config: config, fifoFd: fifoFd, logFd: logFd, mountFds: mountFds, }, nil } return nil, fmt.Errorf(""unknown init type %q"", t) }" 126,"func prepareBindMount(m *configs.Mount, rootfs string) error { stat, err := os.Stat(m.Source) if err != nil { return err } var dest string if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil { return err } if err := checkProcMount(rootfs, dest, m.Source); err != nil { return err } if err := createIfNotExists(dest, stat.IsDir()); err != nil { return err } return nil }",True,Go,prepareBindMount,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Rodrigo Campos,2021-10-12 15:13:45+02:00,"Open bind mount sources from the host userns The source of the bind mount might not be accessible in a different user namespace because a component of the source path might not be traversed under the users and groups mapped inside the user namespace. This caused errors such as the following: # time=""2020-06-22T13:48:26Z"" level=error msg=""container_linux.go:367: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:58: mounting \""/tmp/busyboxtest/source-inaccessible/dir\"" to rootfs at \""/tmp/inaccessible\"" caused: stat /tmp/busyboxtest/source-inaccessible/dir: permission denied"" To solve this problem, this patch performs the following: 1. in nsexec.c, it opens the source path in the host userns (so we have the right permissions to open it) but in the container mntns (so the kernel cross mntns mount check let us mount it later: https://github.com/torvalds/linux/blob/v5.8/fs/namespace.c#L2312). 2. in nsexec.c, it passes the file descriptors of the source to the child process with SCM_RIGHTS. 3. In runc-init in Golang, it finishes the mounts while inside the userns even without access to the some components of the source paths. Passing the fds with SCM_RIGHTS is necessary because once the child process is in the container mntns, it is already in the container userns so it cannot temporarily join the host mntns. This patch uses the existing mechanism with _LIBCONTAINER_* environment variables to pass the file descriptors from runc to runc init. This patch uses the existing mechanism with the Netlink-style bootstrap to pass information about the list of source mounts to nsexec.c. Rootless containers don't use this bind mount sources fdpassing mechanism because we can't setns() to the target mntns in a rootless container (we don't have the privileges when we are in the host userns). This patch takes care of using O_CLOEXEC on mount fds, and close them early. Fixes: #2484. Signed-off-by: Alban Crequy Signed-off-by: Rodrigo Campos Co-authored-by: Rodrigo Campos ",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2021-43784,"return utils.WithProcfd(rootfs, m.Destination, func(procfd string) error { return mount(source, m.Destination, procfd, m.Device, uintptr(m.Flags|unix.MS_REMOUNT), """") })" 127,"func prepareRootfs(pipe io.ReadWriter, iConfig *initConfig) (err error) { config := iConfig.Config if err := prepareRoot(config); err != nil { return fmt.Errorf(""error preparing rootfs: %w"", err) } mountConfig := &mountConfig{ root: config.Rootfs, label: config.MountLabel, cgroup2Path: iConfig.Cgroup2Path, rootlessCgroups: iConfig.RootlessCgroups, cgroupns: config.Namespaces.Contains(configs.NEWCGROUP), } setupDev := needsSetupDev(config) for _, m := range config.Mounts { for _, precmd := range m.PremountCmds { if err := mountCmd(precmd); err != nil { return fmt.Errorf(""error running premount command: %w"", err) } } if err := mountToRootfs(m, mountConfig); err != nil { return fmt.Errorf(""error mounting %q to rootfs at %q: %w"", m.Source, m.Destination, err) } for _, postcmd := range m.PostmountCmds { if err := mountCmd(postcmd); err != nil { return fmt.Errorf(""error running postmount command: %w"", err) } } } if setupDev { if err := createDevices(config); err != nil { return fmt.Errorf(""error creating device nodes: %w"", err) } if err := setupPtmx(config); err != nil { return fmt.Errorf(""error setting up ptmx: %w"", err) } if err := setupDevSymlinks(config.Rootfs); err != nil { return fmt.Errorf(""error setting up /dev symlinks: %w"", err) } } if err := syncParentHooks(pipe); err != nil { return err } if err := unix.Chdir(config.Rootfs); err != nil { return &os.PathError{Op: ""chdir"", Path: config.Rootfs, Err: err} } s := iConfig.SpecState s.Pid = unix.Getpid() s.Status = specs.StateCreating if err := iConfig.Config.Hooks[configs.CreateContainer].RunHooks(s); err != nil { return err } if config.NoPivotRoot { err = msMoveRoot(config.Rootfs) } else if config.Namespaces.Contains(configs.NEWNS) { err = pivotRoot(config.Rootfs) } else { err = chroot() } if err != nil { return fmt.Errorf(""error jailing process inside rootfs: %w"", err) } if setupDev { if err := reOpenDevNull(); err != nil { return fmt.Errorf(""error reopening /dev/null inside container: %w"", err) } } if cwd := iConfig.Cwd; cwd != """" { if err := os.MkdirAll(cwd, 0o755); err != nil { return err } } return nil }",True,Go,prepareRootfs,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Rodrigo Campos,2021-10-12 15:13:45+02:00,"Open bind mount sources from the host userns The source of the bind mount might not be accessible in a different user namespace because a component of the source path might not be traversed under the users and groups mapped inside the user namespace. This caused errors such as the following: # time=""2020-06-22T13:48:26Z"" level=error msg=""container_linux.go:367: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:58: mounting \""/tmp/busyboxtest/source-inaccessible/dir\"" to rootfs at \""/tmp/inaccessible\"" caused: stat /tmp/busyboxtest/source-inaccessible/dir: permission denied"" To solve this problem, this patch performs the following: 1. in nsexec.c, it opens the source path in the host userns (so we have the right permissions to open it) but in the container mntns (so the kernel cross mntns mount check let us mount it later: https://github.com/torvalds/linux/blob/v5.8/fs/namespace.c#L2312). 2. in nsexec.c, it passes the file descriptors of the source to the child process with SCM_RIGHTS. 3. In runc-init in Golang, it finishes the mounts while inside the userns even without access to the some components of the source paths. Passing the fds with SCM_RIGHTS is necessary because once the child process is in the container mntns, it is already in the container userns so it cannot temporarily join the host mntns. This patch uses the existing mechanism with _LIBCONTAINER_* environment variables to pass the file descriptors from runc to runc init. This patch uses the existing mechanism with the Netlink-style bootstrap to pass information about the list of source mounts to nsexec.c. Rootless containers don't use this bind mount sources fdpassing mechanism because we can't setns() to the target mntns in a rootless container (we don't have the privileges when we are in the host userns). This patch takes care of using O_CLOEXEC on mount fds, and close them early. Fixes: #2484. Signed-off-by: Alban Crequy Signed-off-by: Rodrigo Campos Co-authored-by: Rodrigo Campos ",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2021-43784,"func prepareBindMount(m *configs.Mount, rootfs string, mountFd *int) error { source := m.Source if mountFd != nil { source = ""/proc/self/fd/"" + strconv.Itoa(*mountFd) } stat, err := os.Stat(source) if err != nil { return err } var dest string if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil { return err } if err := checkProcMount(rootfs, dest, source); err != nil { return err } if err := createIfNotExists(dest, stat.IsDir()); err != nil { return err } return nil }" 129,"func mountToRootfs(m *configs.Mount, c *mountConfig) error { rootfs := c.root mountLabel := c.label dest, err := securejoin.SecureJoin(rootfs, m.Destination) if err != nil { return err } switch m.Device { case ""proc"", ""sysfs"": if fi, err := os.Lstat(dest); err != nil { if !os.IsNotExist(err) { return err } } else if fi.Mode()&os.ModeDir == 0 { return fmt.Errorf(""filesystem %q must be mounted on ordinary directory"", m.Device) } if err := os.MkdirAll(dest, 0o755); err != nil { return err } return mountPropagate(m, rootfs, """") case ""mqueue"": if err := os.MkdirAll(dest, 0o755); err != nil { return err } if err := mountPropagate(m, rootfs, """"); err != nil { return err } return label.SetFileLabel(dest, mountLabel) case ""tmpfs"": stat, err := os.Stat(dest) if err != nil { if err := os.MkdirAll(dest, 0o755); err != nil { return err } } if m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP { err = doTmpfsCopyUp(m, rootfs, mountLabel) } else { err = mountPropagate(m, rootfs, mountLabel) } if err != nil { return err } if stat != nil { if err = os.Chmod(dest, stat.Mode()); err != nil { return err } } if m.Flags&unix.MS_RDONLY != 0 { if err := remount(m, rootfs); err != nil { return err } } return nil case ""bind"": if err := prepareBindMount(m, rootfs); err != nil { return err } if err := mountPropagate(m, rootfs, mountLabel); err != nil { return err } if m.Flags&^(unix.MS_REC|unix.MS_REMOUNT|unix.MS_BIND) != 0 { if err := remount(m, rootfs); err != nil { return err } } if m.Relabel != """" { if err := label.Validate(m.Relabel); err != nil { return err } shared := label.IsShared(m.Relabel) if err := label.Relabel(m.Source, mountLabel, shared); err != nil { return err } } case ""cgroup"": if cgroups.IsCgroup2UnifiedMode() { return mountCgroupV2(m, c) } return mountCgroupV1(m, c) default: if err := checkProcMount(rootfs, dest, m.Source); err != nil { return err } if err := os.MkdirAll(dest, 0o755); err != nil { return err } return mountPropagate(m, rootfs, mountLabel) } return nil }",True,Go,mountToRootfs,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Rodrigo Campos,2021-10-12 15:13:45+02:00,"Open bind mount sources from the host userns The source of the bind mount might not be accessible in a different user namespace because a component of the source path might not be traversed under the users and groups mapped inside the user namespace. This caused errors such as the following: # time=""2020-06-22T13:48:26Z"" level=error msg=""container_linux.go:367: starting container process caused: process_linux.go:459: container init caused: rootfs_linux.go:58: mounting \""/tmp/busyboxtest/source-inaccessible/dir\"" to rootfs at \""/tmp/inaccessible\"" caused: stat /tmp/busyboxtest/source-inaccessible/dir: permission denied"" To solve this problem, this patch performs the following: 1. in nsexec.c, it opens the source path in the host userns (so we have the right permissions to open it) but in the container mntns (so the kernel cross mntns mount check let us mount it later: https://github.com/torvalds/linux/blob/v5.8/fs/namespace.c#L2312). 2. in nsexec.c, it passes the file descriptors of the source to the child process with SCM_RIGHTS. 3. In runc-init in Golang, it finishes the mounts while inside the userns even without access to the some components of the source paths. Passing the fds with SCM_RIGHTS is necessary because once the child process is in the container mntns, it is already in the container userns so it cannot temporarily join the host mntns. This patch uses the existing mechanism with _LIBCONTAINER_* environment variables to pass the file descriptors from runc to runc init. This patch uses the existing mechanism with the Netlink-style bootstrap to pass information about the list of source mounts to nsexec.c. Rootless containers don't use this bind mount sources fdpassing mechanism because we can't setns() to the target mntns in a rootless container (we don't have the privileges when we are in the host userns). This patch takes care of using O_CLOEXEC on mount fds, and close them early. Fixes: #2484. Signed-off-by: Alban Crequy Signed-off-by: Rodrigo Campos Co-authored-by: Rodrigo Campos ",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2021-43784,"func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) { tmpdir, err := prepareTmp(""/tmp"") if err != nil { return fmt.Errorf(""tmpcopyup: failed to setup tmpdir: %w"", err) } defer cleanupTmp(tmpdir) tmpDir, err := ioutil.TempDir(tmpdir, ""runctmpdir"") if err != nil { return fmt.Errorf(""tmpcopyup: failed to create tmpdir: %w"", err) } defer os.RemoveAll(tmpDir) oldDest := m.Destination m.Destination = tmpDir err = mountPropagate(m, ""/"", mountLabel, nil) m.Destination = oldDest if err != nil { return err } defer func() { if Err != nil { if err := unmount(tmpDir, unix.MNT_DETACH); err != nil { logrus.Warnf(""tmpcopyup: %v"", err) } } }() return utils.WithProcfd(rootfs, m.Destination, func(procfd string) (Err error) { if err := fileutils.CopyDirectory(procfd+""/"", tmpDir); err != nil { return fmt.Errorf(""tmpcopyup: failed to copy %s to %s (%s): %w"", m.Destination, procfd, tmpDir, err) } if err := mount(tmpDir, m.Destination, procfd, """", unix.MS_MOVE, """"); err != nil { return fmt.Errorf(""tmpcopyup: failed to move mount: %w"", err) } return nil }) }" 136,"func (c *linuxContainer) makeCriuRestoreMountpoints(m *configs.Mount) error { switch m.Device { case ""cgroup"": return nil case ""bind"": if err := prepareBindMount(m, c.config.Rootfs); err != nil { return err } default: dest, err := securejoin.SecureJoin(c.config.Rootfs, m.Destination) if err != nil { return err } if err := checkProcMount(c.config.Rootfs, dest, """"); err != nil { return err } m.Destination = dest if err := os.MkdirAll(dest, 0755); err != nil { return err } } return nil }",True,Go,makeCriuRestoreMountpoints,container_linux.go,https://github.com/opencontainers/runc,opencontainers,Aleksa Sarai,2021-05-19 16:58:35+10:00,"rootfs: add mount destination validation Because the target of a mount is inside a container (which may be a volume that is shared with another container), there exists a race condition where the target of the mount may change to a path containing a symlink after we have sanitised the path -- resulting in us inadvertently mounting the path outside of the container. This is not immediately useful because we are in a mount namespace with MS_SLAVE mount propagation applied to ""/"", so we cannot mount on top of host paths in the host namespace. However, if any subsequent mountpoints in the configuration use a subdirectory of that host path as a source, those subsequent mounts will use an attacker-controlled source path (resolved within the host rootfs) -- allowing the bind-mounting of ""/"" into the container. While arguably configuration issues like this are not entirely within runc's threat model, within the context of Kubernetes (and possibly other container managers that provide semi-arbitrary container creation privileges to untrusted users) this is a legitimate issue. Since we cannot block mounting from the host into the container, we need to block the first stage of this attack (mounting onto a path outside the container). The long-term plan to solve this would be to migrate to libpathrs, but as a stop-gap we implement libpathrs-like path verification through readlink(/proc/self/fd/$n) and then do mount operations through the procfd once it's been verified to be inside the container. The target could move after we've checked it, but if it is inside the container then we can assume that it is safe for the same reason that libpathrs operations would be safe. A slight wrinkle is the ""copyup"" functionality we provide for tmpfs, which is the only case where we want to do a mount on the host filesystem. To facilitate this, I split out the copy-up functionality entirely so that the logic isn't interspersed with the regular tmpfs logic. In addition, all dependencies on m.Destination being overwritten have been removed since that pattern was just begging to be a source of more mount-target bugs (we do still have to modify m.Destination for tmpfs-copyup but we only do it temporarily). Fixes: CVE-2021-30465 Reported-by: Etienne Champetier Co-authored-by: Noah Meyerhans Reviewed-by: Samuel Karp Reviewed-by: Kir Kolyshkin (@kolyshkin) Reviewed-by: Akihiro Suda Signed-off-by: Aleksa Sarai ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2021-30465,"users, err := ParsePasswdFilter(passwd, func(u User) bool { if userArg == """" { return u.Uid == user.Uid } if uidErr == nil { return uidArg == u.Uid } return u.Name == userArg })" 137,"func (c *linuxContainer) prepareCriuRestoreMounts(mounts []*configs.Mount) error { tmpfs := []string{} for _, m := range mounts { switch m.Device { case ""tmpfs"": tmpfs = append(tmpfs, m.Destination) } } umounts := []string{} defer func() { for _, u := range umounts { if e := unix.Unmount(u, unix.MNT_DETACH); e != nil { if e != unix.EINVAL { logrus.Warnf(""Error during cleanup unmounting of %q (%v)"", u, e) } } } }() for _, m := range mounts { if !isPathInPrefixList(m.Destination, tmpfs) { if err := c.makeCriuRestoreMountpoints(m); err != nil { return err } if m.Device == ""bind"" { if err := unix.Mount(m.Source, m.Destination, """", unix.MS_BIND|unix.MS_REC, """"); err != nil { return errorsf.Wrapf(err, ""unable to bind mount %q to %q"", m.Source, m.Destination) } umounts = append(umounts, m.Destination) } } } return nil }",True,Go,prepareCriuRestoreMounts,container_linux.go,https://github.com/opencontainers/runc,opencontainers,Aleksa Sarai,2021-05-19 16:58:35+10:00,"rootfs: add mount destination validation Because the target of a mount is inside a container (which may be a volume that is shared with another container), there exists a race condition where the target of the mount may change to a path containing a symlink after we have sanitised the path -- resulting in us inadvertently mounting the path outside of the container. This is not immediately useful because we are in a mount namespace with MS_SLAVE mount propagation applied to ""/"", so we cannot mount on top of host paths in the host namespace. However, if any subsequent mountpoints in the configuration use a subdirectory of that host path as a source, those subsequent mounts will use an attacker-controlled source path (resolved within the host rootfs) -- allowing the bind-mounting of ""/"" into the container. While arguably configuration issues like this are not entirely within runc's threat model, within the context of Kubernetes (and possibly other container managers that provide semi-arbitrary container creation privileges to untrusted users) this is a legitimate issue. Since we cannot block mounting from the host into the container, we need to block the first stage of this attack (mounting onto a path outside the container). The long-term plan to solve this would be to migrate to libpathrs, but as a stop-gap we implement libpathrs-like path verification through readlink(/proc/self/fd/$n) and then do mount operations through the procfd once it's been verified to be inside the container. The target could move after we've checked it, but if it is inside the container then we can assume that it is safe for the same reason that libpathrs operations would be safe. A slight wrinkle is the ""copyup"" functionality we provide for tmpfs, which is the only case where we want to do a mount on the host filesystem. To facilitate this, I split out the copy-up functionality entirely so that the logic isn't interspersed with the regular tmpfs logic. In addition, all dependencies on m.Destination being overwritten have been removed since that pattern was just begging to be a source of more mount-target bugs (we do still have to modify m.Destination for tmpfs-copyup but we only do it temporarily). Fixes: CVE-2021-30465 Reported-by: Etienne Champetier Co-authored-by: Noah Meyerhans Reviewed-by: Samuel Karp Reviewed-by: Kir Kolyshkin (@kolyshkin) Reviewed-by: Akihiro Suda Signed-off-by: Aleksa Sarai ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2021-30465,"func mountToRootfs(m *configs.Mount, c *mountConfig) error { rootfs := c.root mountLabel := c.label dest, err := securejoin.SecureJoin(rootfs, m.Destination) if err != nil { return err } switch m.Device { case ""proc"", ""sysfs"": if fi, err := os.Lstat(dest); err != nil { if !os.IsNotExist(err) { return err } } else if fi.Mode()&os.ModeDir == 0 { return fmt.Errorf(""filesystem %q must be mounted on ordinary directory"", m.Device) } if err := os.MkdirAll(dest, 0755); err != nil { return err } return mountPropagate(m, rootfs, """") case ""mqueue"": if err := os.MkdirAll(dest, 0755); err != nil { return err } if err := mountPropagate(m, rootfs, """"); err != nil { return err } return label.SetFileLabel(dest, mountLabel) case ""tmpfs"": stat, err := os.Stat(dest) if err != nil { if err := os.MkdirAll(dest, 0755); err != nil { return err } } if m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP { err = doTmpfsCopyUp(m, rootfs, mountLabel) } else { err = mountPropagate(m, rootfs, mountLabel) } if err != nil { return err } if stat != nil { if err = os.Chmod(dest, stat.Mode()); err != nil { return err } } if m.Flags&unix.MS_RDONLY != 0 { if err := remount(m, rootfs); err != nil { return err } } return nil case ""bind"": if err := prepareBindMount(m, rootfs); err != nil { return err } if err := mountPropagate(m, rootfs, mountLabel); err != nil { return err } if m.Flags&^(unix.MS_REC|unix.MS_REMOUNT|unix.MS_BIND) != 0 { if err := remount(m, rootfs); err != nil { return err } } if m.Relabel != """" { if err := label.Validate(m.Relabel); err != nil { return err } shared := label.IsShared(m.Relabel) if err := label.Relabel(m.Source, mountLabel, shared); err != nil { return err } } case ""cgroup"": if cgroups.IsCgroup2UnifiedMode() { return mountCgroupV2(m, c) } return mountCgroupV1(m, c) default: if err := checkProcMount(rootfs, dest, m.Source); err != nil { return err } if err := os.MkdirAll(dest, 0755); err != nil { return err } return mountPropagate(m, rootfs, mountLabel) } return nil }" 139,"func remount(m *configs.Mount, rootfs string) error { var ( dest = m.Destination ) if !strings.HasPrefix(dest, rootfs) { dest = filepath.Join(rootfs, dest) } return unix.Mount(m.Source, dest, m.Device, uintptr(m.Flags|unix.MS_REMOUNT), """") }",True,Go,remount,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Aleksa Sarai,2021-05-19 16:58:35+10:00,"rootfs: add mount destination validation Because the target of a mount is inside a container (which may be a volume that is shared with another container), there exists a race condition where the target of the mount may change to a path containing a symlink after we have sanitised the path -- resulting in us inadvertently mounting the path outside of the container. This is not immediately useful because we are in a mount namespace with MS_SLAVE mount propagation applied to ""/"", so we cannot mount on top of host paths in the host namespace. However, if any subsequent mountpoints in the configuration use a subdirectory of that host path as a source, those subsequent mounts will use an attacker-controlled source path (resolved within the host rootfs) -- allowing the bind-mounting of ""/"" into the container. While arguably configuration issues like this are not entirely within runc's threat model, within the context of Kubernetes (and possibly other container managers that provide semi-arbitrary container creation privileges to untrusted users) this is a legitimate issue. Since we cannot block mounting from the host into the container, we need to block the first stage of this attack (mounting onto a path outside the container). The long-term plan to solve this would be to migrate to libpathrs, but as a stop-gap we implement libpathrs-like path verification through readlink(/proc/self/fd/$n) and then do mount operations through the procfd once it's been verified to be inside the container. The target could move after we've checked it, but if it is inside the container then we can assume that it is safe for the same reason that libpathrs operations would be safe. A slight wrinkle is the ""copyup"" functionality we provide for tmpfs, which is the only case where we want to do a mount on the host filesystem. To facilitate this, I split out the copy-up functionality entirely so that the logic isn't interspersed with the regular tmpfs logic. In addition, all dependencies on m.Destination being overwritten have been removed since that pattern was just begging to be a source of more mount-target bugs (we do still have to modify m.Destination for tmpfs-copyup but we only do it temporarily). Fixes: CVE-2021-30465 Reported-by: Etienne Champetier Co-authored-by: Noah Meyerhans Reviewed-by: Samuel Karp Reviewed-by: Kir Kolyshkin (@kolyshkin) Reviewed-by: Akihiro Suda Signed-off-by: Aleksa Sarai ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2021-30465,"func createDeviceNode(rootfs string, node *devices.Device, bind bool) error { if node.Path == """" { return nil } dest, err := securejoin.SecureJoin(rootfs, node.Path) if err != nil { return err } if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil { return err } if bind { return bindMountDeviceNode(rootfs, dest, node) } if err := mknodDevice(dest, node); err != nil { if os.IsExist(err) { return nil } else if os.IsPermission(err) { return bindMountDeviceNode(rootfs, dest, node) } return err } return nil }" 141,"func mountCgroupV1(m *configs.Mount, c *mountConfig) error { binds, err := getCgroupMounts(m) if err != nil { return err } var merged []string for _, b := range binds { ss := filepath.Base(b.Destination) if strings.Contains(ss, "","") { merged = append(merged, ss) } } tmpfs := &configs.Mount{ Source: ""tmpfs"", Device: ""tmpfs"", Destination: m.Destination, Flags: defaultMountFlags, Data: ""mode=755"", PropagationFlags: m.PropagationFlags, } if err := mountToRootfs(tmpfs, c); err != nil { return err } for _, b := range binds { if c.cgroupns { subsystemPath := filepath.Join(c.root, b.Destination) if err := os.MkdirAll(subsystemPath, 0755); err != nil { return err } flags := defaultMountFlags if m.Flags&unix.MS_RDONLY != 0 { flags = flags | unix.MS_RDONLY } cgroupmount := &configs.Mount{ Source: ""cgroup"", Device: ""cgroup"", Destination: subsystemPath, Flags: flags, Data: filepath.Base(subsystemPath), } if err := mountNewCgroup(cgroupmount); err != nil { return err } } else { if err := mountToRootfs(b, c); err != nil { return err } } } for _, mc := range merged { for _, ss := range strings.Split(mc, "","") { if err := os.Symlink(mc, filepath.Join(c.root, m.Destination, ss)); err != nil && !os.IsExist(err) { return err } } } return nil }",True,Go,mountCgroupV1,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Aleksa Sarai,2021-05-19 16:58:35+10:00,"rootfs: add mount destination validation Because the target of a mount is inside a container (which may be a volume that is shared with another container), there exists a race condition where the target of the mount may change to a path containing a symlink after we have sanitised the path -- resulting in us inadvertently mounting the path outside of the container. This is not immediately useful because we are in a mount namespace with MS_SLAVE mount propagation applied to ""/"", so we cannot mount on top of host paths in the host namespace. However, if any subsequent mountpoints in the configuration use a subdirectory of that host path as a source, those subsequent mounts will use an attacker-controlled source path (resolved within the host rootfs) -- allowing the bind-mounting of ""/"" into the container. While arguably configuration issues like this are not entirely within runc's threat model, within the context of Kubernetes (and possibly other container managers that provide semi-arbitrary container creation privileges to untrusted users) this is a legitimate issue. Since we cannot block mounting from the host into the container, we need to block the first stage of this attack (mounting onto a path outside the container). The long-term plan to solve this would be to migrate to libpathrs, but as a stop-gap we implement libpathrs-like path verification through readlink(/proc/self/fd/$n) and then do mount operations through the procfd once it's been verified to be inside the container. The target could move after we've checked it, but if it is inside the container then we can assume that it is safe for the same reason that libpathrs operations would be safe. A slight wrinkle is the ""copyup"" functionality we provide for tmpfs, which is the only case where we want to do a mount on the host filesystem. To facilitate this, I split out the copy-up functionality entirely so that the logic isn't interspersed with the regular tmpfs logic. In addition, all dependencies on m.Destination being overwritten have been removed since that pattern was just begging to be a source of more mount-target bugs (we do still have to modify m.Destination for tmpfs-copyup but we only do it temporarily). Fixes: CVE-2021-30465 Reported-by: Etienne Champetier Co-authored-by: Noah Meyerhans Reviewed-by: Samuel Karp Reviewed-by: Kir Kolyshkin (@kolyshkin) Reviewed-by: Akihiro Suda Signed-off-by: Aleksa Sarai ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2021-30465,"func padBuffer(buffer []byte, blockSize int) []byte { missing := blockSize - (len(buffer) % blockSize) ret, out := resize(buffer, uint64(len(buffer))+uint64(missing)) padding := bytes.Repeat([]byte{byte(missing)}, missing) copy(out, padding) return ret }" 145,"func prepareBindMount(m *configs.Mount, rootfs string) error { stat, err := os.Stat(m.Source) if err != nil { return err } var dest string if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil { return err } if err := checkProcMount(rootfs, dest, m.Source); err != nil { return err } m.Destination = dest if err := createIfNotExists(dest, stat.IsDir()); err != nil { return err } return nil }",True,Go,prepareBindMount,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Aleksa Sarai,2021-05-19 16:58:35+10:00,"rootfs: add mount destination validation Because the target of a mount is inside a container (which may be a volume that is shared with another container), there exists a race condition where the target of the mount may change to a path containing a symlink after we have sanitised the path -- resulting in us inadvertently mounting the path outside of the container. This is not immediately useful because we are in a mount namespace with MS_SLAVE mount propagation applied to ""/"", so we cannot mount on top of host paths in the host namespace. However, if any subsequent mountpoints in the configuration use a subdirectory of that host path as a source, those subsequent mounts will use an attacker-controlled source path (resolved within the host rootfs) -- allowing the bind-mounting of ""/"" into the container. While arguably configuration issues like this are not entirely within runc's threat model, within the context of Kubernetes (and possibly other container managers that provide semi-arbitrary container creation privileges to untrusted users) this is a legitimate issue. Since we cannot block mounting from the host into the container, we need to block the first stage of this attack (mounting onto a path outside the container). The long-term plan to solve this would be to migrate to libpathrs, but as a stop-gap we implement libpathrs-like path verification through readlink(/proc/self/fd/$n) and then do mount operations through the procfd once it's been verified to be inside the container. The target could move after we've checked it, but if it is inside the container then we can assume that it is safe for the same reason that libpathrs operations would be safe. A slight wrinkle is the ""copyup"" functionality we provide for tmpfs, which is the only case where we want to do a mount on the host filesystem. To facilitate this, I split out the copy-up functionality entirely so that the logic isn't interspersed with the regular tmpfs logic. In addition, all dependencies on m.Destination being overwritten have been removed since that pattern was just begging to be a source of more mount-target bugs (we do still have to modify m.Destination for tmpfs-copyup but we only do it temporarily). Fixes: CVE-2021-30465 Reported-by: Etienne Champetier Co-authored-by: Noah Meyerhans Reviewed-by: Samuel Karp Reviewed-by: Kir Kolyshkin (@kolyshkin) Reviewed-by: Akihiro Suda Signed-off-by: Aleksa Sarai ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2021-30465,"func (ctx *cbcAEAD) computeAuthTag(aad, nonce, ciphertext []byte) []byte { buffer := make([]byte, uint64(len(aad))+uint64(len(nonce))+uint64(len(ciphertext))+8) n := 0 n += copy(buffer, aad) n += copy(buffer[n:], nonce) n += copy(buffer[n:], ciphertext) binary.BigEndian.PutUint64(buffer[n:], uint64(len(aad))*8) hmac := hmac.New(ctx.hash, ctx.integrityKey) _, _ = hmac.Write(buffer) return hmac.Sum(nil)[:ctx.authtagBytes] }" 146,"func mountNewCgroup(m *configs.Mount) error { var ( data = m.Data source = m.Source ) if data == ""systemd"" { data = cgroups.CgroupNamePrefix + data source = ""systemd"" } if err := unix.Mount(source, m.Destination, m.Device, uintptr(m.Flags), data); err != nil { return err } return nil }",True,Go,mountNewCgroup,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Aleksa Sarai,2021-05-19 16:58:35+10:00,"rootfs: add mount destination validation Because the target of a mount is inside a container (which may be a volume that is shared with another container), there exists a race condition where the target of the mount may change to a path containing a symlink after we have sanitised the path -- resulting in us inadvertently mounting the path outside of the container. This is not immediately useful because we are in a mount namespace with MS_SLAVE mount propagation applied to ""/"", so we cannot mount on top of host paths in the host namespace. However, if any subsequent mountpoints in the configuration use a subdirectory of that host path as a source, those subsequent mounts will use an attacker-controlled source path (resolved within the host rootfs) -- allowing the bind-mounting of ""/"" into the container. While arguably configuration issues like this are not entirely within runc's threat model, within the context of Kubernetes (and possibly other container managers that provide semi-arbitrary container creation privileges to untrusted users) this is a legitimate issue. Since we cannot block mounting from the host into the container, we need to block the first stage of this attack (mounting onto a path outside the container). The long-term plan to solve this would be to migrate to libpathrs, but as a stop-gap we implement libpathrs-like path verification through readlink(/proc/self/fd/$n) and then do mount operations through the procfd once it's been verified to be inside the container. The target could move after we've checked it, but if it is inside the container then we can assume that it is safe for the same reason that libpathrs operations would be safe. A slight wrinkle is the ""copyup"" functionality we provide for tmpfs, which is the only case where we want to do a mount on the host filesystem. To facilitate this, I split out the copy-up functionality entirely so that the logic isn't interspersed with the regular tmpfs logic. In addition, all dependencies on m.Destination being overwritten have been removed since that pattern was just begging to be a source of more mount-target bugs (we do still have to modify m.Destination for tmpfs-copyup but we only do it temporarily). Fixes: CVE-2021-30465 Reported-by: Etienne Champetier Co-authored-by: Noah Meyerhans Reviewed-by: Samuel Karp Reviewed-by: Kir Kolyshkin (@kolyshkin) Reviewed-by: Akihiro Suda Signed-off-by: Aleksa Sarai ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2021-30465,"func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { if len(ciphertext) < ctx.authtagBytes { return nil, errors.New(""square/go-jose: invalid ciphertext (too short)"") } offset := len(ciphertext) - ctx.authtagBytes expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset]) match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:]) if match != 1 { return nil, errors.New(""square/go-jose: invalid ciphertext (auth tag mismatch)"") } cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce) buffer := append([]byte{}, []byte(ciphertext[:offset])...) if len(buffer)%ctx.blockCipher.BlockSize() > 0 { return nil, errors.New(""square/go-jose: invalid ciphertext (invalid length)"") } cbc.CryptBlocks(buffer, buffer) plaintext, err := unpadBuffer(buffer, ctx.blockCipher.BlockSize()) if err != nil { return nil, err } ret, out := resize(dst, uint64(len(dst))+uint64(len(plaintext))) copy(out, plaintext) return ret, nil }" 148,"func bindMountDeviceNode(dest string, node *devices.Device) error { f, err := os.Create(dest) if err != nil && !os.IsExist(err) { return err } if f != nil { f.Close() } return unix.Mount(node.Path, dest, ""bind"", unix.MS_BIND, """") }",True,Go,bindMountDeviceNode,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Aleksa Sarai,2021-05-19 16:58:35+10:00,"rootfs: add mount destination validation Because the target of a mount is inside a container (which may be a volume that is shared with another container), there exists a race condition where the target of the mount may change to a path containing a symlink after we have sanitised the path -- resulting in us inadvertently mounting the path outside of the container. This is not immediately useful because we are in a mount namespace with MS_SLAVE mount propagation applied to ""/"", so we cannot mount on top of host paths in the host namespace. However, if any subsequent mountpoints in the configuration use a subdirectory of that host path as a source, those subsequent mounts will use an attacker-controlled source path (resolved within the host rootfs) -- allowing the bind-mounting of ""/"" into the container. While arguably configuration issues like this are not entirely within runc's threat model, within the context of Kubernetes (and possibly other container managers that provide semi-arbitrary container creation privileges to untrusted users) this is a legitimate issue. Since we cannot block mounting from the host into the container, we need to block the first stage of this attack (mounting onto a path outside the container). The long-term plan to solve this would be to migrate to libpathrs, but as a stop-gap we implement libpathrs-like path verification through readlink(/proc/self/fd/$n) and then do mount operations through the procfd once it's been verified to be inside the container. The target could move after we've checked it, but if it is inside the container then we can assume that it is safe for the same reason that libpathrs operations would be safe. A slight wrinkle is the ""copyup"" functionality we provide for tmpfs, which is the only case where we want to do a mount on the host filesystem. To facilitate this, I split out the copy-up functionality entirely so that the logic isn't interspersed with the regular tmpfs logic. In addition, all dependencies on m.Destination being overwritten have been removed since that pattern was just begging to be a source of more mount-target bugs (we do still have to modify m.Destination for tmpfs-copyup but we only do it temporarily). Fixes: CVE-2021-30465 Reported-by: Etienne Champetier Co-authored-by: Noah Meyerhans Reviewed-by: Samuel Karp Reviewed-by: Kir Kolyshkin (@kolyshkin) Reviewed-by: Akihiro Suda Signed-off-by: Aleksa Sarai ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2021-30465,"func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte { ciphertext := make([]byte, uint64(len(plaintext))+uint64(ctx.Overhead()))[:len(plaintext)] copy(ciphertext, plaintext) ciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize()) cbc := cipher.NewCBCEncrypter(ctx.blockCipher, nonce) cbc.CryptBlocks(ciphertext, ciphertext) authtag := ctx.computeAuthTag(data, nonce, ciphertext) ret, out := resize(dst, uint64(len(dst))+uint64(len(ciphertext))+uint64(len(authtag))) copy(out, ciphertext) copy(out[len(ciphertext):], authtag) return ret }" 149,"func mountPropagate(m *configs.Mount, rootfs string, mountLabel string) error { var ( dest = m.Destination data = label.FormatMountLabel(m.Data, mountLabel) flags = m.Flags ) if libcontainerUtils.CleanPath(dest) == ""/dev"" { flags &= ^unix.MS_RDONLY } if m.Device == ""tmpfs"" { flags &= ^unix.MS_RDONLY } copyUp := m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP if !(copyUp || strings.HasPrefix(dest, rootfs)) { dest = filepath.Join(rootfs, dest) } if err := unix.Mount(m.Source, dest, m.Device, uintptr(flags), data); err != nil { return err } for _, pflag := range m.PropagationFlags { if err := unix.Mount("""", dest, """", uintptr(pflag), """"); err != nil { return err } } return nil }",True,Go,mountPropagate,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Aleksa Sarai,2021-05-19 16:58:35+10:00,"rootfs: add mount destination validation Because the target of a mount is inside a container (which may be a volume that is shared with another container), there exists a race condition where the target of the mount may change to a path containing a symlink after we have sanitised the path -- resulting in us inadvertently mounting the path outside of the container. This is not immediately useful because we are in a mount namespace with MS_SLAVE mount propagation applied to ""/"", so we cannot mount on top of host paths in the host namespace. However, if any subsequent mountpoints in the configuration use a subdirectory of that host path as a source, those subsequent mounts will use an attacker-controlled source path (resolved within the host rootfs) -- allowing the bind-mounting of ""/"" into the container. While arguably configuration issues like this are not entirely within runc's threat model, within the context of Kubernetes (and possibly other container managers that provide semi-arbitrary container creation privileges to untrusted users) this is a legitimate issue. Since we cannot block mounting from the host into the container, we need to block the first stage of this attack (mounting onto a path outside the container). The long-term plan to solve this would be to migrate to libpathrs, but as a stop-gap we implement libpathrs-like path verification through readlink(/proc/self/fd/$n) and then do mount operations through the procfd once it's been verified to be inside the container. The target could move after we've checked it, but if it is inside the container then we can assume that it is safe for the same reason that libpathrs operations would be safe. A slight wrinkle is the ""copyup"" functionality we provide for tmpfs, which is the only case where we want to do a mount on the host filesystem. To facilitate this, I split out the copy-up functionality entirely so that the logic isn't interspersed with the regular tmpfs logic. In addition, all dependencies on m.Destination being overwritten have been removed since that pattern was just begging to be a source of more mount-target bugs (we do still have to modify m.Destination for tmpfs-copyup but we only do it temporarily). Fixes: CVE-2021-30465 Reported-by: Etienne Champetier Co-authored-by: Noah Meyerhans Reviewed-by: Samuel Karp Reviewed-by: Kir Kolyshkin (@kolyshkin) Reviewed-by: Akihiro Suda Signed-off-by: Aleksa Sarai ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2021-30465,"func TestInvalidPaddingOpen(t *testing.T) { key := make([]byte, 32) nonce := make([]byte, 16) plaintext := padBuffer(make([]byte, 28), aes.BlockSize) plaintext[len(plaintext)-1] = 0xFF io.ReadFull(rand.Reader, key) io.ReadFull(rand.Reader, nonce) block, _ := aes.NewCipher(key) cbc := cipher.NewCBCEncrypter(block, nonce) buffer := append([]byte{}, plaintext...) cbc.CryptBlocks(buffer, buffer) aead, _ := NewCBCHMAC(key, aes.NewCipher) ctx := aead.(*cbcAEAD) size := uint64(len(buffer)) ciphertext, tail := resize(buffer, size+(uint64(len(key))/2)) copy(tail, ctx.computeAuthTag(nil, nonce, ciphertext[:size])) _, err := aead.Open(nil, nonce, ciphertext, nil) if err == nil || !strings.Contains(err.Error(), ""invalid padding"") { t.Error(""no or unexpected error on open with invalid padding:"", err) } }" 150,"func createDeviceNode(rootfs string, node *devices.Device, bind bool) error { if node.Path == """" { return nil } dest := filepath.Join(rootfs, node.Path) if err := os.MkdirAll(filepath.Dir(dest), 0755); err != nil { return err } if bind { return bindMountDeviceNode(dest, node) } if err := mknodDevice(dest, node); err != nil { if os.IsExist(err) { return nil } else if os.IsPermission(err) { return bindMountDeviceNode(dest, node) } return err } return nil }",True,Go,createDeviceNode,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Aleksa Sarai,2021-05-19 16:58:35+10:00,"rootfs: add mount destination validation Because the target of a mount is inside a container (which may be a volume that is shared with another container), there exists a race condition where the target of the mount may change to a path containing a symlink after we have sanitised the path -- resulting in us inadvertently mounting the path outside of the container. This is not immediately useful because we are in a mount namespace with MS_SLAVE mount propagation applied to ""/"", so we cannot mount on top of host paths in the host namespace. However, if any subsequent mountpoints in the configuration use a subdirectory of that host path as a source, those subsequent mounts will use an attacker-controlled source path (resolved within the host rootfs) -- allowing the bind-mounting of ""/"" into the container. While arguably configuration issues like this are not entirely within runc's threat model, within the context of Kubernetes (and possibly other container managers that provide semi-arbitrary container creation privileges to untrusted users) this is a legitimate issue. Since we cannot block mounting from the host into the container, we need to block the first stage of this attack (mounting onto a path outside the container). The long-term plan to solve this would be to migrate to libpathrs, but as a stop-gap we implement libpathrs-like path verification through readlink(/proc/self/fd/$n) and then do mount operations through the procfd once it's been verified to be inside the container. The target could move after we've checked it, but if it is inside the container then we can assume that it is safe for the same reason that libpathrs operations would be safe. A slight wrinkle is the ""copyup"" functionality we provide for tmpfs, which is the only case where we want to do a mount on the host filesystem. To facilitate this, I split out the copy-up functionality entirely so that the logic isn't interspersed with the regular tmpfs logic. In addition, all dependencies on m.Destination being overwritten have been removed since that pattern was just begging to be a source of more mount-target bugs (we do still have to modify m.Destination for tmpfs-copyup but we only do it temporarily). Fixes: CVE-2021-30465 Reported-by: Etienne Champetier Co-authored-by: Noah Meyerhans Reviewed-by: Samuel Karp Reviewed-by: Kir Kolyshkin (@kolyshkin) Reviewed-by: Akihiro Suda Signed-off-by: Aleksa Sarai ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2021-30465,"func TestTruncatedCiphertext(t *testing.T) { key := make([]byte, 32) nonce := make([]byte, 16) data := make([]byte, 32) io.ReadFull(rand.Reader, key) io.ReadFull(rand.Reader, nonce) aead, err := NewCBCHMAC(key, aes.NewCipher) if err != nil { panic(err) } ctx := aead.(*cbcAEAD) ct := aead.Seal(nil, nonce, data, nil) truncated, tail := resize(ct[:len(ct)-ctx.authtagBytes-2], uint64(len(ct))-2) copy(tail, ctx.computeAuthTag(nil, nonce, truncated[:len(truncated)-ctx.authtagBytes])) _, err = aead.Open(nil, nonce, truncated, nil) if err == nil { t.Error(""open on truncated ciphertext should fail"") } }" 151,"func mountCgroupV2(m *configs.Mount, c *mountConfig) error { dest, err := securejoin.SecureJoin(c.root, m.Destination) if err != nil { return err } if err := os.MkdirAll(dest, 0755); err != nil { return err } if err := unix.Mount(m.Source, dest, ""cgroup2"", uintptr(m.Flags), m.Data); err != nil { if err == unix.EPERM || err == unix.EBUSY { src := fs2.UnifiedMountpoint if c.cgroupns && c.cgroup2Path != """" { src = c.cgroup2Path } err = unix.Mount(src, dest, """", uintptr(m.Flags)|unix.MS_BIND, """") if err == unix.ENOENT && c.rootlessCgroups { err = nil } return err } return err } return nil }",True,Go,mountCgroupV2,rootfs_linux.go,https://github.com/opencontainers/runc,opencontainers,Aleksa Sarai,2021-05-19 16:58:35+10:00,"rootfs: add mount destination validation Because the target of a mount is inside a container (which may be a volume that is shared with another container), there exists a race condition where the target of the mount may change to a path containing a symlink after we have sanitised the path -- resulting in us inadvertently mounting the path outside of the container. This is not immediately useful because we are in a mount namespace with MS_SLAVE mount propagation applied to ""/"", so we cannot mount on top of host paths in the host namespace. However, if any subsequent mountpoints in the configuration use a subdirectory of that host path as a source, those subsequent mounts will use an attacker-controlled source path (resolved within the host rootfs) -- allowing the bind-mounting of ""/"" into the container. While arguably configuration issues like this are not entirely within runc's threat model, within the context of Kubernetes (and possibly other container managers that provide semi-arbitrary container creation privileges to untrusted users) this is a legitimate issue. Since we cannot block mounting from the host into the container, we need to block the first stage of this attack (mounting onto a path outside the container). The long-term plan to solve this would be to migrate to libpathrs, but as a stop-gap we implement libpathrs-like path verification through readlink(/proc/self/fd/$n) and then do mount operations through the procfd once it's been verified to be inside the container. The target could move after we've checked it, but if it is inside the container then we can assume that it is safe for the same reason that libpathrs operations would be safe. A slight wrinkle is the ""copyup"" functionality we provide for tmpfs, which is the only case where we want to do a mount on the host filesystem. To facilitate this, I split out the copy-up functionality entirely so that the logic isn't interspersed with the regular tmpfs logic. In addition, all dependencies on m.Destination being overwritten have been removed since that pattern was just begging to be a source of more mount-target bugs (we do still have to modify m.Destination for tmpfs-copyup but we only do it temporarily). Fixes: CVE-2021-30465 Reported-by: Etienne Champetier Co-authored-by: Noah Meyerhans Reviewed-by: Samuel Karp Reviewed-by: Kir Kolyshkin (@kolyshkin) Reviewed-by: Akihiro Suda Signed-off-by: Aleksa Sarai ",CWE-362,Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition'),"The product contains a code sequence that can run concurrently with other code, and the code sequence requires temporary, exclusive access to a shared resource, but a timing window exists in which the shared resource can be modified by another code sequence that is operating concurrently.",https://cwe.mitre.org/data/definitions/362.html,CVE-2021-30465,"func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader { buffer := make([]byte, uint64(len(algID))+uint64(len(ptyUInfo))+uint64(len(ptyVInfo))+uint64(len(supPubInfo))+uint64(len(supPrivInfo))) n := 0 n += copy(buffer, algID) n += copy(buffer[n:], ptyUInfo) n += copy(buffer[n:], ptyVInfo) n += copy(buffer[n:], supPubInfo) copy(buffer[n:], supPrivInfo) hasher := hash.New() return &concatKDF{ z: z, info: buffer, hasher: hasher, cache: []byte{}, i: 1, } }" 160,"func (ctx *cbcAEAD) Open(dst, nonce, ciphertext, data []byte) ([]byte, error) { if len(ciphertext) < ctx.authtagBytes { return nil, errors.New(""square/go-jose: invalid ciphertext (too short)"") } offset := len(ciphertext) - ctx.authtagBytes expectedTag := ctx.computeAuthTag(data, nonce, ciphertext[:offset]) match := subtle.ConstantTimeCompare(expectedTag, ciphertext[offset:]) if match != 1 { return nil, errors.New(""square/go-jose: invalid ciphertext (auth tag mismatch)"") } cbc := cipher.NewCBCDecrypter(ctx.blockCipher, nonce) buffer := append([]byte{}, []byte(ciphertext[:offset])...) if len(buffer)%ctx.blockCipher.BlockSize() > 0 { return nil, errors.New(""square/go-jose: invalid ciphertext (invalid length)"") } cbc.CryptBlocks(buffer, buffer) plaintext, err := unpadBuffer(buffer, ctx.blockCipher.BlockSize()) if err != nil { return nil, err } ret, out := resize(dst, len(dst)+len(plaintext)) copy(out, plaintext) return ret, nil }",True,Go,Open,cbc_hmac.go,https://github.com/square/go-jose,square,Cedric Staub,2016-09-02 21:47:34-07:00,"Use uint64 for all size calculations, size checks",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2016-9123,"func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact bool, length C.uint, cond C.scmp_cast_t) error { if length != 0 && cond == nil { return fmt.Errorf(""null conditions list, but length is nonzero"") } var retCode C.int if exact { retCode = C.seccomp_rule_add_exact_array(f.filterCtx, action.toNative(), C.int(call), length, cond) } else { retCode = C.seccomp_rule_add_array(f.filterCtx, action.toNative(), C.int(call), length, cond) } if syscall.Errno(-1*retCode) == syscall.EFAULT { return fmt.Errorf(""unrecognized syscall"") } else if syscall.Errno(-1*retCode) == syscall.EPERM { return fmt.Errorf(""requested action matches default action of filter"") } else if syscall.Errno(-1*retCode) == syscall.EINVAL { return fmt.Errorf(""two checks on same syscall argument"") } else if retCode != 0 { return syscall.Errno(-1 * retCode) } return nil }" 162,"func resize(in []byte, n int) (head, tail []byte) { if cap(in) >= n { head = in[:n] } else { head = make([]byte, n) copy(head, in) } tail = head[len(in):] return }",True,Go,resize,cbc_hmac.go,https://github.com/square/go-jose,square,Cedric Staub,2016-09-02 21:47:34-07:00,"Use uint64 for all size calculations, size checks",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2016-9123,"func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact bool, conds []ScmpCondition) error { f.lock.Lock() defer f.lock.Unlock() if !f.valid { return errBadFilter } if len(conds) == 0 { if err := f.addRuleWrapper(call, action, exact, 0, nil); err != nil { return err } } else { if !checkVersionAbove(2, 2, 1) { return VersionError{ message: ""conditional filtering is not supported"", minimum: ""2.2.1"", } } argsArr := C.make_arg_cmp_array(C.uint(len(conds))) if argsArr == nil { return fmt.Errorf(""error allocating memory for conditions"") } defer C.free(argsArr) for i, cond := range conds { C.add_struct_arg_cmp(C.scmp_cast_t(argsArr), C.uint(i), C.uint(cond.Argument), cond.Op.toNative(), C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2)) } if err := f.addRuleWrapper(call, action, exact, C.uint(len(conds)), C.scmp_cast_t(argsArr)); err != nil { return err } } return nil }" 163,"func (ctx *cbcAEAD) Seal(dst, nonce, plaintext, data []byte) []byte { ciphertext := make([]byte, len(plaintext)+ctx.Overhead())[:len(plaintext)] copy(ciphertext, plaintext) ciphertext = padBuffer(ciphertext, ctx.blockCipher.BlockSize()) cbc := cipher.NewCBCEncrypter(ctx.blockCipher, nonce) cbc.CryptBlocks(ciphertext, ciphertext) authtag := ctx.computeAuthTag(data, nonce, ciphertext) ret, out := resize(dst, len(dst)+len(ciphertext)+len(authtag)) copy(out, ciphertext) copy(out[len(ciphertext):], authtag) return ret }",True,Go,Seal,cbc_hmac.go,https://github.com/square/go-jose,square,Cedric Staub,2016-09-02 21:47:34-07:00,"Use uint64 for all size calculations, size checks",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2016-9123,"func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) { origin := r.Header.Get(corsOriginHeader) if !ch.isOriginAllowed(origin) { ch.h.ServeHTTP(w, r) return } if r.Method == corsOptionMethod { if ch.ignoreOptions { ch.h.ServeHTTP(w, r) return } if _, ok := r.Header[corsRequestMethodHeader]; !ok { w.WriteHeader(http.StatusBadRequest) return } method := r.Header.Get(corsRequestMethodHeader) if !ch.isMatch(method, ch.allowedMethods) { w.WriteHeader(http.StatusMethodNotAllowed) return } requestHeaders := strings.Split(r.Header.Get(corsRequestHeadersHeader), "","") allowedHeaders := []string{} for _, v := range requestHeaders { canonicalHeader := http.CanonicalHeaderKey(strings.TrimSpace(v)) if canonicalHeader == """" || ch.isMatch(canonicalHeader, defaultCorsHeaders) { continue } if !ch.isMatch(canonicalHeader, ch.allowedHeaders) { w.WriteHeader(http.StatusForbidden) return } allowedHeaders = append(allowedHeaders, canonicalHeader) } if len(allowedHeaders) > 0 { w.Header().Set(corsAllowHeadersHeader, strings.Join(allowedHeaders, "","")) } if ch.maxAge > 0 { w.Header().Set(corsMaxAgeHeader, strconv.Itoa(ch.maxAge)) } if !ch.isMatch(method, defaultCorsMethods) { w.Header().Set(corsAllowMethodsHeader, method) } } else { if len(ch.exposedHeaders) > 0 { w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, "","")) } } if ch.allowCredentials { w.Header().Set(corsAllowCredentialsHeader, ""true"") } if len(ch.allowedOrigins) > 1 { w.Header().Set(corsVaryHeader, corsOriginHeader) } returnOrigin := origin for _, o := range ch.allowedOrigins { if o == corsOriginMatchAll { returnOrigin = ""*"" break } } w.Header().Set(corsAllowOriginHeader, returnOrigin) if r.Method == corsOptionMethod { return } ch.h.ServeHTTP(w, r) }" 165,"func TestInvalidPaddingOpen(t *testing.T) { key := make([]byte, 32) nonce := make([]byte, 16) plaintext := padBuffer(make([]byte, 28), aes.BlockSize) plaintext[len(plaintext)-1] = 0xFF io.ReadFull(rand.Reader, key) io.ReadFull(rand.Reader, nonce) block, _ := aes.NewCipher(key) cbc := cipher.NewCBCEncrypter(block, nonce) buffer := append([]byte{}, plaintext...) cbc.CryptBlocks(buffer, buffer) aead, _ := NewCBCHMAC(key, aes.NewCipher) ctx := aead.(*cbcAEAD) size := len(buffer) ciphertext, tail := resize(buffer, size+(len(key)/2)) copy(tail, ctx.computeAuthTag(nil, nonce, ciphertext[:size])) _, err := aead.Open(nil, nonce, ciphertext, nil) if err == nil || !strings.Contains(err.Error(), ""invalid padding"") { t.Error(""no or unexpected error on open with invalid padding:"", err) } }",True,Go,TestInvalidPaddingOpen,cbc_hmac_test.go,https://github.com/square/go-jose,square,Cedric Staub,2016-09-02 21:47:34-07:00,"Use uint64 for all size calculations, size checks",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2016-9123,"func TestAuth(t *testing.T) { a, b, err := netPipe() if err != nil { t.Fatalf(""netPipe: %v"", err) } defer a.Close() defer b.Close() agent, _, cleanup := startAgent(t) defer cleanup() if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys[""rsa""], Comment: ""comment""}); err != nil { t.Errorf(""Add: %v"", err) } serverConf := ssh.ServerConfig{} serverConf.AddHostKey(testSigners[""rsa""]) serverConf.PublicKeyCallback = func(c ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { if bytes.Equal(key.Marshal(), testPublicKeys[""rsa""].Marshal()) { return nil, nil } return nil, errors.New(""pubkey rejected"") } go func() { conn, _, _, err := ssh.NewServerConn(a, &serverConf) if err != nil { t.Fatalf(""Server: %v"", err) } conn.Close() }() conf := ssh.ClientConfig{ HostKeyCallback: ssh.InsecureIgnoreHostKey(), } conf.Auth = append(conf.Auth, ssh.PublicKeysCallback(agent.Signers)) conn, _, _, err := ssh.NewClientConn(b, """", &conf) if err != nil { t.Fatalf(""NewClientConn: %v"", err) } conn.Close() }" 166,"func TestTruncatedCiphertext(t *testing.T) { key := make([]byte, 32) nonce := make([]byte, 16) data := make([]byte, 32) io.ReadFull(rand.Reader, key) io.ReadFull(rand.Reader, nonce) aead, err := NewCBCHMAC(key, aes.NewCipher) if err != nil { panic(err) } ctx := aead.(*cbcAEAD) ct := aead.Seal(nil, nonce, data, nil) truncated, tail := resize(ct[:len(ct)-ctx.authtagBytes-2], len(ct)-2) copy(tail, ctx.computeAuthTag(nil, nonce, truncated[:len(truncated)-ctx.authtagBytes])) _, err = aead.Open(nil, nonce, truncated, nil) if err == nil { t.Error(""open on truncated ciphertext should fail"") } }",True,Go,TestTruncatedCiphertext,cbc_hmac_test.go,https://github.com/square/go-jose,square,Cedric Staub,2016-09-02 21:47:34-07:00,"Use uint64 for all size calculations, size checks",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2016-9123,"func ExampleClientAgent() { socket := os.Getenv(""SSH_AUTH_SOCK"") conn, err := net.Dial(""unix"", socket) if err != nil { log.Fatalf(""net.Dial: %v"", err) } agentClient := agent.NewClient(conn) config := &ssh.ClientConfig{ User: ""username"", Auth: []ssh.AuthMethod{ ssh.PublicKeysCallback(agentClient.Signers), }, HostKeyCallback: ssh.InsecureIgnoreHostKey(), } sshc, err := ssh.Dial(""tcp"", ""localhost:22"", config) if err != nil { log.Fatalf(""Dial: %v"", err) } sshc.Close() }" 170,"func NewConcatKDF(hash crypto.Hash, z, algID, ptyUInfo, ptyVInfo, supPubInfo, supPrivInfo []byte) io.Reader { buffer := make([]byte, len(algID)+len(ptyUInfo)+len(ptyVInfo)+len(supPubInfo)+len(supPrivInfo)) n := 0 n += copy(buffer, algID) n += copy(buffer[n:], ptyUInfo) n += copy(buffer[n:], ptyVInfo) n += copy(buffer[n:], supPubInfo) copy(buffer[n:], supPrivInfo) hasher := hash.New() return &concatKDF{ z: z, info: buffer, hasher: hasher, cache: []byte{}, i: 1, } }",True,Go,NewConcatKDF,concat_kdf.go,https://github.com/square/go-jose,square,Cedric Staub,2016-09-02 21:47:34-07:00,"Use uint64 for all size calculations, size checks",CWE-190,Integer Overflow or Wraparound,"The product performs a calculation that can produce an integer overflow or wraparound, when the logic assumes that the resulting value will always be larger than the original value. This can introduce other weaknesses when the calculation is used for resource management or execution control.",https://cwe.mitre.org/data/definitions/190.html,CVE-2016-9123,"func TestSetupForwardAgent(t *testing.T) { a, b, err := netPipe() if err != nil { t.Fatalf(""netPipe: %v"", err) } defer a.Close() defer b.Close() _, socket, cleanup := startAgent(t) defer cleanup() serverConf := ssh.ServerConfig{ NoClientAuth: true, } serverConf.AddHostKey(testSigners[""rsa""]) incoming := make(chan *ssh.ServerConn, 1) go func() { conn, _, _, err := ssh.NewServerConn(a, &serverConf) if err != nil { t.Fatalf(""Server: %v"", err) } incoming <- conn }() conf := ssh.ClientConfig{ HostKeyCallback: ssh.InsecureIgnoreHostKey(), } conn, chans, reqs, err := ssh.NewClientConn(b, """", &conf) if err != nil { t.Fatalf(""NewClientConn: %v"", err) } client := ssh.NewClient(conn, chans, reqs) if err := ForwardToRemote(client, socket); err != nil { t.Fatalf(""SetupForwardAgent: %v"", err) } server := <-incoming ch, reqs, err := server.OpenChannel(channelType, nil) if err != nil { t.Fatalf(""OpenChannel(%q): %v"", channelType, err) } go ssh.DiscardRequests(reqs) agentClient := NewClient(ch) testAgentInterface(t, agentClient, testPrivateKeys[""rsa""], nil, 0) conn.Close() }" 176,"func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact bool, cond C.scmp_cast_t) error { var length C.uint if cond != nil { length = 1 } else { length = 0 } var retCode C.int if exact { retCode = C.seccomp_rule_add_exact_array(f.filterCtx, action.toNative(), C.int(call), length, cond) } else { retCode = C.seccomp_rule_add_array(f.filterCtx, action.toNative(), C.int(call), length, cond) } if syscall.Errno(-1*retCode) == syscall.EFAULT { return fmt.Errorf(""unrecognized syscall"") } else if syscall.Errno(-1*retCode) == syscall.EPERM { return fmt.Errorf(""requested action matches default action of filter"") } else if retCode != 0 { return syscall.Errno(-1 * retCode) } return nil }",True,Go,addRuleWrapper,seccomp_internal.go,https://github.com/seccomp/libseccomp-golang,seccomp,Matthew Heon,2017-04-24 13:34:20-04:00,"golang: Resolve bug with handling of multiple argument rules In the upstream library, when added with a single API call, multiple syscall argument rules should be matched with AND logic - if all of them match, the rule matches. At present, the Golang bindings apply OR logic to this case. This commit resolves this and reverts to the behavior of the main library. Signed-off-by: Matthew Heon ",CWE-20,Improper Input Validation,"The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.",https://cwe.mitre.org/data/definitions/20.html,CVE-2017-18367,"func TestClientLoginCert(t *testing.T) { cert := &Certificate{ Key: testPublicKeys[""rsa""], ValidBefore: CertTimeInfinity, CertType: UserCert, } cert.SignCert(rand.Reader, testSigners[""ecdsa""]) certSigner, err := NewCertSigner(cert, testSigners[""rsa""]) if err != nil { t.Fatalf(""NewCertSigner: %v"", err) } clientConfig := &ClientConfig{ User: ""user"", HostKeyCallback: InsecureIgnoreHostKey(), } clientConfig.Auth = append(clientConfig.Auth, PublicKeys(certSigner)) if err := tryAuth(t, clientConfig); err != nil { t.Errorf(""cert login failed: %v"", err) } cert.Signature.Blob[0]++ if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login passed with corrupted sig"") } cert.Serial = 666 cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""revoked cert login succeeded"") } cert.Serial = 1 cert.SignCert(rand.Reader, testSigners[""dsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login passed with non-authoritative key"") } cert.CertType = HostCert cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login passed with wrong type"") } cert.CertType = UserCert cert.ValidPrincipals = []string{""user""} cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err != nil { t.Errorf(""cert login failed: %v"", err) } cert.ValidPrincipals = []string{""fred""} cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login passed with wrong principal"") } cert.ValidPrincipals = nil cert.CriticalOptions = map[string]string{""root-access"": ""yes""} cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login passed with unrecognized critical option"") } cert.CriticalOptions = map[string]string{""source-address"": ""127.0.0.42/24,::42/120""} cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err != nil { t.Errorf(""cert login with source-address failed: %v"", err) } cert.CriticalOptions = map[string]string{""source-address"": ""127.0.0.42,::42""} cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login with source-address succeeded"") } }" 179,"func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact bool, conds []ScmpCondition) error { f.lock.Lock() defer f.lock.Unlock() if !f.valid { return errBadFilter } if len(conds) == 0 { if err := f.addRuleWrapper(call, action, exact, nil); err != nil { return err } } else { if !checkVersionAbove(2, 2, 1) { return VersionError{ message: ""conditional filtering is not supported"", minimum: ""2.2.1"", } } for _, cond := range conds { cmpStruct := C.make_struct_arg_cmp(C.uint(cond.Argument), cond.Op.toNative(), C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2)) defer C.free(cmpStruct) if err := f.addRuleWrapper(call, action, exact, C.scmp_cast_t(cmpStruct)); err != nil { return err } } } return nil }",True,Go,addRuleGeneric,seccomp_internal.go,https://github.com/seccomp/libseccomp-golang,seccomp,Matthew Heon,2017-04-24 13:34:20-04:00,"golang: Resolve bug with handling of multiple argument rules In the upstream library, when added with a single API call, multiple syscall argument rules should be matched with AND logic - if all of them match, the rule matches. At present, the Golang bindings apply OR logic to this case. This commit resolves this and reverts to the behavior of the main library. Signed-off-by: Matthew Heon ",CWE-20,Improper Input Validation,"The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.",https://cwe.mitre.org/data/definitions/20.html,CVE-2017-18367,"func ExampleDial() { var hostKey ssh.PublicKey config := &ssh.ClientConfig{ User: ""username"", Auth: []ssh.AuthMethod{ ssh.Password(""yourpassword""), }, HostKeyCallback: ssh.FixedHostKey(hostKey), } client, err := ssh.Dial(""tcp"", ""yourserver.com:22"", config) if err != nil { log.Fatal(""Failed to dial: "", err) } session, err := client.NewSession() if err != nil { log.Fatal(""Failed to create session: "", err) } defer session.Close() var b bytes.Buffer session.Stdout = &b if err := session.Run(""/usr/bin/whoami""); err != nil { log.Fatal(""Failed to run: "" + err.Error()) } fmt.Println(b.String()) }" 181,"func (ch *cors) ServeHTTP(w http.ResponseWriter, r *http.Request) { origin := r.Header.Get(corsOriginHeader) if !ch.isOriginAllowed(origin) { ch.h.ServeHTTP(w, r) return } if r.Method == corsOptionMethod { if ch.ignoreOptions { ch.h.ServeHTTP(w, r) return } if _, ok := r.Header[corsRequestMethodHeader]; !ok { w.WriteHeader(http.StatusBadRequest) return } method := r.Header.Get(corsRequestMethodHeader) if !ch.isMatch(method, ch.allowedMethods) { w.WriteHeader(http.StatusMethodNotAllowed) return } requestHeaders := strings.Split(r.Header.Get(corsRequestHeadersHeader), "","") allowedHeaders := []string{} for _, v := range requestHeaders { canonicalHeader := http.CanonicalHeaderKey(strings.TrimSpace(v)) if canonicalHeader == """" || ch.isMatch(canonicalHeader, defaultCorsHeaders) { continue } if !ch.isMatch(canonicalHeader, ch.allowedHeaders) { w.WriteHeader(http.StatusForbidden) return } allowedHeaders = append(allowedHeaders, canonicalHeader) } if len(allowedHeaders) > 0 { w.Header().Set(corsAllowHeadersHeader, strings.Join(allowedHeaders, "","")) } if ch.maxAge > 0 { w.Header().Set(corsMaxAgeHeader, strconv.Itoa(ch.maxAge)) } if !ch.isMatch(method, defaultCorsMethods) { w.Header().Set(corsAllowMethodsHeader, method) } } else { if len(ch.exposedHeaders) > 0 { w.Header().Set(corsExposeHeadersHeader, strings.Join(ch.exposedHeaders, "","")) } } if ch.allowCredentials { w.Header().Set(corsAllowCredentialsHeader, ""true"") } if len(ch.allowedOrigins) > 1 { w.Header().Set(corsVaryHeader, corsOriginHeader) } w.Header().Set(corsAllowOriginHeader, origin) if r.Method == corsOptionMethod { return } ch.h.ServeHTTP(w, r) }",True,Go,ServeHTTP,cors.go,https://github.com/gorilla/handlers,gorilla,Matt Silverlock,2017-11-01 10:43:35-07:00,"[bugfix] Don't return the origin header when configured to * (#116) There's no reason to allow for a server to reflect all origin headers. This has caused numerous security problems in the past. - https://github.com/cyu/rack-cors/issues/126 - https://nodesecurity.io/advisories/148 - https://github.com/captncraig/cors/commit/cc1cf75f5e3c06124602f2aa7893c8f3b1eef0b7 Some helpful blog posts on the topic: - https://ejj.io/misconfigured-cors/ - http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html",CWE-346,Origin Validation Error,The product does not properly verify that the source of data or communication is valid.,https://cwe.mitre.org/data/definitions/346.html,CVE-2017-20146,"func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) { result, err := kex.Client(t.conn, t.config.Rand, magics) if err != nil { return nil, err } hostKey, err := ParsePublicKey(result.HostKey) if err != nil { return nil, err } if err := verifyHostKeySignature(hostKey, result); err != nil { return nil, err } err = t.hostKeyCallback(t.dialAddress, t.remoteAddr, hostKey) if err != nil { return nil, err } return result, nil }" 183,"func TestAuth(t *testing.T) { a, b, err := netPipe() if err != nil { t.Fatalf(""netPipe: %v"", err) } defer a.Close() defer b.Close() agent, _, cleanup := startAgent(t) defer cleanup() if err := agent.Add(AddedKey{PrivateKey: testPrivateKeys[""rsa""], Comment: ""comment""}); err != nil { t.Errorf(""Add: %v"", err) } serverConf := ssh.ServerConfig{} serverConf.AddHostKey(testSigners[""rsa""]) serverConf.PublicKeyCallback = func(c ssh.ConnMetadata, key ssh.PublicKey) (*ssh.Permissions, error) { if bytes.Equal(key.Marshal(), testPublicKeys[""rsa""].Marshal()) { return nil, nil } return nil, errors.New(""pubkey rejected"") } go func() { conn, _, _, err := ssh.NewServerConn(a, &serverConf) if err != nil { t.Fatalf(""Server: %v"", err) } conn.Close() }() conf := ssh.ClientConfig{} conf.Auth = append(conf.Auth, ssh.PublicKeysCallback(agent.Signers)) conn, _, _, err := ssh.NewClientConn(b, """", &conf) if err != nil { t.Fatalf(""NewClientConn: %v"", err) } conn.Close() }",True,Go,TestAuth,client_test.go,https://github.com/golang/crypto,golang,Han-Wen Nienhuys,2017-03-30 15:57:35+00:00,"ssh: require host key checking in the ClientConfig This change breaks existing behavior. Before, a missing ClientConfig.HostKeyCallback would cause host key checking to be disabled. In this configuration, establishing a connection to any host just works, so today, most SSH client code in the wild does not perform any host key checks. This makes it easy to perform a MITM attack: * SSH installations that use keyboard-interactive or password authentication can be attacked with MITM, thereby stealing passwords. * Clients that use public-key authentication with agent forwarding are also vulnerable: the MITM server could allow the login to succeed, and then immediately ask the agent to authenticate the login to the real server. * Clients that use public-key authentication without agent forwarding are harder to attack unnoticedly: an attacker cannot authenticate the login to the real server, so it cannot in general present a convincing server to the victim. Now, a missing HostKeyCallback will cause the handshake to fail. This change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as ready made host checkers. A simplistic parser for OpenSSH's known_hosts file is given as an example. This change does not provide a full-fledged parser, as it has complexity (wildcards, revocation, hashed addresses) that will need further consideration. When introduced, the host checking feature maintained backward compatibility at the expense of security. We have decided this is not the right tradeoff for the SSH library. Fixes golang/go#19767 Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814 Reviewed-on: https://go-review.googlesource.com/38701 Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick ",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2017-3204,"func TestSessionID(t *testing.T) { c1, c2, err := netPipe() if err != nil { t.Fatalf(""netPipe: %v"", err) } defer c1.Close() defer c2.Close() serverID := make(chan []byte, 1) clientID := make(chan []byte, 1) serverConf := &ServerConfig{ NoClientAuth: true, } serverConf.AddHostKey(testSigners[""ecdsa""]) clientConf := &ClientConfig{ HostKeyCallback: InsecureIgnoreHostKey(), User: ""user"", } go func() { conn, chans, reqs, err := NewServerConn(c1, serverConf) if err != nil { t.Fatalf(""server handshake: %v"", err) } serverID <- conn.SessionID() go DiscardRequests(reqs) for ch := range chans { ch.Reject(Prohibited, """") } }() go func() { conn, chans, reqs, err := NewClientConn(c2, """", clientConf) if err != nil { t.Fatalf(""client handshake: %v"", err) } clientID <- conn.SessionID() go DiscardRequests(reqs) for ch := range chans { ch.Reject(Prohibited, """") } }() s := <-serverID c := <-clientID if bytes.Compare(s, c) != 0 { t.Errorf(""server session ID (%x) != client session ID (%x)"", s, c) } else if len(s) == 0 { t.Errorf(""client and server SessionID were empty."") } }" 185,"func ExampleClientAgent() { socket := os.Getenv(""SSH_AUTH_SOCK"") conn, err := net.Dial(""unix"", socket) if err != nil { log.Fatalf(""net.Dial: %v"", err) } agentClient := agent.NewClient(conn) config := &ssh.ClientConfig{ User: ""username"", Auth: []ssh.AuthMethod{ ssh.PublicKeysCallback(agentClient.Signers), }, } sshc, err := ssh.Dial(""tcp"", ""localhost:22"", config) if err != nil { log.Fatalf(""Dial: %v"", err) } sshc.Close() }",True,Go,ExampleClientAgent,example_test.go,https://github.com/golang/crypto,golang,Han-Wen Nienhuys,2017-03-30 15:57:35+00:00,"ssh: require host key checking in the ClientConfig This change breaks existing behavior. Before, a missing ClientConfig.HostKeyCallback would cause host key checking to be disabled. In this configuration, establishing a connection to any host just works, so today, most SSH client code in the wild does not perform any host key checks. This makes it easy to perform a MITM attack: * SSH installations that use keyboard-interactive or password authentication can be attacked with MITM, thereby stealing passwords. * Clients that use public-key authentication with agent forwarding are also vulnerable: the MITM server could allow the login to succeed, and then immediately ask the agent to authenticate the login to the real server. * Clients that use public-key authentication without agent forwarding are harder to attack unnoticedly: an attacker cannot authenticate the login to the real server, so it cannot in general present a convincing server to the victim. Now, a missing HostKeyCallback will cause the handshake to fail. This change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as ready made host checkers. A simplistic parser for OpenSSH's known_hosts file is given as an example. This change does not provide a full-fledged parser, as it has complexity (wildcards, revocation, hashed addresses) that will need further consideration. When introduced, the host checking feature maintained backward compatibility at the expense of security. We have decided this is not the right tradeoff for the SSH library. Fixes golang/go#19767 Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814 Reviewed-on: https://go-review.googlesource.com/38701 Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick ",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2017-3204,"func TestCertLogin(t *testing.T) { s := newServer(t) defer s.Shutdown() clientKey := testSigners[""dsa""] caAuthKey := testSigners[""ecdsa""] cert := &ssh.Certificate{ Key: clientKey.PublicKey(), ValidPrincipals: []string{username()}, CertType: ssh.UserCert, ValidBefore: ssh.CertTimeInfinity, } if err := cert.SignCert(rand.Reader, caAuthKey); err != nil { t.Fatalf(""SetSignature: %v"", err) } certSigner, err := ssh.NewCertSigner(cert, clientKey) if err != nil { t.Fatalf(""NewCertSigner: %v"", err) } conf := &ssh.ClientConfig{ User: username(), HostKeyCallback: ssh.InsecureIgnoreHostKey(), } conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner)) client, err := s.TryDial(conf) if err != nil { t.Fatalf(""TryDial: %v"", err) } client.Close() }" 187,"func TestSetupForwardAgent(t *testing.T) { a, b, err := netPipe() if err != nil { t.Fatalf(""netPipe: %v"", err) } defer a.Close() defer b.Close() _, socket, cleanup := startAgent(t) defer cleanup() serverConf := ssh.ServerConfig{ NoClientAuth: true, } serverConf.AddHostKey(testSigners[""rsa""]) incoming := make(chan *ssh.ServerConn, 1) go func() { conn, _, _, err := ssh.NewServerConn(a, &serverConf) if err != nil { t.Fatalf(""Server: %v"", err) } incoming <- conn }() conf := ssh.ClientConfig{} conn, chans, reqs, err := ssh.NewClientConn(b, """", &conf) if err != nil { t.Fatalf(""NewClientConn: %v"", err) } client := ssh.NewClient(conn, chans, reqs) if err := ForwardToRemote(client, socket); err != nil { t.Fatalf(""SetupForwardAgent: %v"", err) } server := <-incoming ch, reqs, err := server.OpenChannel(channelType, nil) if err != nil { t.Fatalf(""OpenChannel(%q): %v"", channelType, err) } go ssh.DiscardRequests(reqs) agentClient := NewClient(ch) testAgentInterface(t, agentClient, testPrivateKeys[""rsa""], nil, 0) conn.Close() }",True,Go,TestSetupForwardAgent,server_test.go,https://github.com/golang/crypto,golang,Han-Wen Nienhuys,2017-03-30 15:57:35+00:00,"ssh: require host key checking in the ClientConfig This change breaks existing behavior. Before, a missing ClientConfig.HostKeyCallback would cause host key checking to be disabled. In this configuration, establishing a connection to any host just works, so today, most SSH client code in the wild does not perform any host key checks. This makes it easy to perform a MITM attack: * SSH installations that use keyboard-interactive or password authentication can be attacked with MITM, thereby stealing passwords. * Clients that use public-key authentication with agent forwarding are also vulnerable: the MITM server could allow the login to succeed, and then immediately ask the agent to authenticate the login to the real server. * Clients that use public-key authentication without agent forwarding are harder to attack unnoticedly: an attacker cannot authenticate the login to the real server, so it cannot in general present a convincing server to the victim. Now, a missing HostKeyCallback will cause the handshake to fail. This change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as ready made host checkers. A simplistic parser for OpenSSH's known_hosts file is given as an example. This change does not provide a full-fledged parser, as it has complexity (wildcards, revocation, hashed addresses) that will need further consideration. When introduced, the host checking feature maintained backward compatibility at the expense of security. We have decided this is not the right tradeoff for the SSH library. Fixes golang/go#19767 Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814 Reviewed-on: https://go-review.googlesource.com/38701 Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick ",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2017-3204,"static void cmd_sdbk(Sdb *db, const char *input) { const char *arg = (input[0] == ' ')? input + 1: ""*""; char *out = sdb_querys (db, NULL, 0, arg); if (out) { r_cons_println (out); free (out); } else { R_LOG_ERROR (""Usage: ask [query]""); } }" 193,"func ExampleRetryableAuthMethod(t *testing.T) { user := ""testuser"" NumberOfPrompts := 3 Cb := func(user, instruction string, questions []string, echos []bool) (answers []string, err error) { return []string{""answer1"", ""answer2""}, nil } config := &ClientConfig{ User: user, Auth: []AuthMethod{ RetryableAuthMethod(KeyboardInteractiveChallenge(Cb), NumberOfPrompts), }, } if err := tryAuth(t, config); err != nil { t.Fatalf(""unable to dial remote side: %s"", err) } }",True,Go,ExampleRetryableAuthMethod,client_auth_test.go,https://github.com/golang/crypto,golang,Han-Wen Nienhuys,2017-03-30 15:57:35+00:00,"ssh: require host key checking in the ClientConfig This change breaks existing behavior. Before, a missing ClientConfig.HostKeyCallback would cause host key checking to be disabled. In this configuration, establishing a connection to any host just works, so today, most SSH client code in the wild does not perform any host key checks. This makes it easy to perform a MITM attack: * SSH installations that use keyboard-interactive or password authentication can be attacked with MITM, thereby stealing passwords. * Clients that use public-key authentication with agent forwarding are also vulnerable: the MITM server could allow the login to succeed, and then immediately ask the agent to authenticate the login to the real server. * Clients that use public-key authentication without agent forwarding are harder to attack unnoticedly: an attacker cannot authenticate the login to the real server, so it cannot in general present a convincing server to the victim. Now, a missing HostKeyCallback will cause the handshake to fail. This change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as ready made host checkers. A simplistic parser for OpenSSH's known_hosts file is given as an example. This change does not provide a full-fledged parser, as it has complexity (wildcards, revocation, hashed addresses) that will need further consideration. When introduced, the host checking feature maintained backward compatibility at the expense of security. We have decided this is not the right tradeoff for the SSH library. Fixes golang/go#19767 Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814 Reviewed-on: https://go-review.googlesource.com/38701 Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick ",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2017-3204,"static void cmd_anal_ucall_ref(RCore *core, ut64 addr) { RAnalFunction *fcn = r_anal_get_function_at (core->anal, addr); if (fcn) { r_cons_printf ("" ; %s"", fcn->name); } else { r_cons_printf ("" ; 0x%"" PFMT64x, addr); } }" 195,"func TestClientAuthNone(t *testing.T) { user := ""testuser"" serverConfig := &ServerConfig{ NoClientAuth: true, } serverConfig.AddHostKey(testSigners[""rsa""]) clientConfig := &ClientConfig{ User: user, } c1, c2, err := netPipe() if err != nil { t.Fatalf(""netPipe: %v"", err) } defer c1.Close() defer c2.Close() go NewClientConn(c2, """", clientConfig) serverConn, err := newServer(c1, serverConfig) if err != nil { t.Fatalf(""newServer: %v"", err) } if serverConn.User() != user { t.Fatalf(""server: got %q, want %q"", serverConn.User(), user) } }",True,Go,TestClientAuthNone,client_auth_test.go,https://github.com/golang/crypto,golang,Han-Wen Nienhuys,2017-03-30 15:57:35+00:00,"ssh: require host key checking in the ClientConfig This change breaks existing behavior. Before, a missing ClientConfig.HostKeyCallback would cause host key checking to be disabled. In this configuration, establishing a connection to any host just works, so today, most SSH client code in the wild does not perform any host key checks. This makes it easy to perform a MITM attack: * SSH installations that use keyboard-interactive or password authentication can be attacked with MITM, thereby stealing passwords. * Clients that use public-key authentication with agent forwarding are also vulnerable: the MITM server could allow the login to succeed, and then immediately ask the agent to authenticate the login to the real server. * Clients that use public-key authentication without agent forwarding are harder to attack unnoticedly: an attacker cannot authenticate the login to the real server, so it cannot in general present a convincing server to the victim. Now, a missing HostKeyCallback will cause the handshake to fail. This change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as ready made host checkers. A simplistic parser for OpenSSH's known_hosts file is given as an example. This change does not provide a full-fledged parser, as it has complexity (wildcards, revocation, hashed addresses) that will need further consideration. When introduced, the host checking feature maintained backward compatibility at the expense of security. We have decided this is not the right tradeoff for the SSH library. Fixes golang/go#19767 Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814 Reviewed-on: https://go-review.googlesource.com/38701 Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick ",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2017-3204,"static void _anal_calls(RCore *core, ut64 addr, ut64 addr_end, bool printCommands, bool importsOnly) { RAnalOp op = {0}; int depth = r_config_get_i (core->config, ""anal.depth""); const int addrbytes = core->io->addrbytes; const int bsz = 4096; int bufi = 0; int bufi_max = bsz - 16; if (addr_end - addr > UT32_MAX) { return; } ut8 *buf = malloc (bsz); ut8 *block0 = calloc (1, bsz); ut8 *block1 = malloc (bsz); if (!buf || !block0 || !block1) { free (buf); free (block0); free (block1); return; } memset (block1, -1, bsz); int minop = r_anal_archinfo (core->anal, R_ANAL_ARCHINFO_MIN_OP_SIZE); if (minop < 1) { minop = 1; } int setBits = r_config_get_i (core->config, ""asm.bits""); r_cons_break_push (NULL, NULL); while (addr < addr_end && !r_cons_is_breaked ()) { if (bufi > bufi_max) { bufi = 0; } if (!bufi) { (void)r_io_read_at (core->io, addr, buf, bsz); } if (!memcmp (buf, block0, bsz) || !memcmp (buf, block1, bsz)) { addr += bsz; continue; } RAnalHint *hint = r_anal_hint_get (core->anal, addr); if (hint && hint->bits) { setBits = hint->bits; } r_anal_hint_free (hint); if (setBits != core->rasm->config->bits) { r_config_set_i (core->config, ""asm.bits"", setBits); } if (r_anal_op (core->anal, &op, addr, buf + bufi, bsz - bufi, 0) > 0) { if (op.size < 1) { op.size = minop; } if (op.type == R_ANAL_OP_TYPE_CALL) { bool isValidCall = true; if (importsOnly) { RFlagItem *f = r_flag_get_i (core->flags, op.jump); if (!f || !strstr (f->name, ""imp."")) { isValidCall = false; } } RBinReloc *rel = r_core_getreloc (core, addr, op.size); if (rel && (rel->import || rel->symbol)) { isValidCall = false; } if (isValidCall) { ut8 zbuf[4] = {0}; r_io_read_at (core->io, op.jump, zbuf, 4); isValidCall = memcmp (zbuf, ""\x00\x00\x00\x00"", 4); } if (isValidCall) { #if JAYRO_03 if (!anal_is_bad_call (core, from, to, addr, buf, bufi)) { fcn = r_anal_get_fcn_in (core->anal, op.jump, R_ANAL_FCN_TYPE_ROOT); if (!fcn) { r_core_anal_fcn (core, op.jump, addr, R_ANAL_REF_TYPE_CALL, depth - 1); } } #else if (printCommands) { r_cons_printf (""ax 0x%08"" PFMT64x "" 0x%08"" PFMT64x ""\n"", op.jump, addr); r_cons_printf (""af @ 0x%08"" PFMT64x""\n"", op.jump); } else { r_anal_xrefs_set (core->anal, addr, op.jump, R_ANAL_REF_TYPE_CALL); if (r_io_is_valid_offset (core->io, op.jump, 1)) { r_core_anal_fcn (core, op.jump, addr, R_ANAL_REF_TYPE_CALL, depth - 1); } } #endif } } } else { op.size = minop; } if ((int)op.size < 1) { op.size = minop; } addr += op.size; bufi += addrbytes * op.size; r_anal_op_fini (&op); } r_cons_break_pop (); free (buf); free (block0); free (block1); }" 201,"func TestClientLoginCert(t *testing.T) { cert := &Certificate{ Key: testPublicKeys[""rsa""], ValidBefore: CertTimeInfinity, CertType: UserCert, } cert.SignCert(rand.Reader, testSigners[""ecdsa""]) certSigner, err := NewCertSigner(cert, testSigners[""rsa""]) if err != nil { t.Fatalf(""NewCertSigner: %v"", err) } clientConfig := &ClientConfig{ User: ""user"", } clientConfig.Auth = append(clientConfig.Auth, PublicKeys(certSigner)) if err := tryAuth(t, clientConfig); err != nil { t.Errorf(""cert login failed: %v"", err) } cert.Signature.Blob[0]++ if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login passed with corrupted sig"") } cert.Serial = 666 cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""revoked cert login succeeded"") } cert.Serial = 1 cert.SignCert(rand.Reader, testSigners[""dsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login passed with non-authoritative key"") } cert.CertType = HostCert cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login passed with wrong type"") } cert.CertType = UserCert cert.ValidPrincipals = []string{""user""} cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err != nil { t.Errorf(""cert login failed: %v"", err) } cert.ValidPrincipals = []string{""fred""} cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login passed with wrong principal"") } cert.ValidPrincipals = nil cert.CriticalOptions = map[string]string{""root-access"": ""yes""} cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login passed with unrecognized critical option"") } cert.CriticalOptions = map[string]string{""source-address"": ""127.0.0.42/24,::42/120""} cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err != nil { t.Errorf(""cert login with source-address failed: %v"", err) } cert.CriticalOptions = map[string]string{""source-address"": ""127.0.0.42,::42""} cert.SignCert(rand.Reader, testSigners[""ecdsa""]) if err := tryAuth(t, clientConfig); err == nil { t.Errorf(""cert login with source-address succeeded"") } }",True,Go,TestClientLoginCert,client_auth_test.go,https://github.com/golang/crypto,golang,Han-Wen Nienhuys,2017-03-30 15:57:35+00:00,"ssh: require host key checking in the ClientConfig This change breaks existing behavior. Before, a missing ClientConfig.HostKeyCallback would cause host key checking to be disabled. In this configuration, establishing a connection to any host just works, so today, most SSH client code in the wild does not perform any host key checks. This makes it easy to perform a MITM attack: * SSH installations that use keyboard-interactive or password authentication can be attacked with MITM, thereby stealing passwords. * Clients that use public-key authentication with agent forwarding are also vulnerable: the MITM server could allow the login to succeed, and then immediately ask the agent to authenticate the login to the real server. * Clients that use public-key authentication without agent forwarding are harder to attack unnoticedly: an attacker cannot authenticate the login to the real server, so it cannot in general present a convincing server to the victim. Now, a missing HostKeyCallback will cause the handshake to fail. This change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as ready made host checkers. A simplistic parser for OpenSSH's known_hosts file is given as an example. This change does not provide a full-fledged parser, as it has complexity (wildcards, revocation, hashed addresses) that will need further consideration. When introduced, the host checking feature maintained backward compatibility at the expense of security. We have decided this is not the right tradeoff for the SSH library. Fixes golang/go#19767 Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814 Reviewed-on: https://go-review.googlesource.com/38701 Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick ",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2017-3204,"static bool anal_fcn_data (RCore *core, const char *input) { RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, R_ANAL_FCN_TYPE_ANY); if (fcn) { int i; bool gap = false; ut64 gap_addr = UT64_MAX; ut32 fcn_size = r_anal_function_size_from_entry (fcn); char *bitmap = calloc (1, fcn_size); if (bitmap) { RAnalBlock *b; RListIter *iter; r_list_foreach (fcn->bbs, iter, b) { int f = b->addr - fcn->addr; int t = R_MIN (f + b->size, fcn_size); if (f >= 0) { while (f < t) { bitmap[f++] = 1; } } } } for (i = 0; i < fcn_size; i++) { ut64 here = fcn->addr + i; if (bitmap && bitmap[i]) { if (gap) { r_cons_printf (""Cd %d @ 0x%08""PFMT64x""\n"", here - gap_addr, gap_addr); gap = false; } gap_addr = UT64_MAX; } else { if (!gap) { gap = true; gap_addr = here; } } } if (gap) { r_cons_printf (""Cd %d @ 0x%08""PFMT64x""\n"", fcn->addr + fcn_size - gap_addr, gap_addr); } free (bitmap); return true; } return false; }" 213,"func ExampleNewServerConn() { authorizedKeysBytes, err := ioutil.ReadFile(""authorized_keys"") if err != nil { log.Fatalf(""Failed to load authorized_keys, err: %v"", err) } authorizedKeysMap := map[string]bool{} for len(authorizedKeysBytes) > 0 { pubKey, _, _, rest, err := ssh.ParseAuthorizedKey(authorizedKeysBytes) if err != nil { log.Fatal(err) } authorizedKeysMap[string(pubKey.Marshal())] = true authorizedKeysBytes = rest } config := &ssh.ServerConfig{ PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) { if c.User() == ""testuser"" && string(pass) == ""tiger"" { return nil, nil } return nil, fmt.Errorf(""password rejected for %q"", c.User()) }, PublicKeyCallback: func(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) { if authorizedKeysMap[string(pubKey.Marshal())] { return nil, nil } return nil, fmt.Errorf(""unknown public key for %q"", c.User()) }, } privateBytes, err := ioutil.ReadFile(""id_rsa"") if err != nil { log.Fatal(""Failed to load private key: "", err) } private, err := ssh.ParsePrivateKey(privateBytes) if err != nil { log.Fatal(""Failed to parse private key: "", err) } config.AddHostKey(private) listener, err := net.Listen(""tcp"", ""0.0.0.0:2022"") if err != nil { log.Fatal(""failed to listen for connection: "", err) } nConn, err := listener.Accept() if err != nil { log.Fatal(""failed to accept incoming connection: "", err) } _, chans, reqs, err := ssh.NewServerConn(nConn, config) if err != nil { log.Fatal(""failed to handshake: "", err) } go ssh.DiscardRequests(reqs) for newChannel := range chans { if newChannel.ChannelType() != ""session"" { newChannel.Reject(ssh.UnknownChannelType, ""unknown channel type"") continue } channel, requests, err := newChannel.Accept() if err != nil { log.Fatalf(""Could not accept channel: %v"", err) } go func(in <-chan *ssh.Request) { for req := range in { req.Reply(req.Type == ""shell"", nil) } }(requests) term := terminal.NewTerminal(channel, ""> "") go func() { defer channel.Close() for { line, err := term.ReadLine() if err != nil { break } fmt.Println(line) } }() } }",True,Go,ExampleNewServerConn,example_test.go,https://github.com/golang/crypto,golang,Han-Wen Nienhuys,2017-03-30 15:57:35+00:00,"ssh: require host key checking in the ClientConfig This change breaks existing behavior. Before, a missing ClientConfig.HostKeyCallback would cause host key checking to be disabled. In this configuration, establishing a connection to any host just works, so today, most SSH client code in the wild does not perform any host key checks. This makes it easy to perform a MITM attack: * SSH installations that use keyboard-interactive or password authentication can be attacked with MITM, thereby stealing passwords. * Clients that use public-key authentication with agent forwarding are also vulnerable: the MITM server could allow the login to succeed, and then immediately ask the agent to authenticate the login to the real server. * Clients that use public-key authentication without agent forwarding are harder to attack unnoticedly: an attacker cannot authenticate the login to the real server, so it cannot in general present a convincing server to the victim. Now, a missing HostKeyCallback will cause the handshake to fail. This change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as ready made host checkers. A simplistic parser for OpenSSH's known_hosts file is given as an example. This change does not provide a full-fledged parser, as it has complexity (wildcards, revocation, hashed addresses) that will need further consideration. When introduced, the host checking feature maintained backward compatibility at the expense of security. We have decided this is not the right tradeoff for the SSH library. Fixes golang/go#19767 Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814 Reviewed-on: https://go-review.googlesource.com/38701 Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick ",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2017-3204,"func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, ""AddUser"") defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) vars := mux.Vars(r) accessKey := vars[""accessKey""] objectAPI := newObjectLayerFn() if objectAPI == nil || globalNotificationSys == nil { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) return } cred, claims, owner, s3Err := validateAdminSignature(ctx, r, """") if s3Err != ErrNone { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL) return } if owner && accessKey == cred.AccessKey { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAddUserInvalidArgument), r.URL) return } userCred, exists := globalIAMSys.GetUser(ctx, accessKey) if exists && (userCred.IsTemp() || userCred.IsServiceAccount()) { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAddUserInvalidArgument), r.URL) return } if (cred.IsTemp() || cred.IsServiceAccount()) && cred.ParentUser == accessKey { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAddUserInvalidArgument), r.URL) return } checkDenyOnly := false if accessKey == cred.AccessKey { checkDenyOnly = true } if !globalIAMSys.IsAllowed(iampolicy.Args{ AccountName: cred.AccessKey, Groups: cred.Groups, Action: iampolicy.CreateUserAdminAction, ConditionValues: getConditionValues(r, """", cred.AccessKey, claims), IsOwner: owner, Claims: claims, DenyOnly: checkDenyOnly, }) { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAccessDenied), r.URL) return } if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL) return } password := cred.SecretKey configBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength)) if err != nil { logger.LogIf(ctx, err) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) return } var ureq madmin.AddOrUpdateUserReq if err = json.Unmarshal(configBytes, &ureq); err != nil { logger.LogIf(ctx, err) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) return } if err = globalIAMSys.CreateUser(ctx, accessKey, ureq); err != nil { writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } }" 216,"func (t *handshakeTransport) client(kex kexAlgorithm, algs *algorithms, magics *handshakeMagics) (*kexResult, error) { result, err := kex.Client(t.conn, t.config.Rand, magics) if err != nil { return nil, err } hostKey, err := ParsePublicKey(result.HostKey) if err != nil { return nil, err } if err := verifyHostKeySignature(hostKey, result); err != nil { return nil, err } if t.hostKeyCallback != nil { err = t.hostKeyCallback(t.dialAddress, t.remoteAddr, hostKey) if err != nil { return nil, err } } return result, nil }",True,Go,client,handshake.go,https://github.com/golang/crypto,golang,Han-Wen Nienhuys,2017-03-30 15:57:35+00:00,"ssh: require host key checking in the ClientConfig This change breaks existing behavior. Before, a missing ClientConfig.HostKeyCallback would cause host key checking to be disabled. In this configuration, establishing a connection to any host just works, so today, most SSH client code in the wild does not perform any host key checks. This makes it easy to perform a MITM attack: * SSH installations that use keyboard-interactive or password authentication can be attacked with MITM, thereby stealing passwords. * Clients that use public-key authentication with agent forwarding are also vulnerable: the MITM server could allow the login to succeed, and then immediately ask the agent to authenticate the login to the real server. * Clients that use public-key authentication without agent forwarding are harder to attack unnoticedly: an attacker cannot authenticate the login to the real server, so it cannot in general present a convincing server to the victim. Now, a missing HostKeyCallback will cause the handshake to fail. This change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as ready made host checkers. A simplistic parser for OpenSSH's known_hosts file is given as an example. This change does not provide a full-fledged parser, as it has complexity (wildcards, revocation, hashed addresses) that will need further consideration. When introduced, the host checking feature maintained backward compatibility at the expense of security. We have decided this is not the right tradeoff for the SSH library. Fixes golang/go#19767 Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814 Reviewed-on: https://go-review.googlesource.com/38701 Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick ",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2017-3204,"func (sys *IAMSys) CreateUser(ctx context.Context, accessKey string, ureq madmin.AddOrUpdateUserReq) error { if !sys.Initialized() { return errServerNotInitialized } if sys.usersSysType != MinIOUsersSysType { return errIAMActionNotAllowed } if !auth.IsAccessKeyValid(accessKey) { return auth.ErrInvalidAccessKeyLength } if !auth.IsSecretKeyValid(ureq.SecretKey) { return auth.ErrInvalidSecretKeyLength } err := sys.store.AddUser(ctx, accessKey, ureq) if err != nil { return err } sys.notifyForUser(ctx, accessKey, false) return nil }" 219,"func TestSessionID(t *testing.T) { c1, c2, err := netPipe() if err != nil { t.Fatalf(""netPipe: %v"", err) } defer c1.Close() defer c2.Close() serverID := make(chan []byte, 1) clientID := make(chan []byte, 1) serverConf := &ServerConfig{ NoClientAuth: true, } serverConf.AddHostKey(testSigners[""ecdsa""]) clientConf := &ClientConfig{ User: ""user"", } go func() { conn, chans, reqs, err := NewServerConn(c1, serverConf) if err != nil { t.Fatalf(""server handshake: %v"", err) } serverID <- conn.SessionID() go DiscardRequests(reqs) for ch := range chans { ch.Reject(Prohibited, """") } }() go func() { conn, chans, reqs, err := NewClientConn(c2, """", clientConf) if err != nil { t.Fatalf(""client handshake: %v"", err) } clientID <- conn.SessionID() go DiscardRequests(reqs) for ch := range chans { ch.Reject(Prohibited, """") } }() s := <-serverID c := <-clientID if bytes.Compare(s, c) != 0 { t.Errorf(""server session ID (%x) != client session ID (%x)"", s, c) } else if len(s) == 0 { t.Errorf(""client and server SessionID were empty."") } }",True,Go,TestSessionID,session_test.go,https://github.com/golang/crypto,golang,Han-Wen Nienhuys,2017-03-30 15:57:35+00:00,"ssh: require host key checking in the ClientConfig This change breaks existing behavior. Before, a missing ClientConfig.HostKeyCallback would cause host key checking to be disabled. In this configuration, establishing a connection to any host just works, so today, most SSH client code in the wild does not perform any host key checks. This makes it easy to perform a MITM attack: * SSH installations that use keyboard-interactive or password authentication can be attacked with MITM, thereby stealing passwords. * Clients that use public-key authentication with agent forwarding are also vulnerable: the MITM server could allow the login to succeed, and then immediately ask the agent to authenticate the login to the real server. * Clients that use public-key authentication without agent forwarding are harder to attack unnoticedly: an attacker cannot authenticate the login to the real server, so it cannot in general present a convincing server to the victim. Now, a missing HostKeyCallback will cause the handshake to fail. This change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as ready made host checkers. A simplistic parser for OpenSSH's known_hosts file is given as an example. This change does not provide a full-fledged parser, as it has complexity (wildcards, revocation, hashed addresses) that will need further consideration. When introduced, the host checking feature maintained backward compatibility at the expense of security. We have decided this is not the right tradeoff for the SSH library. Fixes golang/go#19767 Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814 Reviewed-on: https://go-review.googlesource.com/38701 Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick ",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2017-3204,"func TestCheckValid(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() objLayer, fsDir, err := prepareFS() if err != nil { t.Fatal(err) } defer os.RemoveAll(fsDir) if err = newTestConfig(globalMinioDefaultRegion, objLayer); err != nil { t.Fatalf(""unable initialize config file, %s"", err) } newAllSubsystems() initConfigSubsystem(ctx, objLayer) globalIAMSys.Init(ctx, objLayer, globalEtcdClient, globalNotificationSys, 2*time.Second) req, err := newTestRequest(http.MethodGet, ""http: if err != nil { t.Fatal(err) } if err = signRequestV4(req, globalActiveCred.AccessKey, globalActiveCred.SecretKey); err != nil { t.Fatal(err) } _, owner, s3Err := checkKeyValid(req, globalActiveCred.AccessKey) if s3Err != ErrNone { t.Fatalf(""Unexpected failure with %v"", errorCodes.ToAPIErr(s3Err)) } if !owner { t.Fatalf(""Expected owner to be 'true', found %t"", owner) } _, _, s3Err = checkKeyValid(req, ""does-not-exist"") if s3Err != ErrInvalidAccessKeyID { t.Fatalf(""Expected error 'ErrInvalidAccessKeyID', found %v"", s3Err) } ucreds, err := auth.CreateCredentials(""myuser1"", ""mypassword1"") if err != nil { t.Fatalf(""unable create credential, %s"", err) } globalIAMSys.CreateUser(ctx, ucreds.AccessKey, madmin.AddOrUpdateUserReq{ SecretKey: ucreds.SecretKey, Status: madmin.AccountEnabled, }) _, owner, s3Err = checkKeyValid(req, ucreds.AccessKey) if s3Err != ErrNone { t.Fatalf(""Unexpected failure with %v"", errorCodes.ToAPIErr(s3Err)) } if owner { t.Fatalf(""Expected owner to be 'false', found %t"", owner) } }" 221,"func TestCertLogin(t *testing.T) { s := newServer(t) defer s.Shutdown() clientKey := testSigners[""dsa""] caAuthKey := testSigners[""ecdsa""] cert := &ssh.Certificate{ Key: clientKey.PublicKey(), ValidPrincipals: []string{username()}, CertType: ssh.UserCert, ValidBefore: ssh.CertTimeInfinity, } if err := cert.SignCert(rand.Reader, caAuthKey); err != nil { t.Fatalf(""SetSignature: %v"", err) } certSigner, err := ssh.NewCertSigner(cert, clientKey) if err != nil { t.Fatalf(""NewCertSigner: %v"", err) } conf := &ssh.ClientConfig{ User: username(), } conf.Auth = append(conf.Auth, ssh.PublicKeys(certSigner)) client, err := s.TryDial(conf) if err != nil { t.Fatalf(""TryDial: %v"", err) } client.Close() }",True,Go,TestCertLogin,cert_test.go,https://github.com/golang/crypto,golang,Han-Wen Nienhuys,2017-03-30 15:57:35+00:00,"ssh: require host key checking in the ClientConfig This change breaks existing behavior. Before, a missing ClientConfig.HostKeyCallback would cause host key checking to be disabled. In this configuration, establishing a connection to any host just works, so today, most SSH client code in the wild does not perform any host key checks. This makes it easy to perform a MITM attack: * SSH installations that use keyboard-interactive or password authentication can be attacked with MITM, thereby stealing passwords. * Clients that use public-key authentication with agent forwarding are also vulnerable: the MITM server could allow the login to succeed, and then immediately ask the agent to authenticate the login to the real server. * Clients that use public-key authentication without agent forwarding are harder to attack unnoticedly: an attacker cannot authenticate the login to the real server, so it cannot in general present a convincing server to the victim. Now, a missing HostKeyCallback will cause the handshake to fail. This change also provides InsecureIgnoreHostKey() and FixedHostKey(key) as ready made host checkers. A simplistic parser for OpenSSH's known_hosts file is given as an example. This change does not provide a full-fledged parser, as it has complexity (wildcards, revocation, hashed addresses) that will need further consideration. When introduced, the host checking feature maintained backward compatibility at the expense of security. We have decided this is not the right tradeoff for the SSH library. Fixes golang/go#19767 Change-Id: I45fc7ba9bd1ea29c31ec23f115cdbab99913e814 Reviewed-on: https://go-review.googlesource.com/38701 Run-TryBot: Han-Wen Nienhuys TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick ",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2017-3204,"func getClaimsFromToken(token string) (map[string]interface{}, error) {" 223,"getReturnAddressWithDisplayName(identityId) { check(identityId, String); const identity = this.getIdentity(identityId); const displayName = identity.profile.name + "" (via "" + this.getServerTitle() + "")""; const sanitized = displayName.replace(/""|<|>|\\|\r/g, """"); return ""\"""" + sanitized + ""\"" <"" + this.getReturnAddress() + "">""; },",True,Go,getReturnAddressWithDisplayName,db.js,https://github.com/sandstorm-io/sandstorm,sandstorm-io,Kenton Varda,2017-03-01 14:23:15-08:00,Validate e-mail addresses more strictly.,CWE-287,Improper Authentication,"When an actor claims to have a given identity, the product does not prove or insufficiently proves that the claim is correct.",https://cwe.mitre.org/data/definitions/287.html,CVE-2017-6199,"func doesPolicySignatureV2Match(formValues http.Header) (auth.Credentials, APIErrorCode) { accessKey := formValues.Get(xhttp.AmzAccessKeyID) cred, _, s3Err := checkKeyValid(accessKey) if s3Err != ErrNone { return cred, s3Err } policy := formValues.Get(""Policy"") signature := formValues.Get(xhttp.AmzSignatureV2) if !compareSignatureV2(signature, calculateSignatureV2(policy, cred.SecretKey)) { return cred, ErrSignatureDoesNotMatch } return cred, ErrNone }" 227,"static void cmd_sdbk(Sdb *db, const char *input) { char *out = (input[0] == ' ') ? sdb_querys (db, NULL, 0, input + 1) : sdb_querys (db, NULL, 0, ""*""); if (out) { r_cons_println (out); free (out); } else { R_LOG_ERROR (""Usage: ask [query]""); } }",True,Go,cmd_sdbk,cmd_anal.c,https://github.com/radareorg/radare2,radareorg,pancake,2023-08-14 16:33:25+02:00,"Fix 1byte heap oobread in the brainfuck disassembler * https://huntr.dev/bounties/06e2484c-d6f1-4497-af67-26549be9fffd/ * Kudos to @7resp4ss for reporting",CWE-787,Out-of-bounds Write,"The product writes data past the end, or before the beginning, of the intended buffer.",https://cwe.mitre.org/data/definitions/787.html,CVE-2023-4322,"func TestDoesPolicySignatureV2Match(t *testing.T) { obj, fsDir, err := prepareFS() if err != nil { t.Fatal(err) } defer os.RemoveAll(fsDir) if err = newTestConfig(globalMinioDefaultRegion, obj); err != nil { t.Fatal(err) } creds := globalActiveCred policy := ""policy"" testCases := []struct { accessKey string policy string signature string errCode APIErrorCode }{ {""invalidAccessKey"", policy, calculateSignatureV2(policy, creds.SecretKey), ErrInvalidAccessKeyID}, {creds.AccessKey, policy, calculateSignatureV2(""random"", creds.SecretKey), ErrSignatureDoesNotMatch}, {creds.AccessKey, policy, calculateSignatureV2(policy, creds.SecretKey), ErrNone}, } for i, test := range testCases { formValues := make(http.Header) formValues.Set(""Awsaccesskeyid"", test.accessKey) formValues.Set(""Signature"", test.signature) formValues.Set(""Policy"", test.policy) _, errCode := doesPolicySignatureV2Match(formValues) if errCode != test.errCode { t.Fatalf(""(%d) expected to get %s, instead got %s"", i+1, niceError(test.errCode), niceError(errCode)) } } }" 228,"static void axfm(RCore *core) { RVecAnalRef *refs = r_anal_xrefs_get_from (core->anal, UT64_MAX); if (refs && !RVecAnalRef_empty (refs)) { RVecAnalRef_sort (refs, compare_ref); ut64 last_addr = UT64_MAX; RAnalRef *ref; R_VEC_FOREACH (refs, ref) { const bool is_first = ref->addr != last_addr; const char *name; if (is_first) { name = axtm_name (core, ref->addr); r_cons_printf (""0x%""PFMT64x"": %s\n"", ref->addr, name? name: ""?""); } name = axtm_name (core, ref->at); r_cons_printf ("" 0x%""PFMT64x"": %s\n"", ref->at, name? name: ""?""); last_addr = ref->addr; } } RVecAnalRef_free (refs); }",True,Go,axfm,cmd_anal.c,https://github.com/radareorg/radare2,radareorg,pancake,2023-08-14 16:33:25+02:00,"Fix 1byte heap oobread in the brainfuck disassembler * https://huntr.dev/bounties/06e2484c-d6f1-4497-af67-26549be9fffd/ * Kudos to @7resp4ss for reporting",CWE-787,Out-of-bounds Write,"The product writes data past the end, or before the beginning, of the intended buffer.",https://cwe.mitre.org/data/definitions/787.html,CVE-2023-4322,"func doesPolicySignatureV4Match(formValues http.Header) (auth.Credentials, APIErrorCode) { region := globalServerRegion credHeader, s3Err := parseCredentialHeader(""Credential=""+formValues.Get(xhttp.AmzCredential), region, serviceS3) if s3Err != ErrNone { return auth.Credentials{}, s3Err } cred, _, s3Err := checkKeyValid(credHeader.accessKey) if s3Err != ErrNone { return cred, s3Err } signingKey := getSigningKey(cred.SecretKey, credHeader.scope.date, credHeader.scope.region, serviceS3) newSignature := getSignature(signingKey, formValues.Get(""Policy"")) if !compareSignatureV4(newSignature, formValues.Get(xhttp.AmzSignature)) { return cred, ErrSignatureDoesNotMatch } return cred, ErrNone }" 229,"static void cmd_anal_ucall_ref(RCore *core, ut64 addr) { RAnalFunction * fcn = r_anal_get_function_at (core->anal, addr); if (fcn) { r_cons_printf ("" ; %s"", fcn->name); } else { r_cons_printf ("" ; 0x%"" PFMT64x, addr); } }",True,Go,cmd_anal_ucall_ref,cmd_anal.c,https://github.com/radareorg/radare2,radareorg,pancake,2023-08-14 16:33:25+02:00,"Fix 1byte heap oobread in the brainfuck disassembler * https://huntr.dev/bounties/06e2484c-d6f1-4497-af67-26549be9fffd/ * Kudos to @7resp4ss for reporting",CWE-787,Out-of-bounds Write,"The product writes data past the end, or before the beginning, of the intended buffer.",https://cwe.mitre.org/data/definitions/787.html,CVE-2023-4322,"func doesPolicySignatureMatch(formValues http.Header) (auth.Credentials, APIErrorCode) { if _, ok := formValues[""Signature""]; ok { return doesPolicySignatureV2Match(formValues) } return doesPolicySignatureV4Match(formValues) }" 230,"static void _anal_calls(RCore *core, ut64 addr, ut64 addr_end, bool printCommands, bool importsOnly) { RAnalOp op = {0}; int depth = r_config_get_i (core->config, ""anal.depth""); const int addrbytes = core->io->addrbytes; const int bsz = 4096; int bufi = 0; int bufi_max = bsz - 16; if (addr_end - addr > UT32_MAX) { return; } ut8 *buf = malloc (bsz); ut8 *block0 = calloc (1, bsz); ut8 *block1 = malloc (bsz); if (!buf || !block0 || !block1) { free (buf); free (block0); free (block1); return; } memset (block1, -1, bsz); int minop = r_anal_archinfo (core->anal, R_ANAL_ARCHINFO_MIN_OP_SIZE); if (minop < 1) { minop = 1; } int setBits = r_config_get_i (core->config, ""asm.bits""); r_cons_break_push (NULL, NULL); while (addr < addr_end && !r_cons_is_breaked ()) { if (bufi > bufi_max) { bufi = 0; } if (!bufi) { (void)r_io_read_at (core->io, addr, buf, bsz); } if (!memcmp (buf, block0, bsz) || !memcmp (buf, block1, bsz)) { addr += bsz; continue; } RAnalHint *hint = r_anal_hint_get (core->anal, addr); if (hint && hint->bits) { setBits = hint->bits; } r_anal_hint_free (hint); if (setBits != core->rasm->config->bits) { r_config_set_i (core->config, ""asm.bits"", setBits); } if (r_anal_op (core->anal, &op, addr, buf + bufi, bsz - bufi, 0) > 0) { if (op.size < 1) { op.size = minop; } if (op.type == R_ANAL_OP_TYPE_CALL) { bool isValidCall = true; if (importsOnly) { RFlagItem *f = r_flag_get_i (core->flags, op.jump); if (!f || !strstr (f->name, ""imp."")) { isValidCall = false; } } RBinReloc *rel = r_core_getreloc (core, addr, op.size); if (rel && (rel->import || rel->symbol)) { isValidCall = false; } if (isValidCall) { ut8 buf[4] = {0}; r_io_read_at (core->io, op.jump, buf, 4); isValidCall = memcmp (buf, ""\x00\x00\x00\x00"", 4); } if (isValidCall) { #if JAYRO_03 if (!anal_is_bad_call (core, from, to, addr, buf, bufi)) { fcn = r_anal_get_fcn_in (core->anal, op.jump, R_ANAL_FCN_TYPE_ROOT); if (!fcn) { r_core_anal_fcn (core, op.jump, addr, R_ANAL_REF_TYPE_CALL, depth - 1); } } #else if (printCommands) { r_cons_printf (""ax 0x%08"" PFMT64x "" 0x%08"" PFMT64x ""\n"", op.jump, addr); r_cons_printf (""af @ 0x%08"" PFMT64x""\n"", op.jump); } else { r_anal_xrefs_set (core->anal, addr, op.jump, R_ANAL_REF_TYPE_CALL); if (r_io_is_valid_offset (core->io, op.jump, 1)) { r_core_anal_fcn (core, op.jump, addr, R_ANAL_REF_TYPE_CALL, depth - 1); } } #endif } } } else { op.size = minop; } if ((int)op.size < 1) { op.size = minop; } addr += op.size; bufi += addrbytes * op.size; r_anal_op_fini (&op); } r_cons_break_pop (); free (buf); free (block0); free (block1); }",True,Go,_anal_calls,cmd_anal.c,https://github.com/radareorg/radare2,radareorg,pancake,2023-08-14 16:33:25+02:00,"Fix 1byte heap oobread in the brainfuck disassembler * https://huntr.dev/bounties/06e2484c-d6f1-4497-af67-26549be9fffd/ * Kudos to @7resp4ss for reporting",CWE-787,Out-of-bounds Write,"The product writes data past the end, or before the beginning, of the intended buffer.",https://cwe.mitre.org/data/definitions/787.html,CVE-2023-4322,"func TestDoesPolicySignatureMatch(t *testing.T) { credentialTemplate := ""%s/%s/%s/s3/aws4_request"" now := UTCNow() accessKey := globalActiveCred.AccessKey testCases := []struct { form http.Header expected APIErrorCode }{ { form: http.Header{}, expected: ErrCredMalformed, }, { form: http.Header{ ""X-Amz-Credential"": []string{fmt.Sprintf(credentialTemplate, ""EXAMPLEINVALIDEXAMPL"", now.Format(yyyymmdd), globalMinioDefaultRegion)}, }, expected: ErrInvalidAccessKeyID, }, { form: http.Header{ ""X-Amz-Credential"": []string{fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion)}, ""X-Amz-Date"": []string{now.Format(iso8601Format)}, ""X-Amz-Signature"": []string{""invalidsignature""}, ""Policy"": []string{""policy""}, }, expected: ErrSignatureDoesNotMatch, }, { form: http.Header{ ""X-Amz-Credential"": []string{ fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion), }, ""X-Amz-Date"": []string{now.Format(iso8601Format)}, ""X-Amz-Signature"": []string{ getSignature(getSigningKey(globalActiveCred.SecretKey, now, globalMinioDefaultRegion, serviceS3), ""policy""), }, ""Policy"": []string{""policy""}, }, expected: ErrNone, }, } for i, testCase := range testCases { _, code := doesPolicySignatureMatch(testCase.form) if code != testCase.expected { t.Errorf(""(%d) expected to get %s, instead got %s"", i, niceError(testCase.expected), niceError(code)) } } }" 232,"static bool anal_fcn_data (RCore *core, const char *input) { RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, -1); ut32 fcn_size = r_anal_function_size_from_entry (fcn); if (fcn) { int i; bool gap = false; ut64 gap_addr = UT64_MAX; char *bitmap = calloc (1, fcn_size); if (bitmap) { RAnalBlock *b; RListIter *iter; r_list_foreach (fcn->bbs, iter, b) { int f = b->addr - fcn->addr; int t = R_MIN (f + b->size, fcn_size); if (f >= 0) { while (f < t) { bitmap[f++] = 1; } } } } for (i = 0; i < fcn_size; i++) { ut64 here = fcn->addr + i; if (bitmap && bitmap[i]) { if (gap) { r_cons_printf (""Cd %d @ 0x%08""PFMT64x""\n"", here - gap_addr, gap_addr); gap = false; } gap_addr = UT64_MAX; } else { if (!gap) { gap = true; gap_addr = here; } } } if (gap) { r_cons_printf (""Cd %d @ 0x%08""PFMT64x""\n"", fcn->addr + fcn_size - gap_addr, gap_addr); } free (bitmap); return true; } return false; }",True,Go,anal_fcn_data,cmd_anal.c,https://github.com/radareorg/radare2,radareorg,GitHub,2020-03-16 17:03:22+01:00,Fix segfault in adf (#16230),CWE-908,Use of Uninitialized Resource,The product uses or accesses a resource that has not been initialized.,https://cwe.mitre.org/data/definitions/908.html,CVE-2020-27795,"func newSignV4ChunkedReader(req *http.Request) (io.ReadCloser, APIErrorCode) { cred, seedSignature, region, seedDate, errCode := calculateSeedSignature(req) if errCode != ErrNone { return nil, errCode } return &s3ChunkedReader{ reader: bufio.NewReader(req.Body), cred: cred, seedSignature: seedSignature, seedDate: seedDate, region: region, chunkSHA256Writer: sha256.New(), buffer: make([]byte, 64*1024), }, ErrNone }" 236,"func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) { ctx := newContext(r, w, ""AddUser"") defer logger.AuditLog(ctx, w, r, mustGetClaimsFromToken(r)) vars := mux.Vars(r) accessKey := vars[""accessKey""] objectAPI := newObjectLayerFn() if objectAPI == nil || globalNotificationSys == nil { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrServerNotInitialized), r.URL) return } cred, claims, owner, s3Err := validateAdminSignature(ctx, r, """") if s3Err != ErrNone { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(s3Err), r.URL) return } if owner && accessKey == cred.AccessKey { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAddUserInvalidArgument), r.URL) return } userCred, exists := globalIAMSys.GetUser(ctx, accessKey) if exists && (userCred.IsTemp() || userCred.IsServiceAccount()) { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAddUserInvalidArgument), r.URL) return } if (cred.IsTemp() || cred.IsServiceAccount()) && cred.ParentUser == accessKey { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAddUserInvalidArgument), r.URL) return } checkDenyOnly := false if accessKey == cred.AccessKey { checkDenyOnly = true } if !globalIAMSys.IsAllowed(iampolicy.Args{ AccountName: cred.AccessKey, Groups: cred.Groups, Action: iampolicy.CreateUserAdminAction, ConditionValues: getConditionValues(r, """", cred.AccessKey, claims), IsOwner: owner, Claims: claims, DenyOnly: checkDenyOnly, }) { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAccessDenied), r.URL) return } if r.ContentLength > maxEConfigJSONSize || r.ContentLength == -1 { writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigTooLarge), r.URL) return } password := cred.SecretKey configBytes, err := madmin.DecryptData(password, io.LimitReader(r.Body, r.ContentLength)) if err != nil { logger.LogIf(ctx, err) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) return } var uinfo madmin.UserInfo if err = json.Unmarshal(configBytes, &uinfo); err != nil { logger.LogIf(ctx, err) writeErrorResponseJSON(ctx, w, errorCodes.ToAPIErr(ErrAdminConfigBadJSON), r.URL) return } if err = globalIAMSys.CreateUser(ctx, accessKey, uinfo); err != nil { writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL) return } }",True,Go,AddUser,admin-handlers-users.go,https://github.com/minio/minio,minio,GitHub,2021-12-23 09:21:21-08:00,"Fix user privilege escalation bug (#13976) The AddUser() API endpoint was accepting a policy field. This API is used to update a user's secret key and account status, and allows a regular user to update their own secret key. The policy update is also applied though does not appear to be used by any existing client-side functionality. This fix changes the accepted request body type and removes the ability to apply policy changes as that is possible via the policy set API. NOTE: Changing passwords can be disabled as a workaround for this issue by adding an explicit ""Deny"" rule to disable the API for users.",CWE-863,Incorrect Authorization,"The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.",https://cwe.mitre.org/data/definitions/863.html,CVE-2021-43858,"func checkKeyValid(r *http.Request, accessKey string) (auth.Credentials, bool, APIErrorCode) { if !globalIAMSys.Initialized() && !globalIsGateway { return auth.Credentials{}, false, ErrServerNotInitialized } cred := globalActiveCred if cred.AccessKey != accessKey { ucred, ok := globalIAMSys.GetUser(accessKey) if !ok { return cred, false, ErrInvalidAccessKeyID } cred = ucred } claims, s3Err := checkClaimsFromToken(r, cred) if s3Err != ErrNone { return cred, false, s3Err } cred.Claims = claims owner := cred.AccessKey == globalActiveCred.AccessKey return cred, owner, ErrNone }" 242,"func (sys *IAMSys) CreateUser(ctx context.Context, accessKey string, uinfo madmin.UserInfo) error { if !sys.Initialized() { return errServerNotInitialized } if sys.usersSysType != MinIOUsersSysType { return errIAMActionNotAllowed } if !auth.IsAccessKeyValid(accessKey) { return auth.ErrInvalidAccessKeyLength } if !auth.IsSecretKeyValid(uinfo.SecretKey) { return auth.ErrInvalidSecretKeyLength } err := sys.store.AddUser(ctx, accessKey, uinfo) if err != nil { return err } sys.notifyForUser(ctx, accessKey, false) return nil }",True,Go,CreateUser,iam.go,https://github.com/minio/minio,minio,GitHub,2021-12-23 09:21:21-08:00,"Fix user privilege escalation bug (#13976) The AddUser() API endpoint was accepting a policy field. This API is used to update a user's secret key and account status, and allows a regular user to update their own secret key. The policy update is also applied though does not appear to be used by any existing client-side functionality. This fix changes the accepted request body type and removes the ability to apply policy changes as that is possible via the policy set API. NOTE: Changing passwords can be disabled as a workaround for this issue by adding an explicit ""Deny"" rule to disable the API for users.",CWE-863,Incorrect Authorization,"The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.",https://cwe.mitre.org/data/definitions/863.html,CVE-2021-43858,"func isReqAuthenticated(r *http.Request, region string) (s3Error APIErrorCode) { if errCode := reqSignatureV4Verify(r, region); errCode != ErrNone { return errCode } var ( err error contentMD5, contentSHA256 []byte ) if _, ok := r.Header[""Content-Md5""]; ok { contentMD5, err = base64.StdEncoding.Strict().DecodeString(r.Header.Get(""Content-Md5"")) if err != nil || len(contentMD5) == 0 { return ErrInvalidDigest } } if skipSHA256 := skipContentSha256Cksum(r); !skipSHA256 && isRequestPresignedSignatureV4(r) { if sha256Sum, ok := r.URL.Query()[""X-Amz-Content-Sha256""]; ok && len(sha256Sum) > 0 { contentSHA256, err = hex.DecodeString(sha256Sum[0]) if err != nil { return ErrContentSHA256Mismatch } } } else if _, ok := r.Header[""X-Amz-Content-Sha256""]; !skipSHA256 && ok { contentSHA256, err = hex.DecodeString(r.Header.Get(""X-Amz-Content-Sha256"")) if err != nil || len(contentSHA256) == 0 { return ErrContentSHA256Mismatch } } reader, err := hash.NewReader(r.Body, -1, hex.EncodeToString(contentMD5), hex.EncodeToString(contentSHA256)) if err != nil { return toAPIErrorCode(err) } r.Body = ioutil.NopCloser(reader) return ErrNone }" 243,"func TestCheckValid(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() objLayer, fsDir, err := prepareFS() if err != nil { t.Fatal(err) } defer os.RemoveAll(fsDir) if err = newTestConfig(globalMinioDefaultRegion, objLayer); err != nil { t.Fatalf(""unable initialize config file, %s"", err) } newAllSubsystems() initConfigSubsystem(ctx, objLayer) globalIAMSys.Init(ctx, objLayer, globalEtcdClient, globalNotificationSys, 2*time.Second) req, err := newTestRequest(http.MethodGet, ""http: if err != nil { t.Fatal(err) } if err = signRequestV4(req, globalActiveCred.AccessKey, globalActiveCred.SecretKey); err != nil { t.Fatal(err) } _, owner, s3Err := checkKeyValid(req, globalActiveCred.AccessKey) if s3Err != ErrNone { t.Fatalf(""Unexpected failure with %v"", errorCodes.ToAPIErr(s3Err)) } if !owner { t.Fatalf(""Expected owner to be 'true', found %t"", owner) } _, _, s3Err = checkKeyValid(req, ""does-not-exist"") if s3Err != ErrInvalidAccessKeyID { t.Fatalf(""Expected error 'ErrInvalidAccessKeyID', found %v"", s3Err) } ucreds, err := auth.CreateCredentials(""myuser1"", ""mypassword1"") if err != nil { t.Fatalf(""unable create credential, %s"", err) } globalIAMSys.CreateUser(ctx, ucreds.AccessKey, madmin.UserInfo{ SecretKey: ucreds.SecretKey, Status: madmin.AccountEnabled, }) _, owner, s3Err = checkKeyValid(req, ucreds.AccessKey) if s3Err != ErrNone { t.Fatalf(""Unexpected failure with %v"", errorCodes.ToAPIErr(s3Err)) } if owner { t.Fatalf(""Expected owner to be 'false', found %t"", owner) } }",True,Go,TestCheckValid,signature-v4-utils_test.go,https://github.com/minio/minio,minio,GitHub,2021-12-23 09:21:21-08:00,"Fix user privilege escalation bug (#13976) The AddUser() API endpoint was accepting a policy field. This API is used to update a user's secret key and account status, and allows a regular user to update their own secret key. The policy update is also applied though does not appear to be used by any existing client-side functionality. This fix changes the accepted request body type and removes the ability to apply policy changes as that is possible via the policy set API. NOTE: Changing passwords can be disabled as a workaround for this issue by adding an explicit ""Deny"" rule to disable the API for users.",CWE-863,Incorrect Authorization,"The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.",https://cwe.mitre.org/data/definitions/863.html,CVE-2021-43858,"func TestIsReqAuthenticated(t *testing.T) { path, err := newTestConfig(globalMinioDefaultRegion) if err != nil { t.Fatalf(""unable initialize config file, %s"", err) } defer os.RemoveAll(path) creds, err := auth.CreateCredentials(""myuser"", ""mypassword"") if err != nil { t.Fatalf(""unable create credential, %s"", err) } globalServerConfig.SetCredential(creds) testCases := []struct { req *http.Request s3Error APIErrorCode }{ {mustNewRequest(""GET"", ""http: {mustNewSignedEmptyMD5Request(""PUT"", ""http: {mustNewSignedShortMD5Request(""PUT"", ""http: {mustNewSignedBadMD5Request(""PUT"", ""http: {mustNewSignedRequest(""GET"", ""http: } for i, testCase := range testCases { if s3Error := isReqAuthenticated(testCase.req, globalServerConfig.GetRegion()); s3Error != testCase.s3Error { if _, err := ioutil.ReadAll(testCase.req.Body); toAPIErrorCode(err) != testCase.s3Error { t.Fatalf(""Test %d: Unexpected S3 error: want %d - got %d (got after reading request %d)"", i, testCase.s3Error, s3Error, toAPIErrorCode(err)) } } } }" 252,"func getClaimsFromToken(r *http.Request, token string) (map[string]interface{}, error) {",True,Go,getClaimsFromToken,auth-handler.go,https://github.com/minio/minio,minio,GitHub,2021-03-03 08:47:08-08:00,fix: missing user policy enforcement in PostPolicyHandler (#11682),CWE-863,Incorrect Authorization,"The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.",https://cwe.mitre.org/data/definitions/863.html,CVE-2021-21362,"func enforceRetentionBypassForDelete(ctx context.Context, r *http.Request, bucket string, object ObjectToDelete, oi ObjectInfo, gerr error) APIErrorCode { opts, err := getOpts(ctx, r, bucket, object.ObjectName) if err != nil { return toAPIErrorCode(ctx, err) } opts.VersionID = object.VersionID if gerr != nil { switch gerr.(type) { case MethodNotAllowed: if oi.DeleteMarker || !oi.VersionPurgeStatus.Empty() { return ErrNone } } if isErrObjectNotFound(gerr) || isErrVersionNotFound(gerr) { return ErrNone } return toAPIErrorCode(ctx, gerr) } lhold := objectlock.GetObjectLegalHoldMeta(oi.UserDefined) if lhold.Status.Valid() && lhold.Status == objectlock.LegalHoldOn { return ErrObjectLocked } ret := objectlock.GetObjectRetentionMeta(oi.UserDefined) if ret.Mode.Valid() { switch ret.Mode { case objectlock.RetCompliance: t, err := objectlock.UTCNowNTP() if err != nil { logger.LogIf(ctx, err) return ErrObjectLocked } if !ret.RetainUntilDate.Before(t) { return ErrObjectLocked } return ErrNone case objectlock.RetGovernance: byPassSet := objectlock.IsObjectLockGovernanceBypassSet(r.Header) if !byPassSet { t, err := objectlock.UTCNowNTP() if err != nil { logger.LogIf(ctx, err) return ErrObjectLocked } if !ret.RetainUntilDate.Before(t) { return ErrObjectLocked } return ErrNone } if checkRequestAuthType(ctx, r, policy.BypassGovernanceRetentionAction, bucket, object.ObjectName) != ErrNone { return ErrAccessDenied } } } return ErrNone }" 254,"func doesPolicySignatureV2Match(formValues http.Header) APIErrorCode { cred := globalActiveCred accessKey := formValues.Get(xhttp.AmzAccessKeyID) cred, _, s3Err := checkKeyValid(accessKey) if s3Err != ErrNone { return s3Err } policy := formValues.Get(""Policy"") signature := formValues.Get(xhttp.AmzSignatureV2) if !compareSignatureV2(signature, calculateSignatureV2(policy, cred.SecretKey)) { return ErrSignatureDoesNotMatch } return ErrNone }",True,Go,doesPolicySignatureV2Match,signature-v2.go,https://github.com/minio/minio,minio,GitHub,2021-03-03 08:47:08-08:00,fix: missing user policy enforcement in PostPolicyHandler (#11682),CWE-863,Incorrect Authorization,"The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.",https://cwe.mitre.org/data/definitions/863.html,CVE-2021-21362,"func isRequestPostPolicySignatureV4(r *http.Request) bool { mediaType, _, err := mime.ParseMediaType(r.Header.Get(xhttp.ContentType)) if err != nil { return false } return mediaType == ""multipart/form-data"" && r.Method == http.MethodPost }" 255,"func TestDoesPolicySignatureV2Match(t *testing.T) { obj, fsDir, err := prepareFS() if err != nil { t.Fatal(err) } defer os.RemoveAll(fsDir) if err = newTestConfig(globalMinioDefaultRegion, obj); err != nil { t.Fatal(err) } creds := globalActiveCred policy := ""policy"" testCases := []struct { accessKey string policy string signature string errCode APIErrorCode }{ {""invalidAccessKey"", policy, calculateSignatureV2(policy, creds.SecretKey), ErrInvalidAccessKeyID}, {creds.AccessKey, policy, calculateSignatureV2(""random"", creds.SecretKey), ErrSignatureDoesNotMatch}, {creds.AccessKey, policy, calculateSignatureV2(policy, creds.SecretKey), ErrNone}, } for i, test := range testCases { formValues := make(http.Header) formValues.Set(""Awsaccesskeyid"", test.accessKey) formValues.Set(""Signature"", test.signature) formValues.Set(""Policy"", test.policy) errCode := doesPolicySignatureV2Match(formValues) if errCode != test.errCode { t.Fatalf(""(%d) expected to get %s, instead got %s"", i+1, niceError(test.errCode), niceError(errCode)) } } }",True,Go,TestDoesPolicySignatureV2Match,signature-v2_test.go,https://github.com/minio/minio,minio,GitHub,2021-03-03 08:47:08-08:00,fix: missing user policy enforcement in PostPolicyHandler (#11682),CWE-863,Incorrect Authorization,"The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.",https://cwe.mitre.org/data/definitions/863.html,CVE-2021-21362,"func hasBadPathComponent(path string) bool { path = filepath.ToSlash(strings.TrimSpace(path)) for _, p := range strings.Split(path, SlashSeparator) { switch strings.TrimSpace(p) { case dotdotComponent: return true case dotComponent: return true } } return false }" 259,"func doesPolicySignatureV4Match(formValues http.Header) APIErrorCode { region := globalServerRegion credHeader, s3Err := parseCredentialHeader(""Credential=""+formValues.Get(xhttp.AmzCredential), region, serviceS3) if s3Err != ErrNone { return s3Err } cred, _, s3Err := checkKeyValid(credHeader.accessKey) if s3Err != ErrNone { return s3Err } signingKey := getSigningKey(cred.SecretKey, credHeader.scope.date, credHeader.scope.region, serviceS3) newSignature := getSignature(signingKey, formValues.Get(""Policy"")) if !compareSignatureV4(newSignature, formValues.Get(xhttp.AmzSignature)) { return ErrSignatureDoesNotMatch } return ErrNone }",True,Go,doesPolicySignatureV4Match,signature-v4.go,https://github.com/minio/minio,minio,GitHub,2021-03-03 08:47:08-08:00,fix: missing user policy enforcement in PostPolicyHandler (#11682),CWE-863,Incorrect Authorization,"The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.",https://cwe.mitre.org/data/definitions/863.html,CVE-2021-21362,"func testObjectAbortMultipartUpload(obj ObjectLayer, instanceType string, t TestErrHandler) { bucket := ""minio-bucket"" object := ""minio-object"" opts := ObjectOptions{} err := obj.MakeBucket(context.Background(), bucket, MakeBucketOptions{}) if err != nil { t.Fatalf(""%s : %s"", instanceType, err.Error()) } res, err := obj.NewMultipartUpload(context.Background(), bucket, object, opts) if err != nil { t.Fatalf(""%s : %s"", instanceType, err.Error()) } uploadID := res.UploadID abortTestCases := []struct { bucketName string objName string uploadID string expectedErrType error }{ {""--"", object, uploadID, BucketNotFound{}}, {""foo"", object, uploadID, BucketNotFound{}}, {bucket, object, ""foo-foo"", InvalidUploadID{}}, {bucket, object, uploadID, nil}, } if runtime.GOOS != globalWindowsOSName { abortTestCases = append(abortTestCases, struct { bucketName string objName string uploadID string expectedErrType error }{bucket, ""\\"", uploadID, InvalidUploadID{}}) } for i, testCase := range abortTestCases { err = obj.AbortMultipartUpload(context.Background(), testCase.bucketName, testCase.objName, testCase.uploadID, opts) if testCase.expectedErrType == nil && err != nil { t.Errorf(""Test %d, unexpected err is received: %v, expected:%v\n"", i+1, err, testCase.expectedErrType) } if testCase.expectedErrType != nil && !isSameType(err, testCase.expectedErrType) { t.Errorf(""Test %d, unexpected err is received: %v, expected:%v\n"", i+1, err, testCase.expectedErrType) } } }" 260,"func doesPolicySignatureMatch(formValues http.Header) APIErrorCode { if _, ok := formValues[""Signature""]; ok { return doesPolicySignatureV2Match(formValues) } return doesPolicySignatureV4Match(formValues) }",True,Go,doesPolicySignatureMatch,signature-v4.go,https://github.com/minio/minio,minio,GitHub,2021-03-03 08:47:08-08:00,fix: missing user policy enforcement in PostPolicyHandler (#11682),CWE-863,Incorrect Authorization,"The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.",https://cwe.mitre.org/data/definitions/863.html,CVE-2021-21362,"func main() { if len(os.Args) < 3 { fatal(usage) } cmd, filename := os.Args[1], os.Args[2] ff := archiver.MatchingFormat(filename) if ff == nil { fatalf(""%s: Unsupported file extension"", filename) } var err error switch cmd { case ""make"": if len(os.Args) < 4 { fatal(usage) } err = ff.Make(filename, os.Args[3:]) case ""open"": dest, osErr := os.Getwd() if osErr != nil { fatal(err) } if len(os.Args) == 4 { dest = os.Args[3] } else if len(os.Args) > 4 { fatal(usage) } err = ff.Open(filename, dest) default: fatal(usage) } if err != nil { fatal(err) } }" 261,"func TestDoesPolicySignatureMatch(t *testing.T) { credentialTemplate := ""%s/%s/%s/s3/aws4_request"" now := UTCNow() accessKey := globalActiveCred.AccessKey testCases := []struct { form http.Header expected APIErrorCode }{ { form: http.Header{}, expected: ErrCredMalformed, }, { form: http.Header{ ""X-Amz-Credential"": []string{fmt.Sprintf(credentialTemplate, ""EXAMPLEINVALIDEXAMPL"", now.Format(yyyymmdd), globalMinioDefaultRegion)}, }, expected: ErrInvalidAccessKeyID, }, { form: http.Header{ ""X-Amz-Credential"": []string{fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion)}, ""X-Amz-Date"": []string{now.Format(iso8601Format)}, ""X-Amz-Signature"": []string{""invalidsignature""}, ""Policy"": []string{""policy""}, }, expected: ErrSignatureDoesNotMatch, }, { form: http.Header{ ""X-Amz-Credential"": []string{ fmt.Sprintf(credentialTemplate, accessKey, now.Format(yyyymmdd), globalMinioDefaultRegion), }, ""X-Amz-Date"": []string{now.Format(iso8601Format)}, ""X-Amz-Signature"": []string{ getSignature(getSigningKey(globalActiveCred.SecretKey, now, globalMinioDefaultRegion, serviceS3), ""policy""), }, ""Policy"": []string{""policy""}, }, expected: ErrNone, }, } for i, testCase := range testCases { code := doesPolicySignatureMatch(testCase.form) if code != testCase.expected { t.Errorf(""(%d) expected to get %s, instead got %s"", i, niceError(testCase.expected), niceError(code)) } } }",True,Go,TestDoesPolicySignatureMatch,signature-v4_test.go,https://github.com/minio/minio,minio,GitHub,2021-03-03 08:47:08-08:00,fix: missing user policy enforcement in PostPolicyHandler (#11682),CWE-863,Incorrect Authorization,"The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check. This allows attackers to bypass intended access restrictions.",https://cwe.mitre.org/data/definitions/863.html,CVE-2021-21362,"func (rarFormat) Read(input io.Reader, destination string) error { rr, err := rardecode.NewReader(input, """") if err != nil { return fmt.Errorf(""read: failed to create reader: %v"", err) } for { header, err := rr.Next() if err == io.EOF { break } else if err != nil { return err } err = sanitizeExtractPath(header.Name, destination) if err != nil { return err } destpath := filepath.Join(destination, header.Name) if header.IsDir { err = mkdir(destpath) if err != nil { return err } continue } err = mkdir(filepath.Dir(destpath)) if err != nil { return err } err = writeNewFile(destpath, rr, header.Mode()) if err != nil { return err } } return nil }" 263,"func newSignV4ChunkedReader(req *http.Request) (io.ReadCloser, APIErrorCode) { cred, seedSignature, region, seedDate, errCode := calculateSeedSignature(req) if errCode != ErrNone { return nil, errCode } return &s3ChunkedReader{ reader: bufio.NewReader(req.Body), cred: cred, seedSignature: seedSignature, seedDate: seedDate, region: region, chunkSHA256Writer: sha256.New(), state: readChunkHeader, }, ErrNone }",True,Go,newSignV4ChunkedReader,streaming-signature-v4.go,https://github.com/minio/minio,minio,GitHub,2021-03-16 13:33:40-07:00,"s3v4: read and verify S3 signature v4 chunks separately (#11801) This commit fixes a security issue in the signature v4 chunked reader. Before, the reader returned unverified data to the caller and would only verify the chunk signature once it has encountered the end of the chunk payload. Now, the chunk reader reads the entire chunk into an in-memory buffer, verifies the signature and then returns data to the caller. In general, this is a common security problem. We verifying data streams, the verifier MUST NOT return data to the upper layers / its callers as long as it has not verified the current data chunk / data segment: ``` func (r *Reader) Read(buffer []byte) { if err := r.readNext(r.internalBuffer); err != nil { return err } if err := r.verify(r.internalBuffer); err != nil { return err } copy(buffer, r.internalBuffer) } ```",CWE-924,Improper Enforcement of Message Integrity During Transmission in a Communication Channel,"The product establishes a communication channel with an endpoint and receives a message from that endpoint, but it does not sufficiently ensure that the message was not modified during transmission.",https://cwe.mitre.org/data/definitions/924.html,CVE-2021-21390,"func generateDataset(dest []uint32, epoch uint64, cache []uint32) { logger := log.New(""epoch"", epoch) start := time.Now() defer func() { elapsed := time.Since(start) logFn := logger.Debug if elapsed > 3*time.Second { logFn = logger.Info } logFn(""Generated ethash verification cache"", ""elapsed"", common.PrettyDuration(elapsed)) }() swapped := !isLittleEndian() header := *(*reflect.SliceHeader)(unsafe.Pointer(&dest)) header.Len *= 4 header.Cap *= 4 dataset := *(*[]byte)(unsafe.Pointer(&header)) threads := runtime.NumCPU() size := uint64(len(dataset)) var pend sync.WaitGroup pend.Add(threads) var progress uint64 for i := 0; i < threads; i++ { go func(id int) { defer pend.Done() keccak512 := makeHasher(sha3.NewLegacyKeccak512()) batch := (size + hashBytes*uint64(threads) - 1) / (hashBytes * uint64(threads)) first := uint64(id) * batch limit := first + batch if limit > size/hashBytes { limit = size / hashBytes } percent := size / hashBytes / 100 for index := first; index < limit; index++ { item := generateDatasetItem(cache, uint32(index), keccak512) if swapped { swap(item) } copy(dataset[index*hashBytes:], item) if status := atomic.AddUint64(&progress, 1); status%percent == 0 { logger.Info(""Generating DAG in progress"", ""percentage"", (status*100)/(size/hashBytes), ""elapsed"", common.PrettyDuration(time.Since(start))) } } }(i) } pend.Wait() }" 264,"func (cr *s3ChunkedReader) readS3ChunkHeader() { var hexChunkSize, hexChunkSignature []byte hexChunkSize, hexChunkSignature, cr.err = readChunkLine(cr.reader) if cr.err != nil { return } cr.n, cr.err = parseHexUint(hexChunkSize) if cr.err != nil { return } if cr.n == 0 { cr.err = io.EOF } cr.chunkSignature = string(hexChunkSignature) }",True,Go,readS3ChunkHeader,streaming-signature-v4.go,https://github.com/minio/minio,minio,GitHub,2021-03-16 13:33:40-07:00,"s3v4: read and verify S3 signature v4 chunks separately (#11801) This commit fixes a security issue in the signature v4 chunked reader. Before, the reader returned unverified data to the caller and would only verify the chunk signature once it has encountered the end of the chunk payload. Now, the chunk reader reads the entire chunk into an in-memory buffer, verifies the signature and then returns data to the caller. In general, this is a common security problem. We verifying data streams, the verifier MUST NOT return data to the upper layers / its callers as long as it has not verified the current data chunk / data segment: ``` func (r *Reader) Read(buffer []byte) { if err := r.readNext(r.internalBuffer); err != nil { return err } if err := r.verify(r.internalBuffer); err != nil { return err } copy(buffer, r.internalBuffer) } ```",CWE-924,Improper Enforcement of Message Integrity During Transmission in a Communication Channel,"The product establishes a communication channel with an endpoint and receives a message from that endpoint, but it does not sufficiently ensure that the message was not modified during transmission.",https://cwe.mitre.org/data/definitions/924.html,CVE-2021-21390,"func TestGetDynamic(t *testing.T) { savedServices := services savedGetVCSDirFn := getVCSDirFn defer func() { services = savedServices getVCSDirFn = savedGetVCSDirFn }() services = []*service{{pattern: regexp.MustCompile("".*""), get: testGet}} getVCSDirFn = testGet client := &http.Client{Transport: testTransport(testWeb)} for _, tt := range getDynamicTests { dir, err := getDynamic(context.Background(), client, tt.importPath, """") if tt.dir == nil { if err == nil { t.Errorf(""getDynamic(ctx, client, %q, etag) did not return expected error"", tt.importPath) } continue } if err != nil { t.Errorf(""getDynamic(ctx, client, %q, etag) return unexpected error: %v"", tt.importPath, err) continue } if !cmp.Equal(dir, tt.dir) { t.Errorf(""getDynamic(client, %q, etag) =\n %+v,\nwant %+v"", tt.importPath, dir, tt.dir) for i, f := range dir.Files { var want *File if i < len(tt.dir.Files) { want = tt.dir.Files[i] } t.Errorf(""file %d = %+v, want %+v"", i, f, want) } } } }" 265,"func (cr *s3ChunkedReader) Read(buf []byte) (n int, err error) { for { switch cr.state { case readChunkHeader: cr.readS3ChunkHeader() if cr.n == 0 && cr.err == io.EOF { cr.state = readChunkTrailer cr.lastChunk = true continue } if cr.err != nil { return 0, cr.err } cr.state = readChunk case readChunkTrailer: cr.err = readCRLF(cr.reader) if cr.err != nil { return 0, errMalformedEncoding } cr.state = verifyChunk case readChunk: if len(buf) == 0 { return n, nil } rbuf := buf if uint64(len(rbuf)) > cr.n { rbuf = rbuf[:cr.n] } var n0 int n0, cr.err = cr.reader.Read(rbuf) if cr.err != nil { if cr.err == io.EOF { cr.err = io.ErrUnexpectedEOF } return 0, cr.err } cr.chunkSHA256Writer.Write(rbuf[:n0]) n += n0 buf = buf[n0:] cr.n -= uint64(n0) if cr.n == 0 { cr.state = readChunkTrailer continue } case verifyChunk: hashedChunk := hex.EncodeToString(cr.chunkSHA256Writer.Sum(nil)) newSignature := getChunkSignature(cr.cred, cr.seedSignature, cr.region, cr.seedDate, hashedChunk) if !compareSignatureV4(cr.chunkSignature, newSignature) { cr.err = errSignatureMismatch return 0, cr.err } cr.seedSignature = newSignature cr.chunkSHA256Writer.Reset() if cr.lastChunk { cr.state = eofChunk } else { cr.state = readChunkHeader } case eofChunk: return n, io.EOF } } }",True,Go,Read,streaming-signature-v4.go,https://github.com/minio/minio,minio,GitHub,2021-03-16 13:33:40-07:00,"s3v4: read and verify S3 signature v4 chunks separately (#11801) This commit fixes a security issue in the signature v4 chunked reader. Before, the reader returned unverified data to the caller and would only verify the chunk signature once it has encountered the end of the chunk payload. Now, the chunk reader reads the entire chunk into an in-memory buffer, verifies the signature and then returns data to the caller. In general, this is a common security problem. We verifying data streams, the verifier MUST NOT return data to the upper layers / its callers as long as it has not verified the current data chunk / data segment: ``` func (r *Reader) Read(buffer []byte) { if err := r.readNext(r.internalBuffer); err != nil { return err } if err := r.verify(r.internalBuffer); err != nil { return err } copy(buffer, r.internalBuffer) } ```",CWE-924,Improper Enforcement of Message Integrity During Transmission in a Communication Channel,"The product establishes a communication channel with an endpoint and receives a message from that endpoint, but it does not sufficiently ensure that the message was not modified during transmission.",https://cwe.mitre.org/data/definitions/924.html,CVE-2021-21390,"func (d *partialArray) add(key string, val *lazyNode) error { if key == ""-"" { *d = append(*d, val) return nil } idx, err := strconv.Atoi(key) if err != nil { return err } ary := make([]*lazyNode, len(*d)+1) cur := *d if idx < 0 { idx *= -1 if idx > len(ary) { return fmt.Errorf(""Unable to access invalid index: %d"", idx) } idx = len(ary) - idx } if idx < 0 || idx >= len(ary) || idx > len(cur) { return fmt.Errorf(""Unable to access invalid index: %d"", idx) } copy(ary[0:idx], cur[0:idx]) ary[idx] = val copy(ary[idx+1:], cur[idx:]) *d = ary return nil }" 267,"func (cs chunkState) String() string { stateString := """" switch cs { case readChunkHeader: stateString = ""readChunkHeader"" case readChunkTrailer: stateString = ""readChunkTrailer"" case readChunk: stateString = ""readChunk"" case verifyChunk: stateString = ""verifyChunk"" case eofChunk: stateString = ""eofChunk"" } return stateString }",True,Go,String,streaming-signature-v4.go,https://github.com/minio/minio,minio,GitHub,2021-03-16 13:33:40-07:00,"s3v4: read and verify S3 signature v4 chunks separately (#11801) This commit fixes a security issue in the signature v4 chunked reader. Before, the reader returned unverified data to the caller and would only verify the chunk signature once it has encountered the end of the chunk payload. Now, the chunk reader reads the entire chunk into an in-memory buffer, verifies the signature and then returns data to the caller. In general, this is a common security problem. We verifying data streams, the verifier MUST NOT return data to the upper layers / its callers as long as it has not verified the current data chunk / data segment: ``` func (r *Reader) Read(buffer []byte) { if err := r.readNext(r.internalBuffer); err != nil { return err } if err := r.verify(r.internalBuffer); err != nil { return err } copy(buffer, r.internalBuffer) } ```",CWE-924,Improper Enforcement of Message Integrity During Transmission in a Communication Channel,"The product establishes a communication channel with an endpoint and receives a message from that endpoint, but it does not sufficiently ensure that the message was not modified during transmission.",https://cwe.mitre.org/data/definitions/924.html,CVE-2021-21390,func (s *Shm) MarkDestroyed() { s.mu.Lock() defer s.mu.Unlock() s.key = linux.IPC_PRIVATE if !s.pendingDestruction { s.pendingDestruction = true s.DecRef() } } 269,"func checkKeyValid(r *http.Request, accessKey string) (auth.Credentials, bool, APIErrorCode) { if !globalIAMSys.Initialized() && !globalIsGateway { return auth.Credentials{}, false, ErrServerNotInitialized } var owner = true var cred = globalActiveCred if cred.AccessKey != accessKey { ucred, ok := globalIAMSys.GetUser(accessKey) if !ok { return cred, false, ErrInvalidAccessKeyID } cred = ucred } claims, s3Err := checkClaimsFromToken(r, cred) if s3Err != ErrNone { return cred, false, s3Err } if len(claims) > 0 { cred.Claims = claims if _, ok := claims[iampolicy.SessionPolicyName]; ok { owner = false } else { owner = cred.AccessKey == cred.ParentUser } } return cred, owner, ErrNone }",True,Go,checkKeyValid,signature-v4-utils.go,https://github.com/minio/minio,minio,GitHub,2021-10-12 13:18:02-07:00,"checkKeyValid() should return owner true for rootCreds (#13422) Looks like policy restriction was not working properly for normal users when they are not svc or STS accounts. - svc accounts are now properly fixed to get right permissions when its inherited, so we do not have to set 'owner = true' - sts accounts have always been using right permissions, do not need an explicit lookup - regular users always have proper policy mapping",NVD-CWE-Other,Other,"NVD is only using a subset of CWE for mapping instead of the entire CWE, and the weakness type is not covered by that subset.",https://nvd.nist.gov/vuln/categories,CVE-2021-41137,"func Shmctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { id := args[0].Int() cmd := args[1].Int() buf := args[2].Pointer() r := t.IPCNamespace().ShmRegistry() switch cmd { case linux.SHM_STAT: fallthrough case linux.IPC_STAT: segment, err := findSegment(t, id) if err != nil { return 0, nil, syserror.EINVAL } stat, err := segment.IPCStat(t) if err == nil { _, err = t.CopyOut(buf, stat) } return 0, nil, err case linux.IPC_INFO: params := r.IPCInfo() _, err := t.CopyOut(buf, params) return 0, nil, err case linux.SHM_INFO: info := r.ShmInfo() _, err := t.CopyOut(buf, info) return 0, nil, err } segment, err := findSegment(t, id) if err != nil { return 0, nil, syserror.EINVAL } switch cmd { case linux.IPC_SET: var ds linux.ShmidDS _, err = t.CopyIn(buf, &ds) if err != nil { return 0, nil, err } err = segment.Set(t, &ds) return 0, nil, err case linux.IPC_RMID: segment.MarkDestroyed() return 0, nil, nil case linux.SHM_LOCK, linux.SHM_UNLOCK: t.Kernel().EmitUnimplementedEvent(t) return 0, nil, nil default: return 0, nil, syserror.EINVAL } }" 275,"func TestIsReqAuthenticated(t *testing.T) { path, err := newTestConfig(globalMinioDefaultRegion) if err != nil { t.Fatalf(""unable initialize config file, %s"", err) } defer os.RemoveAll(path) creds, err := auth.CreateCredentials(""myuser"", ""mypassword"") if err != nil { t.Fatalf(""unable create credential, %s"", err) } globalServerConfig.SetCredential(creds) testCases := []struct { req *http.Request s3Error APIErrorCode }{ {nil, ErrInternalError}, {mustNewRequest(""GET"", ""http: {mustNewSignedEmptyMD5Request(""PUT"", ""http: {mustNewSignedShortMD5Request(""PUT"", ""http: {mustNewSignedBadMD5Request(""PUT"", ""http: {mustNewSignedRequest(""GET"", ""http: } for _, testCase := range testCases { if s3Error := isReqAuthenticated(testCase.req, globalServerConfig.GetRegion()); s3Error != testCase.s3Error { t.Fatalf(""Unexpected s3error returned wanted %d, got %d"", testCase.s3Error, s3Error) } } }",True,Go,TestIsReqAuthenticated,auth-handler_test.go,https://github.com/minio/minio,minio,Dee Koder,2018-05-18 11:27:25-07:00,"security: fix write-to-RAM DoS vulnerability (#5957) This commit fixes a DoS vulnerability for certain APIs using signature V4 by verifying the content-md5 and/or content-sha56 of the request body in a streaming mode. The issue was caused by reading the entire body of the request into memory to verify the content-md5 or content-sha56 checksum if present. The vulnerability could be exploited by either replaying a V4 request (in the 15 min time frame) or sending a V4 presigned request with a large body.",CWE-774,Allocation of File Descriptors or Handles Without Limits or Throttling,"The product allocates file descriptors or handles on behalf of an actor without imposing any restrictions on how many descriptors can be allocated, in violation of the intended security policy for that actor.",https://cwe.mitre.org/data/definitions/774.html,CVE-2018-1000538,"func inHeadIM(p *parser) bool { switch p.tok.Type { case TextToken: s := strings.TrimLeft(p.tok.Data, whitespace) if len(s) < len(p.tok.Data) { p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) if s == """" { return true } p.tok.Data = s } case StartTagToken: switch p.tok.DataAtom { case a.Html: return inBodyIM(p) case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta: p.addElement() p.oe.pop() p.acknowledgeSelfClosingTag() return true case a.Noscript: if p.scripting { p.parseGenericRawTextElement() return true } p.addElement() p.im = inHeadNoscriptIM p.tokenizer.NextIsNotRawText() return true case a.Script, a.Title: p.addElement() p.setOriginalIM() p.im = textIM return true case a.Noframes, a.Style: p.parseGenericRawTextElement() return true case a.Head: return true case a.Template: for _, e := range p.oe { if e.Namespace != """" { p.im = ignoreTheRemainingTokens return true } } p.addElement() p.afe = append(p.afe, &scopeMarker) p.framesetOK = false p.im = inTemplateIM p.templateStack = append(p.templateStack, inTemplateIM) return true } case EndTagToken: switch p.tok.DataAtom { case a.Head: p.oe.pop() p.im = afterHeadIM return true case a.Body, a.Html, a.Br: p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) return false case a.Template: if !p.oe.contains(a.Template) { return true } p.generateImpliedEndTags() for i := len(p.oe) - 1; i >= 0; i-- { if n := p.oe[i]; n.Namespace == """" && n.DataAtom == a.Template { p.oe = p.oe[:i] break } } p.clearActiveFormattingElements() p.templateStack.pop() p.resetInsertionMode() return true default: return true } case CommentToken: p.addChild(&Node{ Type: CommentNode, Data: p.tok.Data, }) return true case DoctypeToken: return true } p.parseImpliedToken(EndTagToken, a.Head, a.Head.String()) return false }" 277,"func NewReader(src io.Reader, size int64, md5Hex, sha256Hex string) (*Reader, error) { if _, ok := src.(*Reader); ok { return nil, errNestedReader } sha256sum, err := hex.DecodeString(sha256Hex) if err != nil { return nil, SHA256Mismatch{} } md5sum, err := hex.DecodeString(md5Hex) if err != nil { return nil, BadDigest{} } var sha256Hash hash.Hash if len(sha256sum) != 0 { sha256Hash = sha256.New() } return &Reader{ md5sum: md5sum, sha256sum: sha256sum, src: io.LimitReader(src, size), size: size, md5Hash: md5.New(), sha256Hash: sha256Hash, }, nil }",True,Go,NewReader,reader.go,https://github.com/minio/minio,minio,Dee Koder,2018-05-18 11:27:25-07:00,"security: fix write-to-RAM DoS vulnerability (#5957) This commit fixes a DoS vulnerability for certain APIs using signature V4 by verifying the content-md5 and/or content-sha56 of the request body in a streaming mode. The issue was caused by reading the entire body of the request into memory to verify the content-md5 or content-sha56 checksum if present. The vulnerability could be exploited by either replaying a V4 request (in the 15 min time frame) or sending a V4 presigned request with a large body.",CWE-774,Allocation of File Descriptors or Handles Without Limits or Throttling,"The product allocates file descriptors or handles on behalf of an actor without imposing any restrictions on how many descriptors can be allocated, in violation of the intended security policy for that actor.",https://cwe.mitre.org/data/definitions/774.html,CVE-2018-1000538,"func (net *Network) checkTopicRegister(data *topicRegister) (*pong, error) { var pongpkt ingressPacket if err := decodePacket(data.Pong, &pongpkt); err != nil { return nil, err } if pongpkt.ev != pongPacket { return nil, errors.New(""is not pong packet"") } if pongpkt.remoteID != net.tab.self.ID { return nil, errors.New(""not signed by us"") } hash, _, _ := wireHash(data.Topics) if hash != pongpkt.data.(*pong).TopicHash { return nil, errors.New(""topic hash mismatch"") } if int(data.Idx) < 0 || int(data.Idx) >= len(data.Topics) { return nil, errors.New(""topic index out of range"") } return pongpkt.data.(*pong), nil }" 279,"func enforceRetentionBypassForDelete(ctx context.Context, r *http.Request, bucket string, object ObjectToDelete, oi ObjectInfo, gerr error) APIErrorCode { opts, err := getOpts(ctx, r, bucket, object.ObjectName) if err != nil { return toAPIErrorCode(ctx, err) } opts.VersionID = object.VersionID if gerr != nil { switch gerr.(type) { case MethodNotAllowed: if oi.DeleteMarker || !oi.VersionPurgeStatus.Empty() { return ErrNone } } if isErrObjectNotFound(gerr) || isErrVersionNotFound(gerr) { return ErrNone } return toAPIErrorCode(ctx, gerr) } lhold := objectlock.GetObjectLegalHoldMeta(oi.UserDefined) if lhold.Status.Valid() && lhold.Status == objectlock.LegalHoldOn { return ErrObjectLocked } ret := objectlock.GetObjectRetentionMeta(oi.UserDefined) if ret.Mode.Valid() { switch ret.Mode { case objectlock.RetCompliance: t, err := objectlock.UTCNowNTP() if err != nil { logger.LogIf(ctx, err) return ErrObjectLocked } if !ret.RetainUntilDate.Before(t) { return ErrObjectLocked } return ErrNone case objectlock.RetGovernance: byPassSet := objectlock.IsObjectLockGovernanceBypassSet(r.Header) if !byPassSet { t, err := objectlock.UTCNowNTP() if err != nil { logger.LogIf(ctx, err) return ErrObjectLocked } if !ret.RetainUntilDate.Before(t) { return ErrObjectLocked } return ErrNone } govBypassPerms1 := checkRequestAuthType(ctx, r, policy.BypassGovernanceRetentionAction, bucket, object.ObjectName) govBypassPerms2 := checkRequestAuthType(ctx, r, policy.GetBucketObjectLockConfigurationAction, bucket, object.ObjectName) if govBypassPerms1 != ErrNone && govBypassPerms2 != ErrNone { return ErrAccessDenied } } } return ErrNone }",True,Go,enforceRetentionBypassForDelete,bucket-object-lock.go,https://github.com/minio/minio,minio,GitHub,2023-02-17 07:41:34+05:18,fix: evaluate BypassGov policy action in deletion correctly (#16635),NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2023-25812,"func SanitizePath(path string) string { path = strings.TrimLeft(path, ""/"") path = strings.Replace(path, ""../"", """", -1) return path }" 282,"func isRequestPostPolicySignatureV4(r *http.Request) bool { return strings.Contains(r.Header.Get(xhttp.ContentType), ""multipart/form-data"") && r.Method == http.MethodPost }",True,Go,isRequestPostPolicySignatureV4,auth-handler.go,https://github.com/minio/minio,minio,GitHub,2023-03-19 21:15:20-07:00,fix: post policy request security bypass (#16849),NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2023-28434,"func MakeEmailPrimary(userID int64, email *EmailAddress) error { has, err := x.Get(email) if err != nil { return err } else if !has { return errors.EmailNotFound{Email: email.Email} } if email.UID != userID { return errors.New(""not the owner of the email"") } if !email.IsActivated { return errors.EmailNotVerified{Email: email.Email} } user := &User{ID: email.UID} has, err = x.Get(user) if err != nil { return err } else if !has { return errors.UserNotExist{UserID: email.UID} } formerPrimaryEmail := &EmailAddress{Email: user.Email} has, err = x.Get(formerPrimaryEmail) if err != nil { return err } sess := x.NewSession() defer sess.Close() if err = sess.Begin(); err != nil { return err } if !has { formerPrimaryEmail.UID = user.ID formerPrimaryEmail.IsActivated = user.IsActive if _, err = sess.Insert(formerPrimaryEmail); err != nil { return err } } user.Email = email.Email if _, err = sess.ID(user.ID).AllCols().Update(user); err != nil { return err } return sess.Commit() }" 284,"func hasBadPathComponent(path string) bool { path = strings.TrimSpace(path) for _, p := range strings.Split(path, SlashSeparator) { switch strings.TrimSpace(p) { case dotdotComponent: return true case dotComponent: return true } } return false }",True,Go,hasBadPathComponent,generic-handlers.go,https://github.com/minio/minio,minio,GitHub,2023-03-20 00:35:25-07:00,fix: convert '\' to '/' on windows (#16852),NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2023-28433,"func SettingsEmailPost(c *context.Context, f form.AddEmail) { c.Title(""settings.emails"") c.PageIs(""SettingsEmails"") if c.Query(""_method"") == ""PRIMARY"" { if err := db.MakeEmailPrimary(c.UserID(), &db.EmailAddress{ID: c.QueryInt64(""id"")}); err != nil { c.ServerError(""MakeEmailPrimary"", err) return } c.SubURLRedirect(""/user/settings/email"") return } emails, err := db.GetEmailAddresses(c.User.ID) if err != nil { c.ServerError(""GetEmailAddresses"", err) return } c.Data[""Emails""] = emails if c.HasError() { c.Success(SETTINGS_EMAILS) return } emailAddr := &db.EmailAddress{ UID: c.User.ID, Email: f.Email, IsActivated: !conf.Auth.RequireEmailConfirmation, } if err := db.AddEmailAddress(emailAddr); err != nil { if db.IsErrEmailAlreadyUsed(err) { c.RenderWithErr(c.Tr(""form.email_been_used""), SETTINGS_EMAILS, &f) } else { c.ServerError(""AddEmailAddress"", err) } return } if conf.Auth.RequireEmailConfirmation { email.SendActivateEmailMail(c.Context, db.NewMailerUser(c.User), emailAddr.Email) if err := c.Cache.Put(""MailResendLimit_""+c.User.LowerName, c.User.LowerName, 180); err != nil { log.Error(""Set cache 'MailResendLimit' failed: %v"", err) } c.Flash.Info(c.Tr(""settings.add_email_confirmation_sent"", emailAddr.Email, conf.Auth.ActivateCodeLives/60)) } else { c.Flash.Success(c.Tr(""settings.add_email_success"")) } c.SubURLRedirect(""/user/settings/email"") }" 287,"func testObjectAbortMultipartUpload(obj ObjectLayer, instanceType string, t TestErrHandler) { bucket := ""minio-bucket"" object := ""minio-object"" opts := ObjectOptions{} err := obj.MakeBucket(context.Background(), bucket, MakeBucketOptions{}) if err != nil { t.Fatalf(""%s : %s"", instanceType, err.Error()) } res, err := obj.NewMultipartUpload(context.Background(), bucket, object, opts) if err != nil { t.Fatalf(""%s : %s"", instanceType, err.Error()) } uploadID := res.UploadID abortTestCases := []struct { bucketName string objName string uploadID string expectedErrType error }{ {""--"", object, uploadID, BucketNotFound{}}, {""foo"", object, uploadID, BucketNotFound{}}, {bucket, object, ""foo-foo"", InvalidUploadID{}}, {bucket, ""\\"", uploadID, InvalidUploadID{}}, {bucket, object, uploadID, nil}, } for i, testCase := range abortTestCases { err = obj.AbortMultipartUpload(context.Background(), testCase.bucketName, testCase.objName, testCase.uploadID, opts) if testCase.expectedErrType == nil && err != nil { t.Errorf(""Test %d, unexpected err is received: %v, expected:%v\n"", i+1, err, testCase.expectedErrType) } if testCase.expectedErrType != nil && !isSameType(err, testCase.expectedErrType) { t.Errorf(""Test %d, unexpected err is received: %v, expected:%v\n"", i+1, err, testCase.expectedErrType) } } }",True,Go,testObjectAbortMultipartUpload,object-api-multipart_test.go,https://github.com/minio/minio,minio,GitHub,2023-03-20 13:16:00-07:00,reject object names with '\' on windows (#16856),NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2023-28433,"func (err ErrInvalidCloneAddr) Error() string { return fmt.Sprintf(""invalid clone address [is_url_error: %v, is_invalid_path: %v, is_permission_denied: %v, is_blocked_local_address: %v]"", err.IsURLError, err.IsInvalidPath, err.IsPermissionDenied, err.IsBlockedLocalAddress) }" 291,"func main() { if len(os.Args) < 3 { fatal(usage) } cmd, filename := os.Args[1], os.Args[2] ff := archiver.MatchingFormat(filename) if ff == nil { fatalf(""%s: Unsupported file extension"", filename) } var err error switch cmd { case ""make"": if len(os.Args) < 4 { fatal(usage) } err = ff.Make(filename, os.Args[3:]) case ""open"": dest := """" if len(os.Args) == 4 { dest = os.Args[3] } else if len(os.Args) > 4 { fatal(usage) } err = ff.Open(filename, dest) default: fatal(usage) } if err != nil { fatal(err) } }",True,Go,main,main.go,https://github.com/mholt/archiver,mholt,Matt Holt,2018-04-17 16:02:35-06:00,"fix: prevent extraction of archived files outside target path (#65) * fix: prevent extraction of archived files outside target path * CR: consolidate the path sanitaiton logic",CWE-22,Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'),"The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.",https://cwe.mitre.org/data/definitions/22.html,CVE-2018-1002207,"func (f MigrateRepo) ParseRemoteAddr(user *db.User) (string, error) { remoteAddr := strings.TrimSpace(f.CloneAddr) if strings.HasPrefix(remoteAddr, ""http: strings.HasPrefix(remoteAddr, ""https: strings.HasPrefix(remoteAddr, ""git: u, err := url.Parse(remoteAddr) if err != nil { return """", db.ErrInvalidCloneAddr{IsURLError: true} } if netutil.IsBlockedLocalHostname(u.Hostname(), conf.Security.LocalNetworkAllowlist) { return """", db.ErrInvalidCloneAddr{IsBlockedLocalAddress: true} } if len(f.AuthUsername)+len(f.AuthPassword) > 0 { u.User = url.UserPassword(f.AuthUsername, f.AuthPassword) } if u.Scheme == ""git"" && (strings.Contains(remoteAddr, ""%0d"") || strings.Contains(remoteAddr, ""%0a"")) { return """", db.ErrInvalidCloneAddr{IsURLError: true} } remoteAddr = u.String() } else if !user.CanImportLocal() { return """", db.ErrInvalidCloneAddr{IsPermissionDenied: true} } else if !com.IsDir(remoteAddr) { return """", db.ErrInvalidCloneAddr{IsInvalidPath: true} } return remoteAddr, nil }" 293,"func (rarFormat) Read(input io.Reader, destination string) error { rr, err := rardecode.NewReader(input, """") if err != nil { return fmt.Errorf(""read: failed to create reader: %v"", err) } for { header, err := rr.Next() if err == io.EOF { break } else if err != nil { return err } if header.IsDir { err = mkdir(filepath.Join(destination, header.Name)) if err != nil { return err } continue } err = mkdir(filepath.Dir(filepath.Join(destination, header.Name))) if err != nil { return err } err = writeNewFile(filepath.Join(destination, header.Name), rr, header.Mode()) if err != nil { return err } } return nil }",True,Go,Read,rar.go,https://github.com/mholt/archiver,mholt,Matt Holt,2018-04-17 16:02:35-06:00,"fix: prevent extraction of archived files outside target path (#65) * fix: prevent extraction of archived files outside target path * CR: consolidate the path sanitaiton logic",CWE-22,Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'),"The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.",https://cwe.mitre.org/data/definitions/22.html,CVE-2018-1002207,"func TestIsLocalHostname(t *testing.T) { tests := []struct { hostname string allowlist []string want bool }{ {hostname: ""localhost"", want: true}, {hostname: ""127.0.0.1"", want: true}, {hostname: ""::1"", want: true}, {hostname: ""0:0:0:0:0:0:0:1"", want: true}, {hostname: ""fuf.me"", want: true}, {hostname: ""127.0.0.95"", want: true}, {hostname: ""0.0.0.0"", want: true}, {hostname: ""192.168.123.45"", want: true}, {hostname: ""gogs.io"", want: false}, {hostname: ""google.com"", want: false}, {hostname: ""165.232.140.255"", want: false}, {hostname: ""192.168.123.45"", allowlist: []string{""10.0.0.17""}, want: true}, {hostname: ""gogs.local"", allowlist: []string{""gogs.local""}, want: false}, } for _, test := range tests { t.Run("""", func(t *testing.T) { assert.Equal(t, test.want, IsBlockedLocalHostname(test.hostname, test.allowlist)) }) } }" 297,"func generateDataset(dest []uint32, epoch uint64, cache []uint32) { logger := log.New(""epoch"", epoch) start := time.Now() defer func() { elapsed := time.Since(start) logFn := logger.Debug if elapsed > 3*time.Second { logFn = logger.Info } logFn(""Generated ethash verification cache"", ""elapsed"", common.PrettyDuration(elapsed)) }() swapped := !isLittleEndian() header := *(*reflect.SliceHeader)(unsafe.Pointer(&dest)) header.Len *= 4 header.Cap *= 4 dataset := *(*[]byte)(unsafe.Pointer(&header)) threads := runtime.NumCPU() size := uint64(len(dataset)) var pend sync.WaitGroup pend.Add(threads) var progress uint64 for i := 0; i < threads; i++ { go func(id int) { defer pend.Done() keccak512 := makeHasher(sha3.NewLegacyKeccak512()) batch := uint32((size + hashBytes*uint64(threads) - 1) / (hashBytes * uint64(threads))) first := uint32(id) * batch limit := first + batch if limit > uint32(size/hashBytes) { limit = uint32(size / hashBytes) } percent := size / hashBytes / 100 for index := first; index < limit; index++ { item := generateDatasetItem(cache, index, keccak512) if swapped { swap(item) } copy(dataset[index*hashBytes:], item) if status := atomic.AddUint64(&progress, 1); status%percent == 0 { logger.Info(""Generating DAG in progress"", ""percentage"", (status*100)/(size/hashBytes), ""elapsed"", common.PrettyDuration(time.Since(start))) } } }(i) } pend.Wait() }",True,Go,generateDataset,algorithm.go,https://github.com/ethereum/go-ethereum,ethereum,GitHub,2020-11-11 21:13:12+01:00,"consensus/ethash: use 64bit indexes for the DAG generation (#21793) * Bit boundary fix for the DAG generation routine * Fix unnecessary conversion warnings Co-authored-by: Sergey Pavlov ",CWE-682,Incorrect Calculation,The product performs a calculation that generates incorrect or unintended results that are later used in security-critical decisions or resource management.,https://cwe.mitre.org/data/definitions/682.html,CVE-2020-26240,"func MigratePost(c *context.Context, f form.MigrateRepo) { c.Data[""Title""] = c.Tr(""new_migrate"") ctxUser := checkContextUser(c, f.Uid) if c.Written() { return } c.Data[""ContextUser""] = ctxUser if c.HasError() { c.Success(MIGRATE) return } remoteAddr, err := f.ParseRemoteAddr(c.User) if err != nil { if db.IsErrInvalidCloneAddr(err) { c.Data[""Err_CloneAddr""] = true addrErr := err.(db.ErrInvalidCloneAddr) switch { case addrErr.IsURLError: c.RenderWithErr(c.Tr(""repo.migrate.clone_address"")+c.Tr(""form.url_error""), MIGRATE, &f) case addrErr.IsPermissionDenied: c.RenderWithErr(c.Tr(""repo.migrate.permission_denied""), MIGRATE, &f) case addrErr.IsInvalidPath: c.RenderWithErr(c.Tr(""repo.migrate.invalid_local_path""), MIGRATE, &f) case addrErr.IsBlockedLocalAddress: c.RenderWithErr(c.Tr(""repo.migrate.clone_address_resolved_to_blocked_local_address""), MIGRATE, &f) default: c.Error(err, ""unexpected error"") } } else { c.Error(err, ""parse remote address"") } return } repo, err := db.MigrateRepository(c.User, ctxUser, db.MigrateRepoOptions{ Name: f.RepoName, Description: f.Description, IsPrivate: f.Private || conf.Repository.ForcePrivate, IsUnlisted: f.Unlisted, IsMirror: f.Mirror, RemoteAddr: remoteAddr, }) if err == nil { log.Trace(""Repository migrated [%d]: %s/%s"", repo.ID, ctxUser.Name, f.RepoName) c.Redirect(conf.Server.Subpath + ""/"" + ctxUser.Name + ""/"" + f.RepoName) return } if repo != nil { if errDelete := db.DeleteRepository(ctxUser.ID, repo.ID); errDelete != nil { log.Error(""DeleteRepository: %v"", errDelete) } } if strings.Contains(err.Error(), ""Authentication failed"") || strings.Contains(err.Error(), ""could not read Username"") { c.Data[""Err_Auth""] = true c.RenderWithErr(c.Tr(""form.auth_failed"", db.HandleMirrorCredentials(err.Error(), true)), MIGRATE, &f) return } else if strings.Contains(err.Error(), ""fatal:"") { c.Data[""Err_CloneAddr""] = true c.RenderWithErr(c.Tr(""repo.migrate.failed"", db.HandleMirrorCredentials(err.Error(), true)), MIGRATE, &f) return } handleCreateError(c, ctxUser, err, ""MigratePost"", MIGRATE, &f) }" 300,"func TestGetDynamic(t *testing.T) { savedServices := services savedGetVCSDirFn := getVCSDirFn defer func() { services = savedServices getVCSDirFn = savedGetVCSDirFn }() services = []*service{{pattern: regexp.MustCompile("".*""), get: testGet}} getVCSDirFn = testGet client := &http.Client{Transport: testTransport(testWeb)} for _, tt := range getDynamicTests { dir, err := getDynamic(context.Background(), client, tt.importPath, """") if tt.dir == nil { if err == nil { t.Errorf(""getDynamic(client, %q, etag) did not return expected error"", tt.importPath) } continue } if err != nil { t.Errorf(""getDynamic(client, %q, etag) return unexpected error: %v"", tt.importPath, err) continue } if !cmp.Equal(dir, tt.dir) { t.Errorf(""getDynamic(client, %q, etag) =\n %+v,\nwant %+v"", tt.importPath, dir, tt.dir) for i, f := range dir.Files { var want *File if i < len(tt.dir.Files) { want = tt.dir.Files[i] } t.Errorf(""file %d = %+v, want %+v"", i, f, want) } } } }",True,Go,TestGetDynamic,gosrc_test.go,https://github.com/golang/gddo,golang,Filippo Valsorda,2018-07-03 17:44:36+00:00,"gosrc: validate repo from meta Fixes CVE-2018-12976. Change-Id: I6b87ab692915d46ba4f668ab848473de9b054c8a Reviewed-on: https://go-review.googlesource.com/121358 Reviewed-by: Filippo Valsorda ",CWE-22,Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'),"The product uses external input to construct a pathname that is intended to identify a file or directory that is located underneath a restricted parent directory, but the product does not properly neutralize special elements within the pathname that can cause the pathname to resolve to a location that is outside of the restricted directory.",https://cwe.mitre.org/data/definitions/22.html,CVE-2018-12976,"func validateWebhook(l macaron.Locale, w *db.Webhook) (field, msg string, ok bool) { payloadURL, err := url.Parse(w.URL) if err != nil { return ""PayloadURL"", l.Tr(""repo.settings.webhook.err_cannot_parse_payload_url"", err), false } if netutil.IsBlockedLocalHostname(payloadURL.Hostname(), conf.Security.LocalNetworkAllowlist) { return ""PayloadURL"", l.Tr(""repo.settings.webhook.url_resolved_to_blocked_local_address""), false } return """", """", true }" 303,"func (d *partialArray) add(key string, val *lazyNode) error { if key == ""-"" { *d = append(*d, val) return nil } idx, err := strconv.Atoi(key) if err != nil { return err } ary := make([]*lazyNode, len(*d)+1) cur := *d if idx < 0 { idx *= -1 if idx > len(ary) { return fmt.Errorf(""Unable to access invalid index: %d"", idx) } idx = len(ary) - idx } copy(ary[0:idx], cur[0:idx]) ary[idx] = val copy(ary[idx+1:], cur[idx:]) *d = ary return nil }",True,Go,add,patch.go,https://github.com/evanphx/json-patch,evanphx,Guoliang Wang,2018-05-25 22:54:09+08:00,fix check idx index,CWE-787,Out-of-bounds Write,"The product writes data past the end, or before the beginning, of the intended buffer.",https://cwe.mitre.org/data/definitions/787.html,CVE-2018-14632,"func validateAndCreateWebhook(c *context.Context, orCtx *orgRepoContext, w *db.Webhook) { c.Data[""Webhook""] = w if c.HasError() { c.Success(orCtx.TmplNew) return } field, msg, ok := validateWebhook(c.Locale, w) if !ok { c.FormErr(field) c.RenderWithErr(msg, orCtx.TmplNew, nil) return } if err := w.UpdateEvent(); err != nil { c.Error(err, ""update event"") return } else if err := db.CreateWebhook(w); err != nil { c.Error(err, ""create webhook"") return } c.Flash.Success(c.Tr(""repo.settings.add_hook_success"")) c.Redirect(orCtx.Link + ""/settings/hooks"") }" 304,func (s *Shm) MarkDestroyed() { s.mu.Lock() defer s.mu.Unlock() s.key = linux.IPC_PRIVATE s.pendingDestruction = true s.DecRef() },True,Go,MarkDestroyed,shm.go,https://github.com/google/gvisor,google,Shentubot,2018-11-01 15:54:14-07:00,"Prevent premature destruction of shm segments. Shm segments can be marked for lazy destruction via shmctl(IPC_RMID), which destroys a segment once it is no longer attached to any processes. We were unconditionally decrementing the segment refcount on shmctl(IPC_RMID) which allowed a user to force a segment to be destroyed by repeatedly calling shmctl(IPC_RMID), with outstanding memory maps to the segment. This is problematic because the memory released by a segment destroyed this way can be reused by a different process while remaining accessible by the process with outstanding maps to the segment. PiperOrigin-RevId: 219713660 Change-Id: I443ab838322b4fb418ed87b2722c3413ead21845",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2018-19333,"func validateAndUpdateWebhook(c *context.Context, orCtx *orgRepoContext, w *db.Webhook) { c.Data[""Webhook""] = w if c.HasError() { c.Success(orCtx.TmplNew) return } field, msg, ok := validateWebhook(c.Locale, w) if !ok { c.FormErr(field) c.RenderWithErr(msg, orCtx.TmplNew, nil) return } if err := w.UpdateEvent(); err != nil { c.Error(err, ""update event"") return } else if err := db.UpdateWebhook(w); err != nil { c.Error(err, ""update webhook"") return } c.Flash.Success(c.Tr(""repo.settings.update_hook_success"")) c.Redirect(fmt.Sprintf(""%s/settings/hooks/%d"", orCtx.Link, w.ID)) }" 307,"func Shmctl(t *kernel.Task, args arch.SyscallArguments) (uintptr, *kernel.SyscallControl, error) { id := args[0].Int() cmd := args[1].Int() buf := args[2].Pointer() r := t.IPCNamespace().ShmRegistry() switch cmd { case linux.SHM_STAT: fallthrough case linux.IPC_STAT: segment, err := findSegment(t, id) if err != nil { return 0, nil, syserror.EINVAL } stat, err := segment.IPCStat(t) if err == nil { _, err = t.CopyOut(buf, stat) } return 0, nil, err case linux.IPC_INFO: params := r.IPCInfo() _, err := t.CopyOut(buf, params) return 0, nil, err case linux.SHM_INFO: info := r.ShmInfo() _, err := t.CopyOut(buf, info) return 0, nil, err } segment, err := findSegment(t, id) if err != nil { return 0, nil, syserror.EINVAL } switch cmd { case linux.IPC_SET: var ds linux.ShmidDS _, err = t.CopyIn(buf, &ds) if err != nil { return 0, nil, err } err = segment.Set(t, &ds) return 0, nil, err case linux.IPC_RMID: segment.MarkDestroyed() return 0, nil, nil case linux.SHM_LOCK, linux.SHM_UNLOCK: t.Kernel().EmitUnimplementedEvent(t) return 0, nil, nil default: return 0, nil, syserror.EINVAL } }",True,Go,Shmctl,sys_shm.go,https://github.com/google/gvisor,google,Shentubot,2018-11-01 15:54:14-07:00,"Prevent premature destruction of shm segments. Shm segments can be marked for lazy destruction via shmctl(IPC_RMID), which destroys a segment once it is no longer attached to any processes. We were unconditionally decrementing the segment refcount on shmctl(IPC_RMID) which allowed a user to force a segment to be destroyed by repeatedly calling shmctl(IPC_RMID), with outstanding memory maps to the segment. This is problematic because the memory released by a segment destroyed this way can be reused by a different process while remaining accessible by the process with outstanding maps to the segment. PiperOrigin-RevId: 219713660 Change-Id: I443ab838322b4fb418ed87b2722c3413ead21845",NVD-CWE-noinfo,Insufficient Information,There is insufficient information about the issue to classify it; details are unkown or unspecified.,https://nvd.nist.gov/vuln/categories,CVE-2018-19333,"func isRepositoryGitPath(path string) bool { return strings.HasSuffix(path, "".git"") || strings.Contains(path, "".git/"") || strings.Contains(path, `.git\`) || strings.HasSuffix(path, "".git."") || strings.Contains(path, "".git./"") || strings.Contains(path, `.git.\`) }" 309,"s := strings.Map(func(c rune) rune { switch c { case ' ', '\t', '\n', '\f', '\r': return c } return -1 }, p.tok.Data) if s != """" { p.addText(s) } case StartTagToken: switch p.tok.DataAtom { case a.Html: return inBodyIM(p) case a.Frameset: p.addElement() case a.Frame: p.addElement() p.oe.pop() p.acknowledgeSelfClosingTag() case a.Noframes: return inHeadIM(p) case a.Template: return inTemplateIM(p) } case EndTagToken: switch p.tok.DataAtom { case a.Frameset: if p.oe.top().DataAtom != a.Html { p.oe.pop() if p.oe.top().DataAtom != a.Frameset { p.im = afterFramesetIM return true } } } default: }",True,Go,rune,parse.go,https://github.com/golang/net,golang,Nigel Tao,2018-08-16 10:28:01+00:00,"html: remove special procedure for