Giter VIP home page Giter VIP logo

jsluice's Introduction

jsluice

Go Reference

jsluice is a Go package and command-line tool for extracting URLs, paths, secrets, and other interesting data from JavaScript source code.

If you want to do those things right away: look at the command-line tool.

If you want to integrate jsluice's capabilities with your own project: look at the examples, and read the package documentation.

Install

To install the command-line tool, run:

▶ go install github.com/BishopFox/jsluice/cmd/jsluice@latest

To add the package to your project, run:

▶ go get github.com/BishopFox/jsluice

Extracting URLs

Rather than using regular expressions alone, jsluice uses go-tree-sitter to look for places that URLs are known to be used, such as being assigned to document.location, passed to window.open(), or passed to fetch() etc.

A simple example program is provided here:

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)
}

Running the example:

▶ 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\""
}

Note that the value of the redirect query string parameter is EXPR. Code like this is common in JavaScript:

document.location = "/login?redirect=" + redirect + "&method=oauth"

jsluice understands string concatenation, and replaces any expressions it cannot know the value of with EXPR. Although not a foolproof solution, this approach results in a valid URL or path more often than not, and means that it's possible to discover things that aren't easily found using other approaches. In this case, a naive regular expression may well miss the method query string parameter:

▶ JS='document.location = "/login?redirect=" + redirect + "&method=oauth"'
▶ echo $JS | grep -oE 'document\.location = "[^"]+"'
document.location = "/login?redirect="

Custom URL Matchers

jsluice comes with some built-in URL matchers for common scenarios, but you can add more with the AddURLMatcher function:

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)
}

There's a copy of this example here. You can run it like this:

▶ go run examples/urlmatcher/main.go
mailto:[email protected]
https://example.com

jsluice doesn't match mailto: URIs by default, it was found by the custom URLMatcher.

Extracting Secrets

As well as URLs, jsluice can extract secrets. As with URL extraction, custom matchers can be supplied to supplement the default matchers. There's a short example program here that does just that:

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)
}

Running the example:

▶ 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/"
  }
}

Because we have a syntax tree available for the entire JavaScript source, it was possible to inspect both the key and value, and also to easily provide the parent object as context for the match.

jsluice's People

Contributors

bf-tomnomnom avatar secgus avatar c3l3si4n avatar bf-arhodes avatar hackerandya avatar dptsec avatar testwill avatar osxtest avatar

Stargazers

mr_ofcodyx avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.