Files
MasterHttpRelayVPN-RUST/docs/changelog/v1.9.6.md
T
therealaleph cbb08468bc fix: v1.9.6 — Code.gs/CodeFull.gs hardening, goog.script.init unwrap, README rewrite
Server-side (Apps Script) fixes — users replace their Code.gs with assets/apps_script/Code.gs (or CodeFull.gs for full mode) and Manage deployments → ✏️ → New version → Deploy:
- Removed duplicate doGet in Code.gs (HtmlService one was overriding ContentService one due to JS hoisting → every GET to /exec returned a goog.script.init iframe instead of the placeholder HTML)
- CodeFull.gs doGet switched from HtmlService to ContentService (same reason)
- SKIP_HEADERS now strips X-Forwarded-* / Forwarded / Via family — second line of defense to v1.2.9's client-side stripping (#104), in case a misconfigured upstream proxy adds these
- _doBatch fallback when UrlFetchApp.fetchAll() throws as a whole — per-item fetch on safe methods so one bad URL no longer poisons the entire batch (port from masterking32@3094288)

Client-side (Rust) defense-in-depth:
- parse_relay_json now unwraps goog.script.init("...userHtml...") if any deployment returns the iframe-wrapped form (legacy Code.gs, or a redirect that GETs doGet). New extract_apps_script_user_html + decode_js_string_escapes helpers. Tested against a real deployment's doGet response.

Docs:
- README rewritten as short bilingual landing page (English + Persian RTL) targeting normal users; advanced reference moved to docs/guide.md + docs/guide.fa.md.

Tests: 3 new regression tests. 176 lib + 33 tunnel-node tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 19:00:32 +03:00

6.2 KiB

• Code.gs / CodeFull.gs hardening + باگ‌فیکس (هیچ تغییری در کانفیگ کاربر لازم نیست — فقط Code.gs خودتان را با assets/apps_script/Code.gs (یا CodeFull.gs برای حالت full) جایگزین کنید + در Apps Script editor: Manage deployments → ✏️ → Version: New version → Deploy. Deployment ID همان قبلی می‌ماند):

  • Code.gs doGet تکراری حذف شد: نسخه‌ای که با HtmlService.createHtmlOutput تعریف شده بود به‌خاطر hoisting جاوااسکریپت روی نسخهٔ صحیح ContentService overwrite می‌کرد. در نتیجه هر GET به URL deployment پاسخ سندباکس goog.script.init iframe برمی‌گرداند به‌جای HTML پلیس‌هولدر ساده. این برای ترافیک معمولی POST تأثیری نداشت ولی در زنجیرهٔ redirect که با GET پی می‌گیریم می‌توانست باگ ظاهر شود.
  • CodeFull.gs doGet به ContentService تغییر کرد (قبلاً HtmlService بود) — به همان دلیل بالا.
  • هدرهای IP-leak در SKIP_HEADERS اضافه شد (X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Proto, X-Forwarded-Port, X-Real-IP, Forwarded, Via) — در صورت misconfigured بودن یک پروکسی upstream سمت کاربر، IP واقعی کاربر دیگر در leg دوم سرور به مقصد نشت نمی‌کند. لایهٔ دفاع دوم به stripping سمت کلاینت v1.2.9 (#104).
  • _doBatch دارای fallback شد: اگر UrlFetchApp.fetchAll() به‌عنوان یک کل throw کند (مثلاً یک URL بد همه را poison کند)، حالا برای متدهای امن (GET / HEAD / OPTIONS) per-item fetch می‌کند به‌جای صفر کردن کل پاسخ batch. port از masterking32/MasterHttpRelayVPN@3094288. • parse_relay_json (سمت Rust): unwrapper برای goog.script.init("...userHtml...") اضافه شد — اگر هر deployment‌ای پاسخ HtmlService-wrapped برگرداند (legacy Code.gs قبل از v1.9.6، یا redirect که doGet را GET بزند)، client حالا JSON داخلی را استخراج می‌کند به‌جای key must be a string at line 2 column 1 fail کردن. در مقابل پاسخ doGet واقعی deployment کاربر تست شده — UTF-8 با \xNN byte-escape را درست decode می‌کند. • README بازنویسی شد: نسخهٔ کوتاه دوزبانه (انگلیسی + فارسی RTL) برای کاربر معمولی + راهنمای کامل پیشرفته در docs/guide.md و docs/guide.fa.md. جدا کردن "راه‌اندازی ۵ دقیقه‌ای" از "همهٔ گزینه‌ها و troubleshooting" راهنما را خیلی قابل‌فهم‌تر کرد، خصوصاً برای کاربرانی که می‌خواهند فقط شروع کنند. • تست: ۳ regression test جدید برای extract_apps_script_user_html + decode_js_string_escapes + parse_relay_json end-to-end. ۱۷۶ lib test + ۳۳ tunnel-node test همه pass.

• Code.gs / CodeFull.gs hardening + bug fixes (no client config change needed — just replace your own Code.gs with assets/apps_script/Code.gs (or CodeFull.gs for full mode) and in the Apps Script editor: Manage deployments → ✏️ → Version: New version → Deploy. Your Deployment ID stays the same):

  • Removed duplicate doGet in Code.gs: a second copy declared with HtmlService.createHtmlOutput was silently overriding the correct ContentService one due to JS function hoisting. Result: every GET to the deployment URL was returning the goog.script.init sandbox iframe instead of the simple placeholder HTML. Did not affect normal POST traffic, but could surface during redirect chains we GET-follow.
  • CodeFull.gs doGet switched to ContentService (was HtmlService) — same reason as above.
  • Added IP-leak headers to SKIP_HEADERS (X-Forwarded-For, X-Forwarded-Host, X-Forwarded-Proto, X-Forwarded-Port, X-Real-IP, Forwarded, Via) — if a misconfigured upstream proxy on the user side adds these, the user's real IP no longer leaks to the destination on the server-side leg. Second line of defense to v1.2.9's client-side stripping (#104).
  • _doBatch got a fallback path: if UrlFetchApp.fetchAll() throws as a whole (e.g. one bad URL poisons the batch), it now per-item-fetches safe methods (GET / HEAD / OPTIONS) instead of zeroing the entire batch's responses. Ported from masterking32/MasterHttpRelayVPN@3094288. • parse_relay_json (Rust client): added unwrapper for goog.script.init("...userHtml...") iframe — if any deployment ever returns an HtmlService-wrapped response (legacy Code.gs prior to v1.9.6, or a redirect that GET-hits doGet), the client now extracts the inner JSON instead of failing with key must be a string at line 2 column 1. Tested against a real user deployment's actual doGet output — correctly decodes UTF-8 with \xNN byte-escapes. • Rewrote the README: short bilingual landing page (English + Persian RTL) for normal users, with the full advanced reference moved to docs/guide.md and docs/guide.fa.md. Splitting "5-minute quick start" from "every option + troubleshooting" makes the docs much more approachable, especially for users who just want to get running. • Tests: 3 new regression tests for extract_apps_script_user_html + decode_js_string_escapes + parse_relay_json end-to-end. 176 lib tests + 33 tunnel-node tests all passing.