- Implemented a new tool `stella-callgraph-node` that extracts call graphs from JavaScript/TypeScript projects using Babel AST. - Added command-line interface with options for JSON output and help. - Included functionality to analyze project structure, detect functions, and build call graphs. - Created a package.json file for dependency management. feat: introduce stella-callgraph-python for Python call graph extraction - Developed `stella-callgraph-python` to extract call graphs from Python projects using AST analysis. - Implemented command-line interface with options for JSON output and verbose logging. - Added framework detection to identify popular web frameworks and their entry points. - Created an AST analyzer to traverse Python code and extract function definitions and calls. - Included requirements.txt for project dependencies. chore: add framework detection for Python projects - Implemented framework detection logic to identify frameworks like Flask, FastAPI, Django, and others based on project files and import patterns. - Enhanced the AST analyzer to recognize entry points based on decorators and function definitions.
87 lines
1.9 KiB
Go
87 lines
1.9 KiB
Go
// grpc-sql benchmark case
|
|
// Demonstrates SQL injection sink reachable via gRPC handler
|
|
package main
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
|
"google.golang.org/grpc"
|
|
)
|
|
|
|
// User represents a user record
|
|
type User struct {
|
|
ID string
|
|
Name string
|
|
Email string
|
|
}
|
|
|
|
// userServer implements the gRPC UserService
|
|
type userServer struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
// GetUser - VULNERABLE: SQL injection sink
|
|
// User ID is concatenated directly into SQL query
|
|
func (s *userServer) GetUser(ctx context.Context, userID string) (*User, error) {
|
|
// SINK: database/sql.Query with string concatenation
|
|
query := fmt.Sprintf("SELECT id, name, email FROM users WHERE id = '%s'", userID)
|
|
row := s.db.QueryRow(query)
|
|
|
|
var user User
|
|
if err := row.Scan(&user.ID, &user.Name, &user.Email); err != nil {
|
|
return nil, fmt.Errorf("user not found: %w", err)
|
|
}
|
|
|
|
return &user, nil
|
|
}
|
|
|
|
// GetUserSafe - SAFE: uses parameterized query
|
|
func (s *userServer) GetUserSafe(ctx context.Context, userID string) (*User, error) {
|
|
query := "SELECT id, name, email FROM users WHERE id = ?"
|
|
row := s.db.QueryRow(query, userID)
|
|
|
|
var user User
|
|
if err := row.Scan(&user.ID, &user.Name, &user.Email); err != nil {
|
|
return nil, fmt.Errorf("user not found: %w", err)
|
|
}
|
|
|
|
return &user, nil
|
|
}
|
|
|
|
func main() {
|
|
db, err := sql.Open("sqlite3", ":memory:")
|
|
if err != nil {
|
|
log.Fatalf("failed to open database: %v", err)
|
|
}
|
|
defer db.Close()
|
|
|
|
// Initialize schema
|
|
_, err = db.Exec(`
|
|
CREATE TABLE users (
|
|
id TEXT PRIMARY KEY,
|
|
name TEXT,
|
|
email TEXT
|
|
)
|
|
`)
|
|
if err != nil {
|
|
log.Fatalf("failed to create table: %v", err)
|
|
}
|
|
|
|
lis, err := net.Listen("tcp", ":50051")
|
|
if err != nil {
|
|
log.Fatalf("failed to listen: %v", err)
|
|
}
|
|
|
|
s := grpc.NewServer()
|
|
// Register service here (simplified for benchmark)
|
|
log.Printf("gRPC server listening on %v", lis.Addr())
|
|
if err := s.Serve(lis); err != nil {
|
|
log.Fatalf("failed to serve: %v", err)
|
|
}
|
|
}
|