Installation and Overview - adam-schaefer-ncc/tracy GitHub Wiki

Extension Setup

Install the Tracy browser extension with Firefox or Chrome using one of the following links:

If you want to run Tracy from an earlier release or a specific commit

Load the extension using the add-on developer options. In order to get the UI working, you will need to build it with npm run build from the root directory of the project. Once that is done, you should be able to sideload the extension using the browser development options. When loading an unpacked extension, load the manifest.json file from the build directory.

Tracy in the Web Application

Tracy will highlight the following <input> element types with the Tracy Owl Logo:

  • strings
  • text
  • url

<textarea> elements are also highlighted. Note that certain types of input element types will not be highlighted, such as "tel" , "password", or "number" because those forms fields are usually not good sources of arbitrary injection points when submitting requests with forms. If there are cases where you'd like to use a tracer string in one of these types of fields, you can manually type the payload into the field and it will be replaced as normal. The highlighting is more of a suggested injection spot.

By clicking on the logo, you will have the option to insert any configured tracer payloads. Here's an example of what that looks like in the Google Gruyere Profile page:

Tracy UI in Google Gruyere

Default Tracer Strings

  • zzXSSzz - When Tracy sees this tracer string, it will insert the literal string zzXSSzz in the text field. Before the form goes out, it will be replaced with a unique XSS polyglot. This can be used to bypass client side validatation without having to intercept and modify the HTTP request with a proxy. This string can also be modified within the web application to fit various format restrictions (e.g. [email protected], http://zzXSSzz.com, zzXSSzz.png). The resulting Tracer Payload will be identical to one generated with a GEN-XSS payload.
  • GEN-XSS - Directly inserts an XSS polyglot with a unique tracer payload. Example: \"'<rltizfdonk>
  • GEN-PLAIN - Directly inserts a tracer payload (no XSS polyglot characters). Example: varqapgxdd
  • zzPLAINzz - Directly inserts a tracer string that can be modified similar to zzXSSzz, but without XSS polyglot characters.

New tracer strings can be created in the Tracy settings page.

Tracer strings that begin with the string "gen", will be generated on-the-fly. This means that when a user clicks GEN-XSS or GEN-PLAIN from the dropdown menu, the corresponding payload will be generated and put into the input field right away. This is different from zzXSSzz and zzPLAINzz. When using these tracer strings, the literal string zzXSSzz and zzPLAINzz will be inserted into the input field and will be replaced after the user submits the form.

As an example, consider signing up for an account using the zzXSSzz payload as the first and last name. After the submit button is clicked, before the form goes out, the strings zzXSSzz will get swapped for their corresponding tracer payloads. Since the swapping happens right before the form goes out, these tracer strings can be really handy if there is client-side JavaScript preventing common XSS characters from being used in a form field. These payloads are also cool because Tracy modifies the behavior of innerHTML, fetch, XMLHTTPRequest, and other types of sources of input from a web application to look for these tracer strings. If one of these tracer strings is found in a call to fetch, for example, the value will be swapped for its respective payload before the actual fetch request is made. This payloads are great for capturing the origins of user-controlled input in JavaScript-heavy application or those that do not make large use of traditional forms.

If you notice there is no input validation on the client side, try the GEN-XSS field to generate a payload on-the-fly. If you want to track where your input is ending up in the application without trying to break out of anything, you can use GEN-PLAIN or zzPLAINzz if you need to bypass client side validation.

Tracy Extension UI

By clicking on the Tracy extension icon in your browser, a tab will open containing the Tracy UI. In the top left, you can see each tracer string and payload as well as the severity, method, URL used to submit the string. By clicking on a payload, you can see the HTTP Request sent to submit the payload, as well as a screenshot showing where the payload was submitted in the web application. Note: if you are a tracking a string that wasn't submitted by a form input, such as a string submitted through a URL parameter or by uploading a list of tracer payloads in the Settings menu, you may not see a screenshot.

In the bottom left, you can see each location that a tracer payload has appeared in the web application -- whether it has been reflected directly or inserted into the DOM. By clicking on an observed output, you can see how your tracer payload is inserted into the HTML of the site.

Here is an example of what the Tracy UI looks like after inserting a few Tracer String Payloads into Google Gruyere:

Tracy UI with Data

Severity Levels

Tracer Payloads are assigned a Severity level on a scale of 0-3. TO DO

  • 0 - Unexploitable - No detected XSS risk
  • 1 - Suspicious - User input within a tag's value. Worth investigation, but likely not an issue.
  • 2 - Probable - User input was rendered in the value of an on-handler inline attribute of an HTML element, such as onclick or onload. An example of this might look like the following: <body onload="alert('loaded\\\"'<rltizfdonk>")></body>.
  • 3 - Exploitable - Tracer payload rendered in the DOM in a vulnerable context, such as an attribute or node name. No user-input should ever be rendered as a attribute name or node name. These will likely look like the following (based on how the browser interprets the broken HTML, they will likely look a little different, but the basic idea is the same: polyglot escaped something and rendered in a location it shouldn't be):
    • <\"'<rltizfdonk></rltizfdonk>
    • <img src='something\&quot;' < rltizfdonk=">"></img>

Tracy Settings

By clicking on the cog in the bottom left of the Tracy UI, you can access the settings menu. Tracy comes with four default string payloads, but you can add new custom payloads. When creating tracer strings and payloads, there are a couple of things to know:

  1. A tracer string simply maps to a tracer payload. When you select a tracer string from the Tracy dropdown, the tracer payload is what shows up in the input field. The tracer payload is also what Tracy remembers for future web application sinks.
  2. When picking a tracer payload, if you use the [[ID]] identifier, Tracy will automatically convert this identifier to a random unique character string that it will remember. You can create tracer payloads without the [[ID]], but I can't imagine them being very useful.
  3. Tracer payloads that start with the word GEN will be payloads that are generated on-the-fly into the page. This means they will be created before any JavaScript validation occurs on the page. If you want a payload that is generated after JavaScript validation (for example, right before the form is submitted or right before a fetch request goes out), simply create a payload that doesn't start with GEN.

You can also import Tracer Payloads This setting allows you to tell Tracy you want it to watch for an arbitrary tracer payload of your choosing. This can be helpful in a number of cases:

  1. A sensitive value is rendered in the DOM (such as an API key) and you want Tracy to watch and alert whenever it is rendered again.
  2. Another teammate is also using Tracy and you want to instruct your version of Tracy to watch for payloads they have inserted. This may assist you in finding data sources that lead to injection sinks across tenant boundaries, such as data leaks between different user tenants or XSS that bleeds into other types of user accounts (such as a low privilege user and an customer service agent portal).
  3. Changing the value of a user-controlled input is too difficult and you'd like to watch that input as is.
⚠️ **GitHub.com Fallback** ⚠️