-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathgraphql_beautifier.rb
executable file
·129 lines (103 loc) · 3 KB
/
graphql_beautifier.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
require 'java'
java_import 'burp.IBurpExtender'
java_import 'burp.IMessageEditorTab'
java_import 'burp.IMessageEditorTabFactory'
java_import 'burp.IParameter'
$LOAD_PATH.unshift 'BLAH_BLAH_BLAH'
module Delegate; end
module Forwardable; end
require 'graphql'
class BurpExtender
include IBurpExtender, IMessageEditorTabFactory
attr_accessor :callbacks, :helpers
def registerExtenderCallbacks(callbacks)
# keep a reference to our callbacks object
@callbacks = callbacks
# obtain an extension helpers object
@helpers = callbacks.getHelpers
# set our extension name
callbacks.setExtensionName 'GraphQL Beautifier'
# register ourselves as a message editor tab factory
callbacks.registerMessageEditorTabFactory(self)
return
end
#
# implement IMessageEditorTabFactory
#
def createNewInstance(controller, editable)
# create a new instance of our custom editor tab
GraphQLBeautifierTab.new self, controller, editable
end
end
#
# class implementing IMessageEditorTab
#
class GraphQLBeautifierTab
include IMessageEditorTab
def initialize(extender, controller, editable)
@extender = extender
@editable = editable
# create an instance of Burp's text editor, to display our deserialized data
@txtInput = extender.callbacks.createTextEditor
@txtInput.setEditable editable
end
#
# implement IMessageEditorTab
#
def getTabCaption()
'GraphQL Beautifier'
end
def getUiComponent()
@txtInput.getComponent
end
def isGraphQL(content)
requestInfo = @extender.helpers.analyzeRequest(content)
requestInfo.getHeaders.to_a.each do |header|
return true if header.match /Content-Type: application\/graphql/i
end
false
end
def isEnabled(content, isRequest)
# enable this tab for requests containing a data parameter
isRequest and isGraphQL(content)
end
def setMessage(content, isRequest)
if content.nil?
# clear our display
@txtInput.setText nil
@txtInput.setEditable false
else
begin
requestInfo = @extender.helpers.analyzeRequest(content)
body = content[requestInfo.getBodyOffset()..-1].to_s
@txtInput.setText @extender.helpers.stringToBytes(GraphQL.parse(body).to_query_string)
rescue => e
@txtInput.setText @extender.helpers.stringToBytes("Unable to parse GraphQL: #{e.to_s}")
end
@txtInput.setEditable @editable
end
# remember the displayed content
@currentMessage = content
return
end
def getMessage()
# determine whether the user modified the deserialized data
if @txtInput.isTextModified
begin
requestInfo = @extender.helpers.analyzeRequest(@currentMessage)
bodyBytes = @extender.helpers.stringToBytes(GraphQL.parse(@txtInput.getText.to_s).to_query_string)
@extender.helpers.buildHttpMessage(requestInfo.getHeaders(), bodyBytes)
rescue => e
@currentMessage
end
else
@currentMessage
end
end
def isModified()
@txtInput.isTextModified
end
def getSelectedData()
@txtInput.getSelectedText
end
end