Procházet zdrojové kódy

- added some bounds checks since munchclient crashed in production

Tobias Begalke před 7 roky
rodič
revize
e4f4b07019
1 změnil soubory, kde provedl 47 přidání a 2 odebrání
  1. 47 2
      ajp13.go

+ 47 - 2
ajp13.go

@@ -50,15 +50,29 @@ func Parse(payload []byte) (*AJP13, error) {
 	// the request type
 	a.Type = uint8(data[0])
 
+	var err error
+
 	switch a.Type {
 	case ForwardRequest:
-		a.parseForwardRequest(data)
+		err = a.parseForwardRequest(data)
+		if err != nil {
+			return nil, err
+		}
 	}
 
 	return a, nil
 }
 
-func (a *AJP13) parseForwardRequest(data []byte) {
+func checkLength(data []byte, minLen int, location string) error {
+	dataLen := len(data)
+	if dataLen < minLen {
+		return fmt.Errorf("%s: need %d bytes but have %d", location, minLen, dataLen)
+	}
+
+	return nil
+}
+
+func (a *AJP13) parseForwardRequest(data []byte) error {
 
 	// Method
 	a.method = HTTPMethod(uint8(data[1]))
@@ -68,6 +82,11 @@ func (a *AJP13) parseForwardRequest(data []byte) {
 	// Version
 	if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
 		versionLen := binary.BigEndian.Uint16(data[offset : offset+2])
+
+		if err := checkLength(data, int(offset+2+versionLen+1), "parseForwardRequest/Version"); err != nil {
+			return err
+		}
+
 		a.Version = string(data[offset+2 : offset+2+versionLen])
 		offset += versionLen + 1
 	}
@@ -76,6 +95,11 @@ func (a *AJP13) parseForwardRequest(data []byte) {
 	// URI
 	if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
 		uriLen := binary.BigEndian.Uint16(data[offset : offset+2])
+
+		if err := checkLength(data, int(offset+2+uriLen+1), "parseForwardRequest/URI"); err != nil {
+			return err
+		}
+
 		a.URI = string(data[offset+2 : offset+2+uriLen])
 		offset += uriLen + 1
 	}
@@ -84,6 +108,11 @@ func (a *AJP13) parseForwardRequest(data []byte) {
 	// RemoteAddr
 	if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
 		raddrLen := binary.BigEndian.Uint16(data[offset : offset+2])
+
+		if err := checkLength(data, int(offset+2+raddrLen+1), "parseForwardRequest/RemoteAddr"); err != nil {
+			return err
+		}
+
 		a.RemoteAddr = net.ParseIP(string(data[offset+2 : offset+2+raddrLen]))
 		offset += raddrLen + 1
 	}
@@ -92,6 +121,11 @@ func (a *AJP13) parseForwardRequest(data []byte) {
 	// RemoteHost
 	if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
 		rhostLen := binary.BigEndian.Uint16(data[offset : offset+2])
+
+		if err := checkLength(data, int(offset+2+rhostLen+1), "parseForwardRequest/RemoteHost"); err != nil {
+			return err
+		}
+
 		a.RemoteHost = string(data[offset+2 : offset+2+rhostLen])
 		offset += rhostLen + 1
 	}
@@ -100,6 +134,11 @@ func (a *AJP13) parseForwardRequest(data []byte) {
 	// Server
 	if !reflect.DeepEqual(data[offset:offset+2], []byte{0xff, 0xff}) {
 		len := binary.BigEndian.Uint16(data[offset : offset+2])
+
+		if err := checkLength(data, int(offset+2+len+1), "parseForwardRequest/Server"); err != nil {
+			return err
+		}
+
 		a.Server = string(data[offset+2 : offset+2+len])
 		offset += len + 1
 	}
@@ -149,6 +188,7 @@ func (a *AJP13) parseForwardRequest(data []byte) {
 
 	// don't need Attributes for the time being
 
+	return nil
 }
 
 // Length returns the length of the data this AJP13 request consists of
@@ -166,3 +206,8 @@ func (a *AJP13) Header(key string) (string, bool) {
 	val, ok := a.headers[key]
 	return val, ok
 }
+
+// Headers returns all headers
+func (a *AJP13) Headers() map[string]string {
+	return a.headers
+}