Skip to content

Instantly share code, notes, and snippets.

@Turkidev
Last active August 16, 2026 07:06
Show Gist options
  • Select an option

  • Save Turkidev/ecf08332458dd688dfbc65c67030fc05 to your computer and use it in GitHub Desktop.

Select an option

Save Turkidev/ecf08332458dd688dfbc65c67030fc05 to your computer and use it in GitHub Desktop.
Huawei AX3 Router – DNS override interceptor (fix hidden DNS fields in web UI)
/**
* Huawei AX3 DNS Interceptor (hardened)
* - Catches Request objects and string URLs
* - Matches by pathname to survive host changes
* - Safely clones & rewrites JSON bodies
*
* Edit these:
*/
const PAGE_IP = location.hostname || "192.168.100.1"; // your router IP (auto-uses current host)
const CUSTOM_DNS1 = "1.1.1.1"; // primary DNS
const CUSTOM_DNS2 = ""; // secondary DNS (optional, "" to leave empty)
// -------- internals ----------
(() => {
const TARGET_PATH = '/api/ntwk/lan_server';
const LOG = true;
const isTarget = (urlLike) => {
try {
const u = new URL(typeof urlLike === 'string' ? urlLike : urlLike.url, window.location.href);
// Match by path (firmware sometimes flips hosts/ports)
return u.pathname === TARGET_PATH;
} catch { return false; }
};
const patchObj = (obj) => {
if (!obj || typeof obj !== 'object') return obj;
obj.data = obj.data || {};
obj.data.DNSServerone = CUSTOM_DNS1;
obj.data.DNSServertwo = CUSTOM_DNS2;
// Firmware expects string "true"/"false"
obj.data.dnsmode = "false";
return obj;
};
// Build a new Request with a modified JSON body, preserving init
const rebuildRequest = async (req) => {
// Clone to read body
const clone = req.clone();
let text = null;
try { text = await clone.text(); } catch { /* no body */ }
if (!text) return req; // GET or empty body
// Only touch JSON bodies
const ct = req.headers.get('content-type') || '';
const maybeJson = ct.includes('application/json') || text.trim().startsWith('{');
if (!maybeJson) return req;
try {
const obj = JSON.parse(text);
const newObj = patchObj(obj);
const newBody = JSON.stringify(newObj);
if (LOG) console.log('[AX3 DNS][fetch] patched', newObj);
// Rebuild headers (Request.headers is a Headers object; we need a fresh one)
const headers = new Headers(req.headers);
if (!headers.has('Content-Type')) headers.set('Content-Type', 'application/json; charset=UTF-8');
return new Request(req, { body: newBody, headers });
} catch {
return req; // not JSON after all
}
};
// ---- fetch interceptor ----
const origFetch = window.fetch.bind(window);
window.fetch = async function(input, init) {
try {
// Normalize to Request object
let req = input instanceof Request ? input : new Request(input, init);
if (req.method.toUpperCase() === 'POST' && isTarget(req)) {
req = await rebuildRequest(req);
return origFetch(req);
}
} catch (e) {
console.warn('[AX3 DNS][fetch] interceptor error', e);
}
// Fallback normal path
return origFetch(input, init);
};
// ---- XHR interceptor ----
const NativeXHR = window.XMLHttpRequest;
function PatchedXHR() {
const xhr = new NativeXHR();
let _method = '', _url = '';
const open = xhr.open;
xhr.open = function(method, url, ...rest) {
_method = method || '';
_url = url || '';
return open.apply(this, [method, url, ...rest]);
};
const send = xhr.send;
xhr.send = function(body) {
try {
if (_method.toUpperCase() === 'POST' && isTarget(_url) && typeof body === 'string') {
// Only patch JSON bodies
if (body.trim().startsWith('{')) {
try {
const obj = JSON.parse(body);
const newObj = patchObj(obj);
if (LOG) console.log('[AX3 DNS][xhr] patched', newObj);
return send.call(this, JSON.stringify(newObj));
} catch { /* ignore parse errs */ }
}
}
} catch (e) {
console.warn('[AX3 DNS][xhr] error', e);
}
return send.call(this, body);
};
return xhr;
}
PatchedXHR.prototype = NativeXHR.prototype;
window.XMLHttpRequest = PatchedXHR;
console.log(`[AX3 DNS] interceptor active for ${TARGET_PATH} on ${PAGE_IP}. Click Save now.`);
})();
@princely

princely commented Oct 7, 2025

Copy link
Copy Markdown

I get the following error when pasting this code on devtools console:

The Content Security Policy (CSP) prevents cross-site scripting attacks by blocking inline execution of scripts and style sheets.

To solve this, move all inline scripts (e.g. onclick=[JS code]) and styles into external files.

⚠️ Allowing inline execution comes at the risk of script injection via injection of HTML script elements. If you absolutely must, you can allow inline script and styles by:

adding unsafe-inline as a source to the CSP header
adding the hash or nonce of the inline script to your CSP header.

@Turkidev

Turkidev commented Oct 7, 2025

Copy link
Copy Markdown
Author

I get the following error when pasting this code on devtools console:

The Content Security Policy (CSP) prevents cross-site scripting attacks by blocking inline execution of scripts and style sheets.

To solve this, move all inline scripts (e.g. onclick=[JS code]) and styles into external files.

⚠️ Allowing inline execution comes at the risk of script injection via injection of HTML script elements. If you absolutely must, you can allow inline script and styles by:

adding unsafe-inline as a source to the CSP header adding the hash or nonce of the inline script to your CSP header.

can you send an image where you ran the code and the type of the router you use?

@Turkidev

Turkidev commented Oct 7, 2025

Copy link
Copy Markdown
Author

[image: image.png]
…
On Tue, Oct 7, 2025 at 9:28 PM Turki Mohammed Alturki < @.> wrote: @.* commented on this gist. ------------------------------ I get the following error when pasting this code on devtools console: The Content Security Policy (CSP) prevents cross-site scripting attacks by blocking inline execution of scripts and style sheets. To solve this, move all inline scripts (e.g. onclick=[JS code]) and styles into external files. ⚠️ Allowing inline execution comes at the risk of script injection via injection of HTML script elements. If you absolutely must, you can allow inline script and styles by: adding unsafe-inline as a source to the CSP header adding the hash or nonce of the inline script to your CSP header. can you send an image where you ran the code and the type of the router you use? — Reply to this email directly, view it on GitHub https://gist.github.com/Turkidev/ecf08332458dd688dfbc65c67030fc05#gistcomment-5791136 or unsubscribe https://github.com/notifications/unsubscribe-auth/AABGAPYIPHV6YAF2ALJIJ7T3WQH6TBFHORZGSZ3HMVZKMY3SMVQXIZNMON2WE2TFMN2F65DZOBS2WR3JON2EG33NNVSW45FGORXXA2LDOOIYFJDUPFYGLJDHNFZXJJLWMFWHKZNJGE2DCMZTGAYDONVKMF2HI4TJMJ2XIZLTSOBKK5TBNR2WLKJRGE2DSNZTG44TLJDOMFWWLKDBMN2G64S7NFSIFJLWMFWHKZNEORZHKZNENZQW2ZN3ORUHEZLBMRPXAYLSORUWG2LQMFXHIX3BMN2GS5TJOR4YFJLWMFWHKZNEM5UXG5FENZQW2ZNLORUHEZLBMRPXI6LQMU . You are receiving this email because you commented on the thread. Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub .

i can't see the image send it via github not email

@princely

princely commented Oct 7, 2025

Copy link
Copy Markdown
image

@Turkidev

Turkidev commented Oct 7, 2025

Copy link
Copy Markdown
Author
image

try and use a different browser
it worked for me using brave and edge

@princely

princely commented Oct 8, 2025

Copy link
Copy Markdown

I tried in Brave. When I paste it and press Enter, it just shows “undefined”, and nothing is written to the console log as expected from the last line:

console.log('Interceptor active for', TARGET, 'on', PAGE_IP, '- now click Save on router UI.');

@Turkidev

Turkidev commented Oct 8, 2025

Copy link
Copy Markdown
Author

I tried in Brave. When I paste it and press Enter, it just shows “undefined”, and nothing is written to the console log as expected from the last line:

console.log('Interceptor active for', TARGET, 'on', PAGE_IP, '- now click Save on router UI.');

fixed the issue
tested it on my local AX3 on latest version it works (they updated there api)

test and let me know

@princely

princely commented Oct 8, 2025 •

Copy link
Copy Markdown

I tried in Brave. When I paste it and press Enter, it just shows “undefined”, and nothing is written to the console log as expected from the last line:
console.log('Interceptor active for', TARGET, 'on', PAGE_IP, '- now click Save on router UI.');

fixed the issue tested it on my local AX3 on latest version it works (they updated there api)

test and let me know

The last console.log still isn’t executed and the console shows “undefined,” but it looks like the changes are being saved on the router. Thank you!

@laopaoer-wallet

Copy link
Copy Markdown

This solution solved my problem. Thank you so much.

@Cognixx

Cognixx commented Feb 3, 2026 •

Copy link
Copy Markdown

Thanks a lot. It's worked on latest firmware version

@carloscslira

Copy link
Copy Markdown

It works on the Huawei AX6 model too. Tried here and worked! Thank you very much!

@dreamhakeem

dreamhakeem commented Apr 5, 2026 •

Copy link
Copy Markdown

Hello. Can you help me? What I need to change in the script for it to work on a Huawei WiFi Mesh? I'm trying to change the dns for my pihole. Thank you. The Huawei model number is WS5800, I'm using Brave.

@Tzomby

Tzomby commented Aug 16, 2026

Copy link
Copy Markdown

Hello, I'm trying to apply it but I just get a line saying "undefined".
I've tried on brave and firefox, but neither worked.
the version of the firmware is 2.0.0.112(C500)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment