Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
उपकरण/GitHubGitHub/renio-wow/cve-2026-51416
स्थैतिक विश्लेषणभेद्यता विश्लेषणकोड विश्लेषणवेब सुरक्षा
GitHubrenio-wow/cve-2026-51416

CVE-2026-51416

वीचैट OAuth हैंडलर में एक विशिष्ट CVE का विश्लेषण करता है, जो अनबाउंड HTTP प्रतिक्रिया रीड्स की पहचान करता है जो सेवा अस्वीकृति (denial of service) की ओर ले जाती हैं, साथ ही उपचार मार्गदर्शन के साथ।

रिपॉजिटरी देखें
4 महीने पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

1. सारांश

  • भेद्यता प्रकार: सेवा अस्वीकार / अप्रतिबंधित HTTP प्रतिक्रिया पठन ([CWE-400])
  • चिह्नित स्थान: backend/internal/handler/auth_wechat_oauth.go:1149
  • भेद्यता विवरण: WeChat OAuth टोकन विनिमय प्रक्रिया बफरिंग से पहले कोई अधिकतम आकार सीमा लागू किए बिना संपूर्ण अपस्ट्रीम HTTP प्रतिक्रिया निकाय को मेमोरी में पढ़ने के लिए io.ReadAll(resp.Body) का उपयोग करती है।

2. विश्लेषण

चरण 1: backend/internal/handler/auth_wechat_oauth.go:1124 पर चिह्नित सिंक की जाँच करें

चिह्नित फ़ंक्शन और आसपास के 50 से अधिक पंक्तियों के संदर्भ की समीक्षा की गई। सिंक टोकन विनिमय सहायक exchangeWeChatOAuthCode() है। यह फ़ंक्शन WeChat के लिए GET अनुरोध बनाता है, इसे सादे http.Client का उपयोग करके भेजता है, और फिर के साथ संपूर्ण प्रतिक्रिया निकाय पढ़ता है।

io.ReadAll(resp.Body)
root@kitploit:~
func exchangeWeChatOAuthCode(ctx context.Context, cfg wechatOAuthConfig, code string) (*wechatOAuthTokenResponse, error) {
    endpoint, err := url.Parse(wechatOAuthAccessTokenURL)
    ...
    req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
    ...
    client := &http.Client{Timeout: 30 * time.Second}
    resp, err := client.Do(req)
    ...
    defer func() { _ = resp.Body.Close() }()

    body, err := io.ReadAll(resp.Body)
    if err != nil {
        return nil, fmt.Errorf("read wechat access token response: %w", err)
    }
    if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
        return nil, fmt.Errorf("wechat access token status=%d", resp.StatusCode)
    }
    ...
}

साक्ष्य:

  • backend/internal/handler/auth_wechat_oauth.go:1142 client := &http.Client{Timeout: 30 * time.Second} बनाता है।
  • backend/internal/handler/auth_wechat_oauth.go:1149 body, err := io.ReadAll(resp.Body) निष्पादित करता है।
  • प्रतिक्रिया निकाय को बफर करने से पहले कोई io.LimitReader, कोई ContentLength जाँच, और कोई सहायक फ़ंक्शन कॉल मौजूद नहीं है।

विश्लेषण: यहाँ एकमात्र सुरक्षा समय सीमा है (Timeout: 30 * time.Second), मेमोरी सीमा नहीं। एक दूरस्थ सहकर्मी EOF तक पहुँचने से पहले बड़ी मेमोरी आवंटन को ट्रिगर कर सकता है। फिर उत्पादन मार्गों से इस सिंक की पहुँच का पता लगाया गया।

चरण 2: सार्वजनिक OAuth कॉलबैक मार्ग से मुख्य अनुरोध पथ का पता लगाएं

प्रमाणीकरण मार्ग पंजीकरण और WeChat OAuth हैंडलर की समीक्षा की गई। मार्ग सार्वजनिक /auth समूह के अंतर्गत पंजीकृत है, JWT-संरक्षित समूह के अंतर्गत नहीं। कॉलबैक हैंडलर चिह्नित प्रवाह को लागू करने से पहले उपयोगकर्ता-आपूर्ति किए गए code और state क्वेरी पैरामीटर प्राप्त करता है।

root@kitploit:~
// routes
auth := v1.Group("/auth")
auth.Use(servermiddleware.BackendModeAuthGuard(settingService))
...
auth.GET("/oauth/wechat/start", h.Auth.WeChatOAuthStart)
auth.GET("/oauth/wechat/callback", h.Auth.WeChatOAuthCallback)
root@kitploit:~
// callback handler
func (h *AuthHandler) WeChatOAuthCallback(c *gin.Context) {
    ...
    code := strings.TrimSpace(c.Query("code"))
    state := strings.TrimSpace(c.Query("state"))
    if code == "" || state == "" {
        redirectOAuthError(c, frontendCallback, "missing_params", "missing code/state", "")
        return
    }
    ...
    tokenResp, userInfo, err := fetchWeChatOAuthIdentity(c.Request.Context(), cfg, code)
    if err != nil {
        redirectOAuthError(c, frontendCallback, "provider_error", "wechat_identity_fetch_failed", singleLine(err.Error()))
        return
    }
    ...
}
root@kitploit:~
// start handler
func (h *AuthHandler) WeChatOAuthStart(c *gin.Context) {
    ...
    state, err := oauth.GenerateState()
    ...
    wechatSetCookie(c, wechatOAuthStateCookieName, encodeCookieValue(state), wechatOAuthCookieMaxAgeSec, secureCookie)
    ...
    c.Redirect(http.StatusFound, authURL)
}

साक्ष्य:

  • backend/internal/server/routes/auth.go:27-28 इन मार्गों को सार्वजनिक /auth राउटर समूह में रखता है।
  • backend/internal/server/routes/auth.go:73 auth.GET("/oauth/wechat/start", h.Auth.WeChatOAuthStart) पंजीकृत करता है।
  • backend/internal/server/routes/auth.go:80 auth.GET("/oauth/wechat/callback", h.Auth.WeChatOAuthCallback) पंजीकृत करता है।
  • backend/internal/handler/auth_wechat_oauth.go:160-162 HTTP अनुरोध से code और state पढ़ता है।
  • backend/internal/handler/auth_wechat_oauth.go:206 fetchWeChatOAuthIdentity(c.Request.Context(), cfg, code) को कॉल करता है।
  • backend/internal/handler/auth_wechat_oauth.go:105-147 सामान्य पूर्व-प्रसंस्करण चरण दिखाता है जो एक स्टेट कुकी सेट करता है और ब्राउज़र को OAuth प्रवाह में पुनर्निर्देशित करता है।

विश्लेषण: यह सार्वजनिक GET कॉलबैक से पहुँच योग्य लाइव उत्पादन कोड है। स्टेट कुकी OAuth-CSRF सुरक्षा प्रदान करती है, लेकिन यह टोकन विनिमय के बाद डाउनस्ट्रीम में आने वाले HTTP प्रतिक्रिया के आकार को सीमित नहीं करती है। फिर आंतरिक कॉल श्रृंखला और सिंक के सभी उत्पादन कॉलर का अनुसरण किया गया।

चरण 3: exchangeWeChatOAuthCode() में सभी उत्पादन कॉलर का पता लगाएं

हैंडलर और सहायक फ़ंक्शनों के बीच आंतरिक कॉल श्रृंखला का पता लगाया गया। मुख्य कॉलबैक एक सहायक (fetchWeChatOAuthIdentity) के माध्यम से सिंक तक पहुँचता है, जबकि भुगतान कॉलबैक सीधे उसी सिंक तक पहुँचता है।

root@kitploit:~
func fetchWeChatOAuthIdentity(ctx context.Context, cfg wechatOAuthConfig, code string) (*wechatOAuthTokenResponse, *wechatOAuthUserInfoResponse, error) {
    tokenResp, err := exchangeWeChatOAuthCode(ctx, cfg, code)
    if err != nil {
        return nil, nil, err
    }
    userInfo, err := fetchWeChatUserInfo(ctx, tokenResp)
    ...
}
root@kitploit:~
cfg, err := h.getWeChatOAuthConfig(c.Request.Context(), "mp", c)
...
cfg.redirectURI = h.resolveWeChatPaymentOAuthCallbackURL(c.Request.Context(), c)
tokenResp, err := exchangeWeChatOAuthCode(c.Request.Context(), cfg, code)
if err != nil {
    redirectOAuthError(c, frontendCallback, "token_exchange_failed", "failed to exchange oauth code", err.Error())
    return
}

साक्ष्य:

  • backend/internal/handler/auth_wechat_oauth.go:1112-1117 दिखाता है कि fetchWeChatOAuthIdentity() exchangeWeChatOAuthCode() को कॉल करता है, फिर fetchWeChatUserInfo() को।
  • backend/internal/handler/auth_wechat_oauth.go:206 वह स्थान है जहाँ मुख्य OAuth कॉलबैक fetchWeChatOAuthIdentity() को कॉल करता है।
  • backend/internal/handler/auth_wechat_oauth.go:438 वह स्थान है जहाँ भुगतान OAuth कॉलबैक सीधे exchangeWeChatOAuthCode() को कॉल करता है।

विश्लेषण: चिह्नित सिंक मृत कोड नहीं है। एक परियोजना-व्यापी कॉलर खोज उसी सहायक में दो उत्पादन प्रवेश पथों को हल करती है: मानक WeChat लॉगिन/बाइंड कॉलबैक और WeChat भुगतान कॉलबैक। फिर इस प्रतिक्रिया पथ पर मौजूद किसी भी सैनिटाइज़र, वैलिडेटर, या फ्रेमवर्क-स्तरीय आकार गार्ड की जाँच की गई।

चरण 4: कोडबेस में आकार सीमाओं और मौजूदा सुरक्षा पैटर्न की जाँच करें

प्रतिक्रिया निकाय आकार-सीमित पैटर्न के लिए कोडबेस खोजा गया, और अन्यत्र साझा सहायक की समीक्षा की गई जो पहले से ही सीमित अपस्ट्रीम रीड के लिए उपयोग किया जाता है। वह सहायक io.LimitReader(..., maxBytes+1) का उपयोग करता है और सीमा पार होने पर स्पष्ट रूप से त्रुटि देता है, लेकिन WeChat OAuth कोड इसका उपयोग नहीं करता है।

root@kitploit:~
func readUpstreamResponseBodyLimited(reader io.Reader, maxBytes int64) ([]byte, error) {
    ...
    body, err := io.ReadAll(io.LimitReader(reader, maxBytes+1))
    if err != nil {
        return nil, err
    }
    if int64(len(body)) > maxBytes {
        return nil, fmt.Errorf("%w: limit=%d", ErrUpstreamResponseBodyTooLarge, maxBytes)
    }
    return body, nil
}
root@kitploit:~
// DefaultUpstreamResponseReadMaxBytes is the default read cap for upstream non-streaming response bodies.
const DefaultUpstreamResponseReadMaxBytes int64 = 128 * 1024 * 1024
root@kitploit:~
raw, _ := io.ReadAll(io.LimitReader(resp.Body, 1<<20))
...
raw, _ := io.ReadAll(io.LimitReader(resp.Body, 5<<20))

साक्ष्य:

  • backend/internal/service/upstream_response_limit.go:26-40 io.LimitReader(reader, maxBytes+1) का उपयोग करके readUpstreamResponseBodyLimited() को परिभाषित करता है।
  • backend/internal/service/upstream_response_limit.go:49-61 ReadUpstreamResponseBody() को एक साझा सीमित-रीड रैपर के रूप में परिभाषित करता है।
  • backend/internal/config/config.go:55-58 DefaultUpstreamResponseReadMaxBytes को परिभाषित करता है।
  • backend/internal/service/crs_sync_service.go:1166 अपस्ट्रीम प्रतिक्रिया पढ़ने के लिए io.ReadAll(io.LimitReader(resp.Body, 1<<20)) का उपयोग करता है।
  • backend/internal/service/crs_sync_service.go:1201 एक अन्य अपस्ट्रीम प्रतिक्रिया के लिए io.ReadAll(io.LimitReader(resp.Body, 5<<20)) का उपयोग करता है।
  • इसके विपरीत, backend/internal/handler/auth_wechat_oauth.go:1149 अभी भी एक कच्चा io.ReadAll(resp.Body) उपयोग करता है।

विश्लेषण: परियोजना ने पहले ही अपस्ट्रीम प्रतिक्रिया निकाय आकारों को सीमित करने की आवश्यकता को पहचान लिया है, और तदर्थ और साझा सीमा कार्यान्वयन दोनों उपयोग में हैं। चिह्नित WeChat OAuth पथ इन सुरक्षाओं को पूरी तरह से दरकिनार कर देता है। फिर यह निर्धारित करने के लिए दूरस्थ एंडपॉइंट की जाँच की गई कि क्या यह निश्चित है और क्या यह निष्कर्ष बदलता है।

चरण 5: विश्वास सीमाओं और आसन्न कोड संदर्भ सत्यापित करें

स्थिर परिभाषाओं और आसन्न उपयोगकर्ता-जानकारी प्राप्ति कोड की समीक्षा की गई। OAuth टोकन एंडपॉइंट WeChat के लिए हार्डकोडेड है और उपयोगकर्ता-आपूर्ति नहीं है, लेकिन प्रतिक्रिया निकाय सामग्री अभी भी दूरस्थ नेटवर्क डेटा है और इसे बिना किसी आकार सीमा के पढ़ा जाता है। उपयोगकर्ता-जानकारी अनुरोध के लिए उसी फ़ाइल में एक दूसरा अप्रतिबंधित अपस्ट्रीम रीड मौजूद है।

root@kitploit:~
var (
    wechatOAuthAccessTokenURL = "https://api.weixin.qq.com/sns/oauth2/access_token"
    wechatOAuthUserInfoURL    = "https://api.weixin.qq.com/sns/userinfo"
)
root@kitploit:~
body, err := io.ReadAll(resp.Body)
if err != nil {
    return nil, fmt.Errorf("read wechat userinfo response: %w", err)
}
root@kitploit:~
for _, suffix := range []string{
    "/auth/oauth/linuxdo/callback",
    "/auth/oauth/wechat/callback",
    "/auth/oauth/wechat/payment/callback",
    ...
} {
    if strings.HasSuffix(path, suffix) {
        return true
    }
}

साक्ष्य:

  • backend/internal/handler/auth_wechat_oauth.go:52-54 अपस्ट्रीम एंडपॉइंट्स को WeChat URL पर हार्डकोड करता है।
  • backend/internal/handler/auth_wechat_oauth.go:1197 fetchWeChatUserInfo() के अंदर एक दूसरा अप्रतिबंधित io.ReadAll(resp.Body) करता है।
  • backend/internal/server/middleware/backend_mode_guard.go:38-55 स्पष्ट रूप से /auth/oauth/wechat/callback और /auth/oauth/wechat/payment/callback को अनुमति देता है, भले ही बैकएंड मोड सक्षम हो।

विश्लेषण: निश्चित WeChat होस्टनाम एंडपॉइंट चयन पर हमलावर के नियंत्रण को कम करता है, लेकिन यह कोई प्रतिक्रिया आकार सीमा नहीं जोड़ता है। कमजोरी बनी रहती है क्योंकि एप्लिकेशन बिना किसी ऊपरी सीमा के मनमाने दूरस्थ प्रतिक्रिया बाइट्स को मेमोरी में बफर करता है। यह उत्पादन हैंडलर कोड है, परीक्षण, डेमो, या मृत कोड नहीं।

निर्णय पथ

  • Q1: क्या कोड दूरस्थ रूप से आपूर्ति किए गए डेटा का अप्रतिबंधित पठन करता है? → हाँ। exchangeWeChatOAuthCode() एक आउटबाउंड HTTP अनुरोध जारी करता है और फिर backend/internal/handler/auth_wechat_oauth.go:1142-1149 पर बिना किसी आकार गार्ड के io.ReadAll(resp.Body) को कॉल करता है।
  • Q2: क्या सिंक वास्तविक उत्पादन अनुरोध पथ से पहुँच योग्य है? → हाँ। backend/internal/server/routes/auth.go:73 और backend/internal/server/routes/auth.go:80 सार्वजनिक WeChat प्रारंभ/कॉलबैक मार्गों को पंजीकृत करते हैं, और backend/internal/handler/auth_wechat_oauth.go:206 कॉलबैक प्रवाह को fetchWeChatOAuthIdentity() के माध्यम से मार्ग देता है।
  • Q3: क्या पठन से पहले अधिकतम प्रतिक्रिया निकाय आकार लागू करने वाले कोई सैनिटाइज़र, वैलिडेटर, या फ्रेमवर्क/सहायक फ़ंक्शन हैं? → नहीं। साझा सीमा सहायक backend/internal/service/upstream_response_limit.go:26-40 पर मौजूद है और अन्य सेवाएँ backend/internal/service/crs_sync_service.go:1166 और backend/internal/service/crs_sync_service.go:1201 पर io.LimitReader का उपयोग करती हैं, लेकिन चिह्नित फ़ंक्शन इनमें से किसी का उपयोग नहीं करता है।
  • Q4: क्या कोड मृत, केवल-परीक्षण, या अन्यथा उत्पादन से बाहर है? → नहीं। कोड उत्पादन हैंडलर फ़ाइल backend/internal/handler/auth_wechat_oauth.go में रहता है, backend/internal/server/routes/auth.go:73-82 पर पंजीकृत है, और बैकएंड-मोड मिडलवेयर अभी भी backend/internal/server/middleware/backend_mode_guard.go:38-55 पर कॉलबैक पथों की अनुमति देता है।
  • → सत्य सकारात्मक

3. निष्कर्ष

सत्य भेद्यता

मुख्य साक्ष्य:

  • backend/internal/handler/auth_wechat_oauth.go:1149 केवल एक टाइमआउट सेट करने के बाद संपूर्ण अपस्ट्रीम टोकन प्रतिक्रिया पढ़ने के लिए body, err := io.ReadAll(resp.Body) का उपयोग करता है — कोई आकार सीमा नहीं।
  • backend/internal/server/routes/auth.go:73-82 /oauth/wechat/callback और /oauth/wechat/payment/callback को उजागर करता है, और दोनों मार्ग backend/internal/handler/auth_wechat_oauth.go:206 और backend/internal/handler/auth_wechat_oauth.go:438 के माध्यम से चिह्नित सहायक तक पहुँचते हैं।
  • backend/internal/service/upstream_response_limit.go:26-40 और backend/internal/service/crs_sync_service.go:1166 दिखाते हैं कि कोडबेस पहले से ही सीमित अपस्ट्रीम रीड के लिए io.LimitReader का उपयोग करता है — WeChat OAuth कोड बस ऐसा नहीं करता है।

4. उपचार

  • WeChat टोकन प्रतिक्रिया को बफर करने से पहले एक स्पष्ट अधिकतम प्रतिक्रिया निकाय आकार जोड़ें — उदाहरण के लिए, resp.Body को io.LimitReader(..., maxBytes+1) के साथ लपेटें और सीमा से अधिक निकायों को अस्वीकार करें।
  • backend/internal/handler/auth_wechat_oauth.go:1197 पर आसन्न उपयोगकर्ता-जानकारी रीड पर समान सुधार लागू करें, जिसमें समान अप्रतिबंधित पैटर्न है।
  • backend/internal/service/upstream_response_limit.go:26-40 से मौजूदा सीमित-रीड पैटर्न का पुन: उपयोग करना पसंद करें ताकि OAuth प्रवाह शेष कोडबेस के अपस्ट्रीम प्रतिक्रियाओं को संभालने के तरीके के अनुरूप हो।
  • सुधार के बाद, दोनों उत्पादन कॉल पथों को फिर से सत्यापित करें: मुख्य OAuth कॉलबैक (backend/internal/handler/auth_wechat_oauth.go:206) और भुगतान कॉलबैक (backend/internal/handler/auth_wechat_oauth.go:438)।
टूल डाउनलोड करें