Skip to content

Commit 4820dc4

Browse files
committed
feat: implement client fingerprinting to camouflage API requests with Antigravity Electron headers.
1 parent 04b7977 commit 4820dc4

File tree

4 files changed

+378
-47
lines changed

4 files changed

+378
-47
lines changed

src/auth/mod.rs

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -104,28 +104,21 @@ impl HttpClient {
104104
content_type: &str,
105105
body: &[u8],
106106
) -> Result<Vec<u8>, String> {
107-
let os = std::env::consts::OS;
108-
let arch = std::env::consts::ARCH;
109-
let user_agent = format!(
110-
"antigravity/{} {}/{}",
111-
crate::cloudcode::request::UPSTREAM_VERSION,
112-
os,
113-
arch
114-
);
115-
116107
let client_metadata = r#"{"ideType":"IDE_UNSPECIFIED","platform":"PLATFORM_UNSPECIFIED","pluginType":"GEMINI"}"#;
117108

118-
let req = Request::builder()
109+
let mut req = Request::builder()
119110
.method("POST")
120111
.uri(url)
121112
.header("Authorization", format!("Bearer {}", token))
122113
.header("Content-Type", content_type)
123-
.header("User-Agent", user_agent)
124-
.header(
125-
"X-Goog-Api-Client",
126-
"google-cloud-sdk vscode_cloudshelleditor/0.1",
127-
)
128-
.header("Client-Metadata", client_metadata)
114+
.header("Client-Metadata", client_metadata);
115+
116+
// Inject full identity camouflage headers
117+
for (name, value) in crate::fingerprint::build_fingerprint_headers() {
118+
req = req.header(name.as_ref(), value.as_ref());
119+
}
120+
121+
let req = req
129122
.body(Full::new(Bytes::from(body.to_vec())))
130123
.map_err(|e| e.to_string())?;
131124

@@ -154,28 +147,19 @@ impl HttpClient {
154147
body: &[u8],
155148
headers: &[(&str, &str)],
156149
) -> Result<Vec<u8>, String> {
157-
let os = std::env::consts::OS;
158-
let arch = std::env::consts::ARCH;
159-
let user_agent = format!(
160-
"antigravity/{} {}/{}",
161-
crate::cloudcode::request::UPSTREAM_VERSION,
162-
os,
163-
arch
164-
);
165-
166150
let client_metadata = r#"{"ideType":"IDE_UNSPECIFIED","platform":"PLATFORM_UNSPECIFIED","pluginType":"GEMINI"}"#;
167151

168152
let mut req = Request::builder()
169153
.method("POST")
170154
.uri(url)
171155
.header("Content-Type", content_type)
172-
.header("User-Agent", user_agent)
173-
.header(
174-
"X-Goog-Api-Client",
175-
"google-cloud-sdk vscode_cloudshelleditor/0.1",
176-
)
177156
.header("Client-Metadata", client_metadata);
178157

158+
// Inject full identity camouflage headers
159+
for (name, value) in crate::fingerprint::build_fingerprint_headers() {
160+
req = req.header(name.as_ref(), value.as_ref());
161+
}
162+
179163
for (name, value) in headers {
180164
req = req.header(*name, *value);
181165
}

src/cloudcode/request.rs

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,12 @@ static SYSTEM_INSTRUCTION_IGNORE: LazyLock<String> = LazyLock::new(|| {
1818
)
1919
});
2020

21-
/// The upstream Antigravity client version to impersonate.
22-
/// This must be kept up to date with the latest Antigravity release
23-
/// to avoid Google's version gate ("This version of Antigravity is no longer supported").
24-
pub const UPSTREAM_VERSION: &str = "1.16.5";
25-
26-
static USER_AGENT: LazyLock<String> = LazyLock::new(|| {
27-
let os = std::env::consts::OS;
28-
let arch = std::env::consts::ARCH;
29-
format!("antigravity/{} {}/{}", UPSTREAM_VERSION, os, arch)
30-
});
31-
3221
pub fn build_headers(
3322
access_token: &str,
3423
model: &str,
3524
streaming: bool,
3625
) -> Vec<(Cow<'static, str>, Cow<'static, str>)> {
37-
let mut headers = Vec::with_capacity(7);
26+
let mut headers = Vec::with_capacity(10);
3827
headers.push((
3928
Cow::Borrowed("Authorization"),
4029
Cow::Owned(format!("Bearer {}", access_token)),
@@ -43,11 +32,12 @@ pub fn build_headers(
4332
Cow::Borrowed("Content-Type"),
4433
Cow::Borrowed("application/json"),
4534
));
46-
headers.push((Cow::Borrowed("User-Agent"), Cow::Owned(USER_AGENT.clone())));
47-
headers.push((
48-
Cow::Borrowed("X-Goog-Api-Client"),
49-
Cow::Borrowed("google-cloud-sdk vscode_cloudshelleditor/0.1"),
50-
));
35+
36+
// Full identity camouflage headers from the fingerprint module
37+
for (name, value) in crate::fingerprint::build_fingerprint_headers() {
38+
headers.push((name, value));
39+
}
40+
5141
headers.push((
5242
Cow::Borrowed("Client-Metadata"),
5343
Cow::Borrowed(r#"{"ideType":"IDE_UNSPECIFIED","platform":"PLATFORM_UNSPECIFIED","pluginType":"GEMINI"}"#),

0 commit comments

Comments
 (0)