Skip to content

fix: remove automatic InsecureSkipVerify=true for HTTPS connections (CWE-295) - #359

Merged
zouyx merged 6 commits into
developfrom
copilot/fix-security-issues
Jul 18, 2026
Merged

fix: remove automatic InsecureSkipVerify=true for HTTPS connections (CWE-295)#359
zouyx merged 6 commits into
developfrom
copilot/fix-security-issues

Conversation

Copilot AI commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

安全漏洞修复 / Security Fix

问题描述 / Problem

protocol/http/request.go 中存在一个严重的安全漏洞:代码通过判断 URL scheme 是否为 https 来决定是否跳过 TLS 证书验证,并无条件地将 InsecureSkipVerify 设为 true。这意味着所有 HTTPS 连接都完全禁用了证书验证,使客户端极易遭受中间人攻击(MITM)。

In protocol/http/request.go there was a critical security vulnerability: whenever the request URL used the https scheme, the code automatically set InsecureSkipVerify: true on the TLS config. This completely disabled TLS certificate verification for every HTTPS connection, exposing all communication to man-in-the-middle (MITM) attacks (CWE-295 – Improper Certificate Validation).

// 修复前 / Before – security hole
if strings.HasPrefix(u.Scheme, "https") {
    insecureSkipVerify = true   // ← always skipped verification!
}

修复内容 / Changes

文件 改动
protocol/http/request.go 保留 url.Parse URL 校验及 HTTPS scheme 自动识别逻辑(向后兼容);当 scheme 为 https 时,从 ConnectConfig.InsecureSkipVerify 读取配置(默认 false,即开启证书验证)而非硬编码为 true;使用精确匹配 u.Scheme == "https" 替代 strings.HasPrefix;修复 retry 循环内 defer res.Body.Close() 资源泄漏;为不安全模式添加独立的单例 Transport
env/request_config.go ConnectConfig 中新增 InsecureSkipVerify bool 字段(默认 false
env/config/config.go AppConfig 中新增 InsecureSkipVerify bool 字段(默认 false,JSON tag insecureSkipVerify
component/remote/abs.go 构建 ConnectConfig 时传递 AppConfig.InsecureSkipVerify
component/remote/async.go 构建 ConnectConfig 时传递 AppConfig.InsecureSkipVerify
component/serverlist/sync.go 构建 ConnectConfig 时传递 AppConfig.InsecureSkipVerify
protocol/http/request_test.go HTTPS 测试显式设置 InsecureSkipVerify: true(自签名测试证书场景)

行为变更 / Behavior Change

  • 默认行为(安全):TLS 证书验证默认启用,与标准 Go net/http 客户端一致。HTTPS scheme 自动识别保留,无需用户额外配置即可连接有效证书的 HTTPS 服务器。
  • 显式禁用(向后兼容):如需连接使用自签名证书的服务器(如内网测试环境),可在 app.properties 中设置 "insecureSkipVerify": true,或在代码中设置 AppConfig.InsecureSkipVerify = true

测试 / Testing

所有现有测试均通过,CodeQL 扫描无告警。

…CWE-295)

- Remove URL-scheme-based logic that unconditionally disabled TLS
  certificate verification for every HTTPS URL
- Add InsecureSkipVerify bool to AppConfig and ConnectConfig as an
  explicit opt-in (defaults to false / secure)
- Propagate the flag through ConnectConfig in abs.go, async.go, sync.go
- Add a second singleton transport for the insecure case so secure and
  insecure connections are isolated
- Fix defer res.Body.Close() inside retry loop (resource leak)
- Update HTTPS unit test to explicitly set InsecureSkipVerify: true

Agent-Logs-Url: https://github.com/apolloconfig/agollo/sessions/64e40f20-b4d3-4bd9-bca1-229ede403e51

Co-authored-by: zouyx <3828072+zouyx@users.noreply.github.com>
@mergify

mergify Bot commented Apr 18, 2026

Copy link
Copy Markdown
Contributor

感谢您提出Pull Request,我会尽快Review。我会在1-2日内进行查看或者回复,如果遇到节假日可能会处理较慢,敬请谅解。

Copilot AI requested a review from zouyx April 18, 2026 15:36
@zouyx
zouyx marked this pull request as ready for review April 18, 2026 15:39
Copilot AI review requested due to automatic review settings April 18, 2026 15:39
@coveralls

coveralls commented Apr 18, 2026

Copy link
Copy Markdown

Coverage Report for CI Build 29652155219

Warning

No base build found for commit eae8218 on develop.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 75.996%

Details

  • Patch coverage: 3 uncovered changes across 1 file (41 of 44 lines covered, 93.18%).

Uncovered Changes

File Changed Covered %
protocol/http/request.go 31 28 90.32%
Total (4 files) 44 41 93.18%

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 1883
Covered Lines: 1431
Line Coverage: 76.0%
Coverage Strength: 4.01 hits per line

💛 - Coveralls

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 addresses a critical TLS security issue (CWE-295) by removing the previous behavior that effectively disabled certificate verification for all HTTPS requests, and replacing it with an explicit opt-in flag (InsecureSkipVerify) passed through configuration.

Changes:

  • Remove scheme-based InsecureSkipVerify=true behavior; instead, read InsecureSkipVerify from env.ConnectConfig and provide a dedicated singleton Transport for insecure mode.
  • Fix response body handling in the retry loop to avoid defer res.Body.Close() accumulating across retries.
  • Add InsecureSkipVerify to ConnectConfig and AppConfig, thread it through remote/serverlist callers, and update HTTPS tests to opt in explicitly.

Reviewed changes

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

Show a summary per file
File Description
protocol/http/request.go Uses config-driven TLS verification behavior; introduces secure/insecure singleton transports; fixes response body close behavior in retries
protocol/http/request_test.go Updates HTTPS test to explicitly opt into insecure TLS for self-signed test server
env/request_config.go Adds ConnectConfig.InsecureSkipVerify flag (default false)
env/config/config.go Adds AppConfig.InsecureSkipVerify with JSON tag for configuration
component/remote/abs.go Passes AppConfig.InsecureSkipVerify into ConnectConfig
component/remote/async.go Passes AppConfig.InsecureSkipVerify into ConnectConfig
component/serverlist/sync.go Passes AppConfig.InsecureSkipVerify into ConnectConfig

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

Comment on lines 60 to 66
func TestHttpsRequestRecovery(t *testing.T) {
time.Sleep(1 * time.Second)
server := runNormalBackupConfigResponseWithHTTPS()
appConfig := getTestAppConfig()
appConfig.IP = server.URL
appConfig.InsecureSkipVerify = true

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

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

This test updates the HTTPS path to explicitly opt into InsecureSkipVerify, but there is no complementary assertion that the default (no opt-in) fails against the self-signed HTTPS server. Adding a negative test case here (same HTTPS server, but without setting InsecureSkipVerify) would lock in the intended security behavior and prevent regressions back to skipping verification by default.

Copilot uses AI. Check for mistakes.
Comment thread protocol/http/request.go
Comment on lines 106 to 114
} else {
client.Timeout = connectTimeout
}
var err error
u, err := url.Parse(requestURL)
if err != nil {
log.Errorf("request Apollo Server url: %q is invalid: %v", requestURL, err)
return nil, err
}
var insecureSkipVerify bool
if strings.HasPrefix(u.Scheme, "https") {
insecureSkipVerify = true
if connectionConfig != nil {
insecureSkipVerify = connectionConfig.InsecureSkipVerify
}
client.Transport = getDefaultTransport(insecureSkipVerify)
retry := 0

Copilot AI Apr 18, 2026

Copy link

Choose a reason for hiding this comment

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

Removing the explicit url.Parse validation means invalid requestURL errors are no longer returned to callers as the original parse error; they now fall through to the generic "generate connect Apollo request fail" path from http.NewRequest. Consider either reintroducing URL validation (returning the parse error) or returning/wrapping the http.NewRequest error so callers can diagnose misconfigured URLs.

Copilot uses AI. Check for mistakes.
Comment thread env/config/config.go Outdated
@nobodyiam

Copy link
Copy Markdown
Member

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@zouyx

zouyx commented Apr 30, 2026

Copy link
Copy Markdown
Member

@copilot review

@stale

stale Bot commented Jun 30, 2026

Copy link
Copy Markdown

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale Bot added the stale label Jun 30, 2026
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@stale stale Bot removed the stale label Jul 6, 2026
Comment thread protocol/http/request.go
Comment on lines -95 to -103
var err error
u, err := url.Parse(requestURL)
if err != nil {
log.Errorf("request Apollo Server url: %q is invalid: %v", requestURL, err)
return nil, err
}
var insecureSkipVerify bool
if strings.HasPrefix(u.Scheme, "https") {
insecureSkipVerify = true

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

这个理解是需要兼容,而不是让用户传入。
这个方法是兼容用户不传入的场景,用于自动识别。
@copilot

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Restored the url.Parse + HTTPS scheme auto-detection in this commit. The code now keeps the original structure for backward compatibility — it auto-identifies HTTPS from the URL scheme — but instead of unconditionally setting InsecureSkipVerify=true, it reads the value from connectionConfig.InsecureSkipVerify (defaults to false, secure):

u, err := url.Parse(requestURL)
if err != nil {
    log.Errorf("request Apollo Server url: %q is invalid: %v", requestURL, err)
    return nil, err
}
var insecureSkipVerify bool
if connectionConfig != nil && strings.HasPrefix(u.Scheme, "https") {
    insecureSkipVerify = connectionConfig.InsecureSkipVerify
}
client.Transport = getDefaultTransport(insecureSkipVerify)

This also restores the URL validation that was previously lost.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

已恢复 url.Parse 和 URL scheme 自动识别逻辑,以保持向后兼容性。当 scheme 为 https 时,InsecureSkipVerify 的值从 connectionConfig 读取(默认为 false,即默认开启证书验证),而不是硬编码为 true。同时将 strings.HasPrefix 替换为精确匹配 u.Scheme == "https",避免误匹配其他 scheme。

Restored url.Parse and URL scheme auto-detection for backward compatibility. When the scheme is https, InsecureSkipVerify is read from connectionConfig (defaults to false / secure) instead of being hardcoded to true. Also changed from strings.HasPrefix to exact equality u.Scheme == "https" for correctness. Commit: fix: use exact scheme equality for HTTPS detection, remove unused strings import

Copilot finished work on behalf of zouyx July 6, 2026 15:34
Copilot AI requested a review from zouyx July 6, 2026 15:34
Copilot finished work on behalf of zouyx July 6, 2026 15:36
@zouyx
zouyx merged commit 5a45b63 into develop Jul 18, 2026
6 checks passed
@nobodyiam
nobodyiam deleted the copilot/fix-security-issues branch July 19, 2026 05:51
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.

5 participants