Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Confused

A tool for checking for lingering free namespaces for private package names referenced in dependency configuration
for Python (pypi) `requirements.txt`, JavaScript (npm) `package.json`, PHP (composer) `composer.json` or MVN (maven) `pom.xml`.
for Python (pypi) `requirements.txt` and `Pipfile`, JavaScript (npm) `package.json`, PHP (composer) `composer.json` or MVN (maven) `pom.xml`.

## What is this all about?

Expand Down Expand Up @@ -46,7 +46,7 @@ Usage:

Usage of ./confused:
-l string
Package repository system. Possible values: "pip", "npm", "composer", "mvn" (default "npm")
Package repository system. Possible values: "pip", "pipenv", "npm", "composer", "mvn" (default "npm")
-s string
Comma-separated list of known-secure namespaces. Supports wildcards
-v Verbose output
Expand All @@ -64,6 +64,14 @@ Issues found, the following packages are not available in public package reposit

```

```
./confused -l pipenv Pipfile

Issues found, the following packages are not available in public package repositories:
[!] internal_package1

```

### JavaScript (npm)
```
./confused -l npm package.json
Expand Down
6 changes: 3 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func main() {
verbose := false
filename := ""
safespaces := ""
flag.StringVar(&lang, "l", "npm", "Package repository system. Possible values: \"pip\", \"npm\", \"composer\", \"mvn\"")
flag.StringVar(&lang, "l", "npm", "Package repository system. Possible values: \"pip\", \"pipenv\", \"npm\", \"composer\", \"mvn\"")
flag.StringVar(&safespaces, "s", "", "Comma-separated list of known-secure namespaces. Supports wildcards")
flag.BoolVar(&verbose, "v", false, "Verbose output")
flag.Parse()
Expand All @@ -34,8 +34,8 @@ func main() {
}

filename = flag.Args()[0]
if lang == "pip" {
resolver = NewPythonLookup(verbose)
if lang == "pip" || lang == "pipenv" {
resolver = NewPythonLookup(verbose, lang)
} else if lang == "npm" {
resolver = NewNPMLookup(verbose)
} else if lang == "composer" {
Expand Down
49 changes: 44 additions & 5 deletions pip.go → python.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,42 @@ package main

import (
"fmt"
"github.com/pelletier/go-toml"
"io/ioutil"
"net/http"
"strings"
)

// PythonLookup represents a collection of python packages to be tested for dependency confusion.
type PythonLookup struct {
Packages []string
Verbose bool
Packages []string
Verbose bool
PackageManager string
}

// NewPythonLookup constructs a `PythonLookup` struct and returns it
func NewPythonLookup(verbose bool) PackageResolver {
return &PythonLookup{Packages: []string{}, Verbose: verbose}
func NewPythonLookup(verbose bool, packageManager string) PackageResolver {
return &PythonLookup{Packages: []string{}, Verbose: verbose, PackageManager: packageManager}
}

// ReadPackagesFromFile reads package information from a python `requirements.txt` file
// ReadPackagesFromFile chooses a file parser based on the user-supplied python package manager.
//
// Returns any errors encountered
func (p *PythonLookup) ReadPackagesFromFile(filename string) error {
switch p.PackageManager {
case "pip":
return p.ReadPackagesFromRequirementsTxt(filename)
case "pipenv":
return p.ReadPackagesFromPipfile(filename)
default:
return fmt.Errorf("Python package manager not implemented: %s", p.PackageManager)
}
}

// ReadPackagesFromRequirementsTxt reads package information from a python `requirements.txt`.
//
// Returns any errors encountered
func (p *PythonLookup) ReadPackagesFromRequirementsTxt(filename string) error {
rawfile, err := ioutil.ReadFile(filename)
if err != nil {
return err
Expand Down Expand Up @@ -50,6 +66,29 @@ func (p *PythonLookup) ReadPackagesFromFile(filename string) error {
return nil
}

// ReadPackagesFromPipfile reads package information from a python `Pipfile`.
//
// Returns any errors encountered
func (p *PythonLookup) ReadPackagesFromPipfile(filename string) error {
rawfile, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
config, err := toml.Load(string(rawfile))
if err != nil {
return err
}
packages := config.Get("packages")
if packages != nil {
p.Packages = append(p.Packages, packages.(*toml.Tree).Keys()...)
}
dev_packages := config.Get("dev-packages")
if dev_packages != nil {
p.Packages = append(p.Packages, dev_packages.(*toml.Tree).Keys()...)
}
return nil
}

// PackagesNotInPublic determines if a python package does not exist in the pypi package repository.
//
// Returns a slice of strings with any python packages not in the pypi package repository
Expand Down