Skip to content

Commit

Permalink
Fix hackenproof (#166)
Browse files Browse the repository at this point in the history
Co-authored-by: arkadiyt <>
  • Loading branch information
arkadiyt authored Jul 7, 2024
1 parent c33e2b9 commit 1206830
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 3,547 deletions.
61 changes: 27 additions & 34 deletions lib/bounty-targets/hackenproof.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,19 @@ def directory_index
programs = []

::Kernel.loop do
document = ::Nokogiri::HTML(::SsrfFilter.get("https://hackenproof.com/programs?page=#{page}").body)
programs.concat(document.css('div.bounty-programs-list--items').map do |node|
link = node.css('div.program-title a').first
document = ::JSON.parse(::SsrfFilter.get("https://hackenproof.com/bug-bounty-programs-list?page=#{page}").body)
programs.concat(document['programs'].map do |program|
{
id: link.attributes['href'].value,
name: link.inner_text.strip,
url: URI.join('https://hackenproof.com', link.attributes['href'].value).to_s,
archived: node.classes.include?('archived-program'),
triaged_by_hackenproof: !node.css('.triaged-by').empty?
id: program['id'],
name: program['program_name'].strip,
slug: program['slug'],
url: "https://hackenproof.com/programs/#{program['slug']}",
archived: program['status'] == 'archived',
triaged_by_hackenproof: program['managed_by_company_name'] == 'HackenProof'
}
end)

break if document.css('.next').empty?
break if document['next_page'].nil?

page += 1
end
Expand All @@ -57,38 +57,31 @@ def directory_index

def program_scopes(program)
retryable do
response = ::SsrfFilter.get(program[:url])
raise StandardError, "#{response.code} response from Hackenproof" unless response.code == '200'

document = ::Nokogiri::HTML(response.body)
h4s = document.css('div#in_scope h4')
response = ::JSON.parse(::SsrfFilter.get("https://hackenproof.com/bug-bounty-programs-list/#{program[:slug]}").body)
grouped = response['scopes'].group_by do |scope|
scope['out_of_scope']
end
{
targets: {
in_scope: scopes_to_hashes(h4s[0]),
out_of_scope: scopes_to_hashes(h4s[1])
in_scope: (grouped[false] || []).map do |scope|
normalize_scope(scope)
end,
out_of_scope: (grouped[true] || []).map do |scope|
normalize_scope(scope)
end
}
}
end
end

def scopes_to_hashes(tag)
return [] unless tag

table = ::Kernel.loop do
tag = tag.next
break tag if tag.name == 'table'
end

table.css('tbody > tr').map do |row|
scopes_target = row.css('.scopes-target-inner')
{
target: scopes_target.css('h5').remove.inner_text.strip,
type: row.css('.type-cell').inner_text.strip,
instruction: scopes_target.inner_text.strip,
severity: row.css('.severity-cell').inner_text.strip,
reward: row.css('.reward-cell').inner_text.strip
}
end
def normalize_scope(scope)
{
target: scope['target'],
type: scope['type'],
instruction: (scope['target_description'] || '').strip,
severity: scope['severity'],
reward: scope['reward_type']
}
end
end
end
78 changes: 30 additions & 48 deletions spec/bounty-targets/hackenproof_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,61 +8,43 @@
end

it 'fetches a list of programs' do
stub_request(:get, %r{/programs\?page=1}).with(headers: {host: 'hackenproof.com'}).to_return(status: 200,
body: File.read('spec/fixtures/hackenproof/programs_1.html'))
stub_request(:get, %r{/programs\?page=2}).with(headers: {host: 'hackenproof.com'}).to_return(status: 200,
body: File.read('spec/fixtures/hackenproof/programs_2.html'))
stub_request(:get, %r{/bug-bounty-programs-list\?page=1}).with(headers: {host: 'hackenproof.com'}).to_return(status:
200, body: File.read('spec/fixtures/hackenproof/programs_1.json'))
stub_request(:get, %r{/bug-bounty-programs-list\?page=2}).with(headers: {host: 'hackenproof.com'}).to_return(status:
200, body: File.read('spec/fixtures/hackenproof/programs_2.json'))

expect(client.directory_index).to eq(
[{id: '/hacken/hackenproof', name: 'HackenProof', url: 'https://hackenproof.com/hacken/hackenproof',
archived: false, triaged_by_hackenproof: true},
{id: '/kuna/kuna-crypto-exchange', name: 'Kuna Crypto Exchange',
url: 'https://hackenproof.com/kuna/kuna-crypto-exchange', archived: false, triaged_by_hackenproof: true},
{id: '/vechain/vechainthor', name: 'VeChainThor', url: 'https://hackenproof.com/vechain/vechainthor',
archived: false, triaged_by_hackenproof: true},
{id: '/vechain/vechainthor-wallet', name: 'VeChainThor Wallet',
url: 'https://hackenproof.com/vechain/vechainthor-wallet', archived: false, triaged_by_hackenproof: true},
{id: '/gate-dot-io/gate-dot-io-exchange', name: 'Gate.io Exchange', url:
'https://hackenproof.com/gate-dot-io/gate-dot-io-exchange', archived: false, triaged_by_hackenproof: false},
{id: '/coingecko/coingecko', name: 'CoinGecko', url: 'https://hackenproof.com/coingecko/coingecko',
archived: false, triaged_by_hackenproof: true},
{id: '/p2pb2b/p2pb2b', name: 'P2PB2B', url: 'https://hackenproof.com/p2pb2b/p2pb2b',
archived: false, triaged_by_hackenproof: false},
{id: '/coinsbit/coinsbit', name: 'Coinsbit', url: 'https://hackenproof.com/coinsbit/coinsbit',
archived: false, triaged_by_hackenproof: false},
{id: '/hotbit/hotbit', name: 'Hotbit', url: 'https://hackenproof.com/hotbit/hotbit',
archived: false, triaged_by_hackenproof: true},
{id: '/whitebit/whitebit', name: 'WhiteBIT', url: 'https://hackenproof.com/whitebit/whitebit',
archived: false, triaged_by_hackenproof: false},
{id: '/vechain/vechainthor-vip191', name: 'VeChainThor VIP191',
url: 'https://hackenproof.com/vechain/vechainthor-vip191', archived: true, triaged_by_hackenproof: false}]
[
{
archived: true,
id: '63517622fd18045e8d9b72bc',
name: 'VirtuSwap DEX APP',
slug: 'virtuswap-dex-app-1',
triaged_by_hackenproof: true,
url: 'https://hackenproof.com/programs/virtuswap-dex-app-1'
}
]
)
end

it 'fetches program scopes' do
scopes = File.read('spec/fixtures/hackenproof/scopes.html')
stub_request(:get, %r{/hacken/hackenproof}).with(headers: {host: 'hackenproof.com'})
scopes = File.read('spec/fixtures/hackenproof/scopes.json')
stub_request(:get, %r{/bug-bounty-programs-list/my-program}).with(headers: {host: 'hackenproof.com'})
.to_return(status: 200, body: scopes)
expect(client.program_scopes(url: 'https://hackenproof.com/hacken/hackenproof')).to eq(
targets: {
in_scope: [
{
instruction: 'HackenProof main site',
reward: 'Bounty',
type: 'Web',
target: 'hackenproof.com',
severity: 'Critical'
}
],
out_of_scope: [
{
target: 'blog.hackenproof.com',
type: 'Web',
instruction: 'Our Blog',
severity: 'None',
reward: ''
}
]
expect(client.program_scopes(slug: 'my-program')).to eq(
{
targets: {
in_scope: [
{
instruction: 'Polygon POS - Heimdall',
reward: 'Bounty',
severity: 'Critical',
type: 'Other',
target: 'https://github.com/maticnetwork/heimdall/'
}
],
out_of_scope: []
}
}
)
end
Expand Down
Loading

0 comments on commit 1206830

Please sign in to comment.