
जावास्क्रिप्ट से URLs, पथ, रहस्य और अन्य दिलचस्प जानकारी निकालें
jsluice एक Go पैकेज और कमांड-लाइन टूल है, जो JavaScript सोर्स कोड से URLs, पथ, सीक्रेट्स और अन्य दिलचस्प डेटा निकालने के लिए है।
यदि आप इन कामों को तुरंत करना चाहते हैं: कमांड-लाइन टूल देखें।
यदि आप jsluice की क्षमताओं को अपने प्रोजेक्ट में एकीकृत करना चाहते हैं: उदाहरण देखें, और पैकेज दस्तावेज़ीकरण पढ़ें।
कमांड-लाइन टूल इंस्टॉल करने के लिए, चलाएँ:
▶ go install github.com/BishopFox/jsluice/cmd/jsluice@latest
पैकेज को अपने प्रोजेक्ट में जोड़ने के लिए, चलाएँ:
▶ go get github.com/BishopFox/jsluice
केवल रेगुलर एक्सप्रेशन का उपयोग करने के बजाय, jsluice go-tree-sitter का उपयोग करके उन स्थानों को खोजता है जहाँ URLs का उपयोग किया जाना ज्ञात होता है, जैसे document.location को असाइन किया जाना, window.open() को पास किया जाना, या fetch() को पास किया जाना आदि।
एक सरल उदाहरण प्रोग्राम यहाँ दिया गया है:
analyzer := jsluice.NewAnalyzer([]byte(`
const login = (redirect) => {
document.location = "/login?redirect=" + redirect + "&method=oauth"
}
`))
for _, url := range analyzer.GetURLs() {
j, err := json.MarshalIndent(url, "", " ")
if err != nil {
continue
}
fmt.Printf("%s\n", j)
}
उदाहरण चलाना:
▶ go run examples/basic/main.go
{
"url": "/login?redirect=EXPR\u0026method=oauth",
"queryParams": [
"method",
"redirect"
],
"bodyParams": [],
"method": "GET",
"type": "locationAssignment",
"source": "document.location = \"/login?redirect=\" + redirect + \"\u0026method=oauth\""
}
ध्यान दें कि redirect क्वेरी स्ट्रिंग पैरामीटर का मान EXPR है।
इस तरह का कोड JavaScript में आम है:
document.location = "/login?redirect=" + redirect + "&method=oauth"
jsluice स्ट्रिंग संयोजन को समझता है, और किसी भी ऐसे एक्सप्रेशन को EXPR से बदल देता है जिसका मान वह नहीं जान सकता। यद्यपि यह कोई अचूक समाधान नहीं है, यह दृष्टिकोण अक्सर एक मान्य URL या पथ उत्पन्न करता है, और इसका अर्थ है कि ऐसी चीज़ों को खोजना संभव है जो अन्य दृष्टिकोणों से आसानी से नहीं मिलतीं। इस मामले में, एक साधारण रेगुलर एक्सप्रेशन method क्वेरी स्ट्रिंग पैरामीटर को चूक सकता है:
▶ JS='document.location = "/login?redirect=" + redirect + "&method=oauth"'
▶ echo $JS | grep -oE 'document\.location = "[^"]+"'
document.location = "/login?redirect="
jsluice में सामान्य परिदृश्यों के लिए कुछ अंतर्निहित URL मैचर शामिल हैं, लेकिन आप AddURLMatcher फ़ंक्शन के साथ और अधिक जोड़ सकते हैं:
analyzer := jsluice.NewAnalyzer([]byte(`
var fn = () => {
var meta = {
contact: "mailto:[email protected]",
home: "https://example.com"
}
return meta
}
`))
analyzer.AddURLMatcher(
// The first value in the jsluice.URLMatcher struct is the type of node to look for.
// It can be one of "string", "assignment_expression", or "call_expression"
jsluice.URLMatcher{"string", func(n *jsluice.Node) *jsluice.URL {
val := n.DecodedString()
if !strings.HasPrefix(val, "mailto:") {
return nil
}
return &jsluice.URL{
URL: val,
Type: "mailto",
}
}},
)
for _, match := range analyzer.GetURLs() {
fmt.Println(match.URL)
}
इस उदाहरण की एक प्रति यहाँ है। आप इसे इस तरह चला सकते हैं:
▶ go run examples/urlmatcher/main.go
mailto:[email protected]
https://example.com
jsluice डिफ़ॉल्ट रूप से mailto: URIs को मैच नहीं करता; इसे कस्टम URLMatcher द्वारा खोजा गया था।
URLs के साथ-साथ, jsluice सीक्रेट्स भी निकाल सकता है। URL निष्कर्षण की तरह, डिफ़ॉल्ट मैचरों को पूरक करने के लिए कस्टम मैचर प्रदान किए जा सकते हैं। यहाँ एक छोटा उदाहरण प्रोग्राम है जो ठीक यही करता है:
analyzer := jsluice.NewAnalyzer([]byte(`
var config = {
apiKey: "AUTH_1a2b3c4d5e6f",
apiURL: "https://api.example.com/v2/"
}
`))
analyzer.AddSecretMatcher(
// The first value in the jsluice.SecretMatcher struct is a
// tree-sitter query to run on the JavaScript source.
jsluice.SecretMatcher{"(pair) @match", func(n *jsluice.Node) *jsluice.Secret {
key := n.ChildByFieldName("key").DecodedString()
value := n.ChildByFieldName("value").DecodedString()
if !strings.Contains(key, "api") {
return nil
}
if !strings.HasPrefix(value, "AUTH_") {
return nil
}
return &jsluice.Secret{
Kind: "fakeApi",
Data: map[string]string{
"key": key,
"value": value,
},
Severity: jsluice.SeverityLow,
Context: n.Parent().AsMap(),
}
}},
)
for _, match := range analyzer.GetSecrets() {
j, err := json.MarshalIndent(match, "", " ")
if err != nil {
continue
}
fmt.Printf("%s\n", j)
}
उदाहरण चलाना:
▶ go run examples/secrets/main.go
[2023-06-14T13:04:16+0100]
{
"kind": "fakeApi",
"data": {
"key": "apiKey",
"value": "AUTH_1a2b3c4d5e6f"
},
"severity": "low",
"context": {
"apiKey": "AUTH_1a2b3c4d5e6f",
"apiURL": "https://api.example.com/v2/"
}
}
क्योंकि हमारे पास संपूर्ण JavaScript सोर्स के लिए एक सिंटैक्स ट्री उपलब्ध है, इसलिए key और value दोनों का निरीक्षण करना संभव था, और मैच के लिए संदर्भ के रूप में पैरेंट ऑब्जेक्ट को आसानी से प्रदान करना भी संभव था।