Skip to content

Commit e57ef0b

Browse files
authored
Merge pull request #29 from edoardottt/devel
v0.0.2
2 parents f9af03f + 0825816 commit e57ef0b

7 files changed

Lines changed: 137 additions & 15 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ OUTPUT:
7575
-o, -output string File to write output results
7676
-v, -verbose Verbose output
7777
-s, -silent Silent output. Print only results
78+
-j, -json JSON output
7879
```
7980

8081
Examples 💡

pkg/input/flags.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type Options struct {
4141
RateLimit int
4242
Silent bool
4343
Verbose bool
44+
JSON bool
4445
}
4546

4647
func (options *Options) configureOutput() {
@@ -88,6 +89,7 @@ func ParseOptions() *Options {
8889
flagSet.StringVarP(&options.FileOutput, "output", "o", "", `File to write output results`),
8990
flagSet.BoolVarP(&options.Verbose, "verbose", "v", false, `Verbose output`),
9091
flagSet.BoolVarP(&options.Silent, "silent", "s", false, `Silent output. Print only results`),
92+
flagSet.BoolVarP(&options.JSON, "json", "j", false, `JSON output`),
9193
)
9294

9395
if help() || noArgs() {

pkg/output/banner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import "github.com/projectdiscovery/gologger"
1111
var printed = false
1212

1313
const (
14-
Version = "v0.0.1"
14+
Version = "v0.0.2"
1515
banner = ` __ __
1616
____ ____ / /_ ____ ______/ /__
1717
/ __ \/ __ \/ __ \/ __ ` + "`" + `/ ___/ //_/

pkg/output/json.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
pphack - The Most Advanced Client-Side Prototype Pollution Scanner
3+
4+
This repository is under MIT License https://github.com/edoardottt/pphack/blob/main/LICENSE
5+
*/
6+
7+
package output
8+
9+
import "encoding/json"
10+
11+
// JSONData.
12+
type JSONData struct {
13+
URL string `json:"URL,omitempty"`
14+
JSEvaluation string `json:"JSEvaluation,omitempty"`
15+
Error string `json:"Error,omitempty"`
16+
}
17+
18+
// FormatJSON returns the input as JSON string.
19+
func FormatJSON(url, jsEval, e string) ([]byte, error) {
20+
input := &JSONData{
21+
URL: url,
22+
JSEvaluation: jsEval,
23+
Error: e,
24+
}
25+
26+
jsonOutput, err := json.Marshal(input)
27+
if err != nil {
28+
return nil, err
29+
}
30+
31+
return jsonOutput, nil
32+
}

pkg/output/json_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
pphack - The Most Advanced Client-Side Prototype Pollution Scanner
3+
4+
This repository is under MIT License https://github.com/edoardottt/pphack/blob/main/LICENSE
5+
*/
6+
7+
package output_test
8+
9+
import (
10+
"reflect"
11+
"testing"
12+
13+
"github.com/edoardottt/pphack/pkg/output"
14+
)
15+
16+
func TestFormatJSON(t *testing.T) {
17+
tests := []struct {
18+
name string
19+
input output.JSONData
20+
want string
21+
}{
22+
{name: "no error",
23+
input: output.JSONData{
24+
URL: "https://edoardottt.github.io/pp-test?constructor.prototype.oigczu=oigczu\u0026__proto__[oigczu]=" +
25+
"oigczu\u0026constructor[prototype][oigczu]=oigczu\u0026__proto__.oigczu=oigczu\u0026__proto__." +
26+
"oigczu=1|2|3\u0026__proto__[oigczu]={\"json\":\"value\"}#__proto__[oigczu]=oigczu",
27+
JSEvaluation: "oigczu",
28+
Error: "",
29+
},
30+
want: `{"URL":"https://edoardottt.github.io/pp-test?constructor.prototype.oigczu=oigczu\u0026__proto__` +
31+
`[oigczu]=oigczu\u0026constructor[prototype][oigczu]=oigczu\u0026__proto__.oigczu=oigczu\u0026__proto__.` +
32+
`oigczu=1|2|3\u0026__proto__[oigczu]={\"json\":\"value\"}#__proto__[oigczu]=oigczu","JSEvaluation":"oigczu"}`,
33+
},
34+
{name: "error",
35+
input: output.JSONData{
36+
URL: "https://edoardottt.github.io/pp-tes?constructor.prototype.sqtiwx=sqtiwx\u0026__proto__[sqtiwx]" +
37+
"=sqtiwx\u0026constructor[prototype][sqtiwx]=sqtiwx\u0026__proto__.sqtiwx=sqtiwx\u0026__proto__." +
38+
"sqtiwx=1|2|3\u0026__proto__[sqtiwx]={\"json\":\"value\"}#__proto__[sqtiwx]=sqtiwx",
39+
JSEvaluation: "",
40+
Error: "encountered an undefined value",
41+
},
42+
want: `{"URL":"https://edoardottt.github.io/pp-tes?constructor.prototype.sqtiwx=sqtiwx\u0026__proto__[sqtiwx]` +
43+
`=sqtiwx\u0026constructor[prototype][sqtiwx]=sqtiwx\u0026__proto__.sqtiwx=sqtiwx\u0026__proto__.` +
44+
`sqtiwx=1|2|3\u0026__proto__[sqtiwx]={\"json\":\"value\"}#__proto__[sqtiwx]=` +
45+
`sqtiwx","Error":"encountered an undefined value"}`,
46+
},
47+
}
48+
49+
for _, tt := range tests {
50+
t.Run(tt.name, func(t *testing.T) {
51+
got, _ := output.FormatJSON(tt.input.URL, tt.input.JSEvaluation, tt.input.Error)
52+
if !reflect.DeepEqual(string(got), tt.want) {
53+
t.Errorf("GetJSONString\n%v", string(got))
54+
t.Errorf("want\n%v", tt.want)
55+
}
56+
})
57+
}
58+
}

pkg/scan/runner.go

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,7 @@ func (r *Runner) Run() {
113113
for value := range r.InputChan {
114114
targetURL, err := PrepareURL(value, testPayload)
115115
if err != nil {
116-
if r.Options.Verbose {
117-
gologger.Error().Msg(err.Error())
118-
}
116+
verboseOutput(r, value, err)
119117
}
120118

121119
ctx, cancel := context.WithTimeout(pctx, time.Second*time.Duration(r.Options.Timeout))
@@ -125,13 +123,15 @@ func (r *Runner) Run() {
125123

126124
res, err := Scan(ctx, js, targetURL)
127125
if err != nil {
128-
if r.Options.Verbose {
129-
gologger.Error().Msg(err.Error())
130-
}
126+
verboseOutput(r, targetURL, err)
131127
}
132128

133129
if resTrimmed := strings.TrimSpace(res); resTrimmed != "" {
134-
writeOutput(r, targetURL)
130+
if err != nil {
131+
writeOutput(r, targetURL, res, err.Error())
132+
} else {
133+
writeOutput(r, targetURL, res, "")
134+
}
135135
}
136136

137137
cancel()
@@ -146,13 +146,13 @@ func (r *Runner) Run() {
146146
wg.Wait()
147147
}
148148

149-
func writeOutput(r *Runner, targetURL string) {
150-
if !r.Result.Printed(targetURL) {
151-
write(r.OutMutex, &r.Options, targetURL)
149+
func writeOutput(r *Runner, url, jsEval, err string) {
150+
if !r.Result.Printed(url) {
151+
write(r.OutMutex, &r.Options, url, jsEval, err)
152152
}
153153
}
154154

155-
func write(m *sync.Mutex, options *input.Options, o string) {
155+
func write(m *sync.Mutex, options *input.Options, u, jse, e string) {
156156
if options.FileOutput != "" && options.Output == nil {
157157
file, err := os.OpenFile(options.FileOutput, os.O_CREATE|os.O_RDWR|os.O_APPEND, 0644)
158158
if err != nil {
@@ -162,15 +162,44 @@ func write(m *sync.Mutex, options *input.Options, o string) {
162162
options.Output = file
163163
}
164164

165+
var (
166+
o []byte
167+
err error
168+
)
169+
170+
if options.JSON {
171+
o, err = output.FormatJSON(u, jse, e)
172+
if err != nil {
173+
gologger.Fatal().Msg(err.Error())
174+
}
175+
} else {
176+
o = []byte(u)
177+
}
178+
165179
m.Lock()
166180

167181
if options.Output != nil {
168-
if _, err := options.Output.Write([]byte(o + "\n")); err != nil && options.Verbose {
182+
if _, err := options.Output.Write([]byte(string(o) + "\n")); err != nil && options.Verbose {
169183
gologger.Fatal().Msg(err.Error())
170184
}
171185
}
172186

173187
m.Unlock()
174188

175-
fmt.Println(o)
189+
fmt.Println(string(o))
190+
}
191+
192+
func verboseOutput(r *Runner, value string, err error) {
193+
if r.Options.Verbose {
194+
if r.Options.JSON {
195+
o, err := output.FormatJSON(value, "", err.Error())
196+
if err != nil {
197+
gologger.Error().Msg(err.Error())
198+
}
199+
200+
fmt.Println(string(o))
201+
} else {
202+
gologger.Error().Msg(err.Error())
203+
}
204+
}
176205
}

snapcraft.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: pphack
22
summary: The Most Advanced Client-Side Prototype Pollution Scanner
33
description: |
44
The Most Advanced Client-Side Prototype Pollution Scanner
5-
version: 0.0.1
5+
version: 0.0.2
66
grade: stable
77
base: core20
88

0 commit comments

Comments
 (0)