HackerOne · Report #858894
Potential stored Cross-Site Scripting vulnerability in Support Backend
How it was found
HackerOne maintains an internal Support Backend system for employees. On the internal user profiles for hackers, a small overview is shown that lists the skills the user tagged their penetration tester profile with. Although the skills are currently managed by HackerOne and a user can only pick skills from a list, an XSS payload can be injected in the skill name to execute JavaScript in the backend system. In case we would allow penetration testers to enter their own skills in a free-form text format, it could lead to a stored Cross-Site Scripting vulnerability that is exploited by people outside of HackerOne.
Proof of concept
To reproduce, make sure your local environment is set up correctly by running the following code:
Skill.create! name: '<script>alert(/XSS/);</script>'
User.find_by!(username: 'hacker').update! h1_pentester: true
Next, authenticate as the hacker user and enable the pentester-profile feature. Go to http://localhost:8080/settings/pentests and create a penetration tester profile with the skill that was created earlier. When the profile is created successfully, sign in to the Support Backend at http://localhost:8080/support and navigate to http://localhost:8080/support/users/hacker. The XSS payload injected in the skill name will be executed.
████
Root cause
The following code leads to two Cross-Site Scripting vulnerabilities:
lib/support/app/controllers/support/tables/columns/pentester_profile_skills.rb
def render(record)
return unless record.pentester_profile.present?
skill_names = record.pentester_profile.skills.map(&:name)
content = "<span
data-toggle='tooltip'
data-placement='top'
style='cursor: pointer; font-weight: bold'
title='#{skill_names.join("\n")}'>
#{skill_names.join(', ')}
</span>"
content.html_safe
end
Due to the lack of sanitization of the skill name, an attacker can append additional HTML attributes and elements, including elements and attributes that execute JavaScript. The code title='#{skill_names.join("\n")}'> can be exploited using skill name 'onclick='alert(/XSS/);. The code #{skill_names.join(', ')} can be exploited using <script>alert(/XSS/);</script>.
Impact
An attacker could use this in the future to execute arbitrary JavaScript in the Support Backend. Please note that in the production environment, inline execution of JavaScript is not allowed, significantly reducing the exploitability of these vulnerabilities.