Create your own
Lesson illustration

Decoding URL, HTML, and Base64 with Burp Decoder

Welcome back. In the last lesson, you used Burp Repeater to turn a captured request into a controlled test case: establish a baseline, change one thing, and compare the live response. Before modifying an input, though, you need to be able to read its representation correctly.

Web applications routinely encode data so it can travel safely inside URLs, HTML, cookies, and structured values. This lesson focuses on using Burp Decoder to transform three forms you will see constantly in web assessments:

  • URL (percent) encoding
  • HTML entity encoding
  • Base64 encoding

The goal is not to treat encoded data as inherently suspicious. It is to identify what representation you are looking at, decode it carefully, and re-encode it correctly when needed—without accidentally changing the surrounding request structure.


Encoding is representation, not protection

An encoding changes how data is represented so it fits a particular format or transport context. It is normally reversible.

For example, a URL has characters with structural meaning:

  • ? begins a query string.
  • & separates parameters.
  • = separates a parameter name from its value.
  • # introduces a fragment.
  • % begins a percent-encoded byte.

If a value itself contains one of those characters, it may need an encoded representation so the server or browser does not mistake it for URL syntax.

This is different from:

  • Encryption, which requires a key to recover plaintext.
  • Hashing, which is designed to be one-way.
  • Encoding, which is reversible and usually intended to be decoded by an ordinary recipient.

Base64, for example, does not protect a secret. If a session-related value, API key, or user data appears to be Base64, decoding it may make it readable—but that does not mean you have broken cryptography.

Before using Burp, build a small recognition habit:

You seeLikely representationExample
Repeated % followed by two hexadecimal charactersURL / percent encodingred%20shoes%26socks
&name; or &#number; sequencesHTML entity encoding<section>
Mostly letters, digits, +, /, and sometimes trailing =Standard Base64SGVsbG8sIEJ1cnAh
A data: prefix followed by ;base64,A data URL containing Base64 contentdata:image/png;base64,...

A recognizable appearance is only a clue. Confirm it by decoding a selected value, inspecting the result, and preserving the original representation.

Percent-encoding - Glossary | MDN

Read MDN’s concise explanation of percent encoding. It provides the URL grammar context that makes Decoder results meaningful rather than mechanical.

In the opening “Percent-encoding” definition, read from the definition. Then inspect the character table immediately below it, especially the entries for &, =, %, and space. Finish with the note on spaces, which explains why a space can appear as either %20 or + depending on context.


URL encoding: preserve the structure, transform the value

Percent encoding substitutes a character with a percent sign followed by its hexadecimal byte value. For example:

CharacterCommon encoded form
Space%20 or + in form-style encoding
&%26
=%3D
/%2F
%%25

Consider this query parameter value:

red%20shoes%26socks

After URL decoding, it becomes:

red shoes&socks

The ampersand is now visible as data. If you placed that decoded text directly into a query string, however, the web server could interpret it as the start of a new parameter. So this matters:

GET /search?q=red%20shoes%26socks HTTP/1.1

Here, the application should receive one parameter named q whose value is red shoes&socks.

By contrast:

GET /search?q=red shoes&socks HTTP/1.1

may be parsed as two parameters:

  • q with a value of red shoes
  • socks with an empty value

That is why you should usually send only the parameter value to Decoder, rather than decoding an entire URL or request indiscriminately.

The special case of +

In an application/x-www-form-urlencoded body or query convention, a plus sign often represents a space:

first+last

may decode to:

first last

But a literal plus sign should generally be represented as %2B. Context matters. Do not assume every + in every URL-like string means a space; inspect where the value is used.

Multiple URL-encoding layers

You may also encounter a value such as:

email%3Dalice%2540example.test

Decode it once:

email=alice%40example.test

Decode it a second time:

email=alice@example.test

The %25 sequence is the encoded form of %, so the first decoding exposes another encoded sequence. Burp Decoder is useful here because each operation appears in a separate layer; you can see exactly how far you have decoded instead of losing the original value.

Do not assume that more decoding is always correct. Stop when the output makes sense in its actual context, and preserve the full transformation chain.


HTML encoding: make markup characters literal

HTML entity encoding represents characters that would otherwise be interpreted as part of HTML markup. Common examples include:

Literal characterHTML entity
<&lt;
>&gt;
&&amp;
"&quot;
'&#39;

For instance:

Welcome &lt;b&gt;visitor&lt;/b&gt;

HTML-decodes to:

Welcome <b>visitor</b>

Decoder is not deciding whether that resulting text is safe or dangerous. It is only showing you what representation it contains. Later, when testing output handling, you will need to identify where an application places controlled data: ordinary HTML text, an attribute, a script, or a URL. For now, the operational skill is simpler: recognize HTML entities, decode them accurately, and avoid confusing them with URL encodings.

A value can contain both forms. For example:

Welcome%20%26lt%3Bb%26gt%3B

has two layers:

  1. URL decoding produces Welcome &lt;b&gt;.
  2. HTML decoding produces Welcome <b>.

If you needed to return modified text to the original representation, reverse the operations in reverse order:

  1. HTML-encode the edited text.
  2. URL-encode the HTML-encoded result.

This preserves the application’s expected format.


Base64: readable transport for text or binary data

Base64 represents arbitrary bytes using letters, digits, +, /, and sometimes = padding. It is often used when an application needs to embed binary data in text-oriented formats such as JSON, HTML, or a cookie value.

For example:

SGVsbG8sIEJ1cnAh

Base64-decodes to:

Hello, Burp!

A decoded Base64 value may be:

  • readable text;
  • JSON or XML;
  • compressed data;
  • an image, document, or other binary file;
  • structured application data.

If Decoder produces unreadable symbols in Text view, switch to Hex view. A binary result is not an error; it may simply not be text.

Base64 comes in variants. Standard Base64 commonly uses +, /, and = padding. URL-safe Base64 often uses - and _, and padding may be omitted. Recognize the possibility, but do not force a decoding operation if the result does not fit the surrounding application format.

The screenshot shows an HTML `<img>` element whose `src` begins with `data:image/png;base64,`; the prefix identifies a data URL and image type, while the long value after the comma is Base64-encoded image data.

A data URL is a practical example of why selecting the right portion matters:

data:text/plain;base64,SGVsbG8sIEJ1cnAh

Only this portion is Base64:

SGVsbG8sIEJ1cnAh

The preceding text is metadata: it tells the browser that the value is a data URL, gives the media type, and declares Base64 encoding. If you send the whole data URL to a Base64 decoder, the transformation will not represent what you intend.

The presence of a long Base64 string is not evidence of malicious activity. It may be an ordinary embedded icon, uploaded file, client-side state value, or application response. A tester’s task is to identify what it represents and whether the application handles it safely—not to infer intent from its encoding alone.


Burp Decoder: a local transformation workspace

Burp Decoder lets you move from “this looks encoded” to “this is the decoded content, and here is the exact operation that produced it.” It operates locally in Burp; decoding a value does not send a new request to the target.

The safest basic workflow is:

  1. In HTTP history or Repeater, select only the value you want to inspect.
  2. Right-click the selection and choose Send to Decoder.
  3. Open the Decoder tab.
  4. Apply the specific operation: Decode as, Encode as, or, cautiously, Smart decode.
  5. Inspect the new output panel.
  6. If necessary, apply another transformation layer.
  7. Keep the original panel intact so you can trace every change.

Burp Decoder - PortSwigger

Read PortSwigger’s official Decoder documentation before the guided practice. Focus on selective transformations, layered output panels, and the limits of automatic decoding.

In “Carrying out transformations,” begin with Decoder’s purpose. Then read the send-and-transform workflow, including the note that you should select a portion of a message before sending it. In “Operations,” read how Smart decode works, then continue through the function list. Finally, read the note in the following section: its warning about mistakes.

Smart decode is a starting point, not proof

Smart decode asks Burp to recognize likely formats and apply multiple decoding layers automatically. It can be a useful first look at an unfamiliar value, especially if it contains obvious nested percent encodings or HTML entities.

But it is heuristic. A string may happen to resemble Base64 or another known representation without actually being intended as one. Use Smart decode to generate hypotheses, then verify:

  • Did each transformation make sense for the value’s context?
  • Is the resulting text coherent?
  • Does the number of layers match what you observed in the original request or response?
  • Can you explain and reproduce the chain manually?

For precise testing, explicit operations are usually better. You can state exactly that you URL-decoded once, edited a value, then URL-encoded it again.

Burpsuite Basics (FREE Community Edition)

Watch the Decoder portion of John Hammond’s “Burpsuite Basics (FREE Community Edition)” for a quick visual tour of stacked transformation panels and the Base64 option. The surrounding video discusses future injection topics; here, focus only on the Decoder interface and representation changes.

Watch Decoder layers. Notice that each encoding operation creates another visible layer and that operations can be stacked or removed. Do not reproduce or send the injection-style example shown in the broader video; this lesson is limited to local decoding and encoding practice.


Guided practice: transform three benign values

Set aside about 20 minutes for this sequence. You can type or paste these values directly into Decoder, so no live target interaction is needed.

1. URL-decoding and re-encoding

In Decoder, paste:

red%20shoes%26socks

Apply Decode as > URL. Confirm that the output becomes:

red shoes&socks

Now apply Encode as > URL to the decoded panel. The result should restore a URL-safe representation. Depending on context and tool behavior, visually check that the space and ampersand are encoded appropriately; do not rely on memorizing one exact rendered form.

Record a small transformation trace:

Original: red%20shoes%26socks
Operation: URL decode
Result: red shoes&socks
Interpretation: ampersand is part of the value, not a query-string separator

2. Decode nested URL and HTML representations

Paste this value into a fresh Decoder panel:

Welcome%20%26lt%3Bb%26gt%3B

Apply these operations one at a time:

  1. Decode as > URL
  2. Decode as > HTML

You should be able to see a separate panel for each representation:

Original: Welcome%20%26lt%3Bb%26gt%3B
After URL decode: Welcome &lt;b&gt;
After HTML decode: Welcome <b>

Do not edit yet. First, use the panels to understand the order. Then, if you want to test reversibility, apply Encode as > HTML followed by Encode as > URL. This is the correct reverse order for returning to the outer representation.

3. Decode Base64 text and a data URL payload

Paste:

SGVsbG8sIEJ1cnAh

Apply Decode as > Base64. Verify that the decoded text is:

Hello, Burp!

Next, paste the full data URL:

data:text/plain;base64,SGVsbG8sIEJ1cnAh

This time, select only the text after the comma before sending it to Decoder or applying the Base64 operation. The prefix is not Base64 data; it is part of the data URL syntax.

A disciplined habit for real requests

When you encounter encoded content in an authorized lab request or response:

  • Preserve the original value.
  • Note the request location: query parameter, body field, cookie, header, or response element.
  • Decode only the relevant selection.
  • Record each transformation in order.
  • If you make an edit, re-encode in reverse order.
  • Compare the final encoded representation with the original before using it in Repeater.

Avoid decoding and re-encoding an entire request just because one parameter looks encoded. That can alter delimiters, headers, or other structural elements that were never part of your test.


Common mistakes to avoid

Decoding too much

A whole URL contains both data and syntax. If you decode the entire URL, characters such as & and = may stop being distinguishable from the delimiters that structure the query string. Select the parameter value whenever possible.

Assuming Base64 means secrecy

Base64 is often used for convenience, not confidentiality. Decoding it is normal analysis; it is not decryption. Conversely, a readable Base64 result is not automatically a security issue.

Losing the original value

If you overwrite a value in Repeater before you know its original encoding and layers, it becomes hard to reproduce your work. Decoder’s panel history helps preserve the chain. Keep the source request available as well.

Treating Smart decode as authoritative

Smart decode is useful, but it can misidentify formats. Inspect each layer and prefer explicit operations when documenting a test.

Editing a decoded value but not restoring its representation

If the server expects URL-encoded, HTML-encoded, or Base64 content, sending raw edited text may change the request format rather than test the application’s behavior. Decode, make one controlled edit when appropriate, then encode back to the expected outer format.


Key takeaways

Burp Decoder is your workspace for interpreting and rebuilding encoded values accurately.

  • URL encoding uses percent sequences such as %26 for &; query-string structure makes selective decoding important.
  • HTML encoding uses entities such as &lt; and &amp; to represent markup-significant characters.
  • Base64 is reversible representation for text or binary data, not encryption.
  • Select the smallest relevant value before sending it to Decoder.
  • Decoder creates visible transformation layers, which makes nested encodings easier to inspect and reverse.
  • Use Smart decode as a cautious first pass, then verify each layer yourself.
  • When returning edited content to a request, re-apply encodings in the reverse order from decoding.

Next, you will turn a meaningful request-response pair into a concise, reproducible evidence note: enough detail for another tester to verify an observation without copying unnecessary sensitive data.

Can't find a good explanation? Sign up and we'll make it for you

Sign up