go.grpc.security.grpc-server-insecure-connection.grpc-server-insecure-connection

Verifed by r2c
Community Favorite
profile photo of returntocorpreturntocorp
Author
178,438
Download Count*

Found an insecure gRPC server without 'grpc.Creds()' or options with credentials. This allows for a connection without encryption to this server. A malicious attacker could tamper with the gRPC message, which could compromise the machine. Include credentials derived from an SSL certificate in order to create a secure gRPC connection. You can create credentials using 'credentials.NewServerTLSFromFile("cert.pem", "cert.key")'.

Run Locally

Run in CI

Defintion

rules:
  - id: grpc-server-insecure-connection
    metadata:
      cwe: "CWE-300: Channel Accessible by Non-Endpoint"
      references:
        - https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption
      category: security
      technology:
        - grpc
      confidence: HIGH
      license: Commons Clause License Condition v1.0[LGPL-2.1-only]
    message: Found an insecure gRPC server without 'grpc.Creds()' or options with
      credentials. This allows for a connection without encryption to this
      server. A malicious attacker could tamper with the gRPC message, which
      could compromise the machine. Include credentials derived from an SSL
      certificate in order to create a secure gRPC connection. You can create
      credentials using 'credentials.NewServerTLSFromFile("cert.pem",
      "cert.key")'.
    languages:
      - go
    severity: ERROR
    patterns:
      - pattern-not: grpc.NewServer(..., grpc.Creds(...), ...)
      - pattern-not-inside: |
          $OPTS := []grpc.ServerOption{
            ...,
            grpc.Creds(credentials.NewClientTLSFromCert(...)),
            ...,
          }
          grpc.NewServer($OPTS...)
      - pattern-not-inside: |
          $CREDS := credentials.NewClientTLSFromCert(...)
          ...
          $OPTS := []grpc.ServerOption{
            ...,
            $CREDS,
            ...,
          }
          grpc.NewServer($OPTS...)
      - pattern: grpc.NewServer(...)

Examples

grpc-server-insecure-connection.go

package insecuregrpc

import (
	"crypto/x509"
	"log"
	"net/http"
	"net/http/httptest"

	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

// cf. https://blog.gopheracademy.com/advent-2019/go-grps-and-tls/#connection-without-encryption
func unsafe() {
	// Server
	// ruleid:grpc-server-insecure-connection
	s := grpc.NewServer()
	// ... register gRPC services ...
	if err = s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

func safe() {
	// Server
	// ok:grpc-server-insecure-connection
	s := grpc.NewServer(grpc.Creds(credentials.NewClientTLSFromCert(x509.NewCertPool(), "")))
	// ... register gRPC services ...
	if err = s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

// False Positive test
// cf. https://github.com/daghan/invoicer-chapter2/blob/4c5b00408a4aeece86d98ad3ef1c88e610053dfc/vendor/golang.org/x/net/websocket/websocket_test.go#L129
func startServer() {
	http.Handle("/echo", Handler(echoServer))
	http.Handle("/count", Handler(countServer))
	http.Handle("/ctrldata", Handler(ctrlAndDataServer))
	subproto := Server{
		Handshake: subProtocolHandshake,
		Handler:   Handler(subProtoServer),
	}
	http.Handle("/subproto", subproto)
	// ok:grpc-server-insecure-connection
	server := httptest.NewServer(nil)
	serverAddr = server.Listener.Addr().String()
	log.Print("Test WebSocket server listening on ", serverAddr)
}

// False Positive test - options have grpc.Creds
func startServerWithOpts() {
	options := []grpc.ServerOption{
		grpc.Creds(credentials.NewClientTLSFromCert(pool, addr)),
	}
	// ok:grpc-server-insecure-connection
	grpcServer := grpc.NewServer(options...)
	_ = grpcServer
}

// False Positive test - options have grpc.Creds, credentials in a variable
func startServerCredsVar() {
	creds := credentials.NewClientTLSFromCert(xpool, xaddr)
	options := []grpc.ServerOption{
		creds,
		grpc.UnaryInterceptor(auth.GRPCInterceptor),
	}
	// ok:grpc-server-insecure-connection
	grpcServer := grpc.NewServer(options...)
	_ = grpcServer
}