Skip to content

Commit a1e88c8

Browse files
Added request masking
1 parent 78ef509 commit a1e88c8

19 files changed

Lines changed: 115 additions & 77 deletions

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# GDIntercept Changelog
22

3+
## v0.8.7 Masking
4+
5+
- Add request masking to hide telemetry info
6+
37
## v0.8.6 Yes.
48

59
- We do a little trolling

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ else()
1010
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")
1111
endif()
1212

13-
project(GDIntercept VERSION 0.8.6)
13+
project(GDIntercept VERSION 0.8.7)
1414

1515
file(GLOB_RECURSE SOURCES "src/*.cpp")
1616
add_library(${PROJECT_NAME} SHARED ${SOURCES})

TODO

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ Alpha 6 Todo:
6262
✔ @high Add scroll based on cursor position @done(26-02-19 15:43)
6363
✔ @high Fix horizontal scroll commands from the mouse @done(26-02-19 21:18)
6464
✔ @low Add advanced header parsing @done(26-02-21 18:37)
65+
☐ @high Implement the to raw of RobTopToJsonV2
6566
Nice To Haves:
6667
☐ Add inputs to the JSON code block
6768
☐ Add spoofing (response mocking) support

mod.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"geode": "5.6.1",
3-
"version": "v0.8.6",
3+
"version": "v0.8.7",
44
"id": "smjs.gdintercept",
55
"name": "GDIntercept",
66
"developers": [
@@ -141,11 +141,17 @@
141141
"description": "Settings related to the proxy server."
142142
},
143143
"pause-between-plays": {
144-
"name": "Pause Between Plays",
144+
"name": "Pause Between Sessions",
145145
"description": "If this is enabled, GDI will remember the pause option between session.",
146146
"type": "bool",
147147
"default": false
148148
},
149+
"mask-telemetry": {
150+
"name": "Mask Telemetry Data",
151+
"description": "Masks telemetry data being sent to the GD servers like OS info & local user info.",
152+
"type": "bool",
153+
"default": true
154+
},
149155
"cache-limit": {
150156
"name": "Cache Limit",
151157
"description": "The amount of requests to cache before removing the oldest one.",

src/proxy/HttpInfo.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,20 @@ const LookupTable<ContentType, converters::Converter*> HttpInfo::CONVERTERS({
1616
{ ContentType::FORM, new FormToJson() }
1717
});
1818

19-
HttpInfo::Content HttpInfo::getContent(const bool raw, const ContentType originalContentType, const std::string_view path, const std::string_view original) {
19+
HttpInfo::Content HttpInfo::getContent(const bool raw, const ContentType originalContentType, const std::string_view path, const std::string_view original, const bool censor) {
2020
if (HttpInfo::CONVERTERS.contains(originalContentType)) {
2121
const converters::Converter* converter = HttpInfo::CONVERTERS.at(originalContentType);
2222

2323
if (!raw) {
24-
return { converter->getResultContentType(), converter->convert(path, original) };
25-
} else if (Mod::get()->getSettingValue<bool>("censor-data") && converter->isNeedsSanitization()) {
26-
return { originalContentType, converter->toRaw(path, converter->convert(path, original)) };
24+
return { converter->getResultContentType(), converter->convert(path, original, censor) };
25+
} else if (
26+
(
27+
(censor && Mod::get()->getSettingValue<bool>("censor-data")) &&
28+
converter->isNeedsCensoring()
29+
) ||
30+
Mod::get()->getSettingValue<bool>("mask-telemetry") && converter->isNeedsMasking()
31+
) {
32+
return { originalContentType, converter->toRaw(path, converter->convert(path, original, censor)) };
2733
}
2834
}
2935

@@ -283,10 +289,9 @@ m_headers(HttpInfo::parseHeaderListStrings(HttpInfo::parseCocosHeaders(request->
283289
m_body(std::string(request->getRequestData(), request->getRequestDataSize())),
284290
m_contentType(HttpInfo::determineContentType(url.getPath(), true, m_body)),
285291
m_startTime(Request::getRequestTime()) {
286-
const size_t index = m_body.find("dvs=");
292+
if (Mod::get()->getSettingValue<bool>("mask-telemetry")) {
293+
m_body = this->getBodyContent(true, false).contents;
287294

288-
if (index != std::string::npos) {
289-
m_body.replace(index, 5, "dvs=12");
290295
request->setRequestData(m_body.c_str(), m_body.size());
291296
}
292297
}
@@ -315,8 +320,8 @@ std::vector<std::string> HttpInfo::Request::getHeader(const std::string_view key
315320
}
316321
}
317322

318-
HttpInfo::Content HttpInfo::Request::getBodyContent(const bool raw) const {
319-
return HttpInfo::getContent(raw, m_contentType, m_path, m_body);
323+
HttpInfo::Content HttpInfo::Request::getBodyContent(const bool raw, const bool censor) const {
324+
return HttpInfo::getContent(raw, m_contentType, m_path, m_body, censor);
320325
}
321326

322327
void HttpInfo::Request::resetTime() {
@@ -371,8 +376,8 @@ HttpInfo::Content HttpInfo::Response::getHeaderList(const bool raw) const {
371376
return HttpInfo::getHeaders(raw, m_headers);
372377
}
373378

374-
HttpInfo::Content HttpInfo::Response::getResponseContent(const bool raw) const {
375-
return HttpInfo::getContent(raw, m_contentType, m_path, m_response);
379+
HttpInfo::Content HttpInfo::Response::getResponseContent(const bool raw, const bool censor) const {
380+
return HttpInfo::getContent(raw, m_contentType, m_path, m_response, censor);
376381
}
377382

378383
std::vector<std::string> HttpInfo::Response::getHeader(const std::string_view key) const {

src/proxy/HttpInfo.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace proxy {
2222
class Request {
2323
public:
2424
Content getHeaderList(const bool raw = false) const;
25-
Content getBodyContent(const bool raw = true) const;
25+
Content getBodyContent(const bool raw = true, const bool censor = true) const;
2626
std::vector<std::string> getHeader(const std::string_view key) const;
2727
private:
2828
static size_t getRequestTime();
@@ -49,7 +49,7 @@ namespace proxy {
4949
public:
5050
std::string stringifyStatusCode() const;
5151
Content getHeaderList(const bool raw = false) const;
52-
Content getResponseContent(const bool raw = true) const;
52+
Content getResponseContent(const bool raw = true, const bool censor = true) const;
5353
std::vector<std::string> getHeader(const std::string_view key) const;
5454
private:
5555
static size_t calculateResponseTime(std::shared_ptr<HttpInfo> info);
@@ -88,7 +88,7 @@ namespace proxy {
8888
private:
8989
static const LookupTable<enums::ContentType, converters::Converter*> CONVERTERS;
9090

91-
static Content getContent(const bool raw, const enums::ContentType originalContentType, const std::string_view path, const std::string_view original);
91+
static Content getContent(const bool raw, const enums::ContentType originalContentType, const std::string_view path, const std::string_view original, const bool censor);
9292
static Content getHeaders(const bool raw, const Headers& headers);
9393
static enums::ContentType determineContentType(const std::string_view path, const bool isBody, const std::string_view content);
9494
static std::string translateHttpVersion(const geode::utils::web::HttpVersion version);

src/proxy/URL.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ void proxy::URL::parsePath(size_t& index) {
170170
}
171171

172172
if (queryStart != std::string::npos && converter.canConvert(m_path, false, m_queryString = fullPath.substr(queryStart + 1))) {
173-
m_query = ordered_json::parse(converter.convert(m_path, m_queryString));
173+
m_query = ordered_json::parse(converter.convert(m_path, m_queryString, true));
174174
}
175175

176176
index += size;

src/proxy/converters/Converter.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@
33
using namespace nlohmann;
44
using namespace geode::prelude;
55

6-
proxy::converters::Converter::Converter(const enums::ContentType resultContentType) {
7-
m_needsSanitization = resultContentType == enums::ContentType::JSON;
8-
m_resultContentType = resultContentType;
9-
}
6+
proxy::converters::Converter::Converter(const enums::ContentType resultContentType, const bool needsMasking) : m_needsCensoring(resultContentType == enums::ContentType::JSON),
7+
m_resultContentType(resultContentType),
8+
m_needsMasking(needsMasking) { }
109

1110
bool proxy::converters::isInt(const std::string_view str) {
1211
if (str.empty()) {
@@ -67,8 +66,8 @@ bool proxy::converters::isString(const std::string_view str) {
6766
return !isEscaped;
6867
}
6968

70-
bool proxy::converters::shouldSanitize(const std::string_view key) {
71-
static const Stream<std::string> sensitiveKeys = {
69+
bool proxy::converters::shouldCensor(const std::string_view key) {
70+
static const std::vector<std::string> SENSITIVE_KEYS {
7271
"password",
7372
"pass",
7473
"passwd",
@@ -80,7 +79,7 @@ bool proxy::converters::shouldSanitize(const std::string_view key) {
8079
"gjp2"
8180
};
8281

83-
return sensitiveKeys.includes(std::string(key));
82+
return std::find(SENSITIVE_KEYS.begin(), SENSITIVE_KEYS.end(), key) != SENSITIVE_KEYS.end();
8483
}
8584

8685
std::string proxy::converters::safeDump(const nlohmann::ordered_json& json, const size_t indent, const bool quoteless) {
@@ -91,8 +90,8 @@ std::string proxy::converters::safeDump(const nlohmann::ordered_json& json, cons
9190
}
9291
}
9392

94-
nlohmann::json proxy::converters::getPrimitiveJsonType(const std::string_view key, const std::string_view str) {
95-
if (converters::shouldSanitize(key) && Mod::get()->getSettingValue<bool>("censor-data")) {
93+
nlohmann::json proxy::converters::getPrimitiveJsonType(const std::string_view key, const std::string_view str, const bool censor) {
94+
if ((Mod::get()->getSettingValue<bool>("censor-data") || censor) && converters::shouldCensor(key)) {
9695
return json("********");
9796
} else if (converters::isNull(str)) {
9897
return json();

src/proxy/converters/Converter.hpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,18 @@ namespace proxy::converters {
99
bool isBool(const std::string_view str);
1010
bool isNull(const std::string_view str);
1111
bool isString(const std::string_view str);
12-
bool shouldSanitize(const std::string_view key);
12+
bool shouldCensor(const std::string_view key);
1313
std::string safeDump(const nlohmann::ordered_json& json, const size_t indent = 2, const bool quoteless = false);
14-
nlohmann::json getPrimitiveJsonType(const std::string_view key, const std::string_view str);
14+
nlohmann::json getPrimitiveJsonType(const std::string_view key, const std::string_view str, const bool censor);
1515

1616
class Converter {
1717
public:
18-
Converter(const enums::ContentType resultContentType);
18+
Converter(const enums::ContentType resultContentType, const bool needsMasking = false);
1919
virtual bool canConvert(const std::string_view path, const bool isBody, const std::string_view original) const = 0;
20-
virtual std::string convert(const std::string_view path, const std::string_view original) const = 0;
20+
virtual std::string convert(const std::string_view path, const std::string_view original, const bool censor) const = 0;
2121
virtual std::string toRaw(const std::string_view path, const std::string_view original) const = 0;
22-
BOOL_GETTER(needsSanitization, NeedsSanitization);
22+
BOOL_PROTECTED_GETTER(needsCensoring, NeedsCensoring);
23+
BOOL_PROTECTED_GETTER(needsMasking, NeedsMasking);
2324
PRIMITIVE_GETTER(enums::ContentType, resultContentType, ResultContentType);
2425
};
2526
}

src/proxy/converters/FormToJson.cpp

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,22 @@
22

33
using namespace nlohmann;
44

5-
proxy::converters::FormToJson::FormToJson() : Converter(enums::ContentType::JSON) { };
5+
proxy::converters::FormToJson::FormToJson() : Converter(enums::ContentType::JSON, true) { };
6+
7+
bool proxy::converters::FormToJson::shouldMask(const std::string_view key) const {
8+
static const std::vector<std::string> MASKED_STRINGS {
9+
"dvs",
10+
"vkey",
11+
"gdw"
12+
};
13+
14+
if (key == "udid" || key == "uuid") {
15+
// Don't mask user info if the user is not logged in
16+
return GJAccountManager::get()->m_accountID != 0;
17+
} else {
18+
return std::find(MASKED_STRINGS.begin(), MASKED_STRINGS.end(), key) != MASKED_STRINGS.end();
19+
}
20+
}
621

722
bool proxy::converters::FormToJson::canConvert(const std::string_view path, const bool isBody, const std::string_view original) const {
823
bool hasAssignment = false;
@@ -24,17 +39,17 @@ bool proxy::converters::FormToJson::canConvert(const std::string_view path, cons
2439
return hasAssignment;
2540
}
2641

27-
std::string proxy::converters::FormToJson::convert(const std::string_view path, const std::string_view original) const {
42+
std::string proxy::converters::FormToJson::convert(const std::string_view path, const std::string_view original, const bool censor) const {
2843
ordered_json object(ordered_json::object());
2944

30-
StringUtils::split(original, '&').forEach([&object](const std::string_view section) {
45+
StringUtils::split(original, '&').forEach([&object, censor](const std::string_view section) {
3146
const size_t equalPos = section.find('=');
3247
const std::string_view key = section.substr(0, equalPos);
3348

3449
if (equalPos == std::string::npos) {
3550
object[key] = json("");
3651
} else {
37-
object[key] = getPrimitiveJsonType(key, section.substr(equalPos + 1));
52+
object[key] = getPrimitiveJsonType(key, section.substr(equalPos + 1), censor);
3853
}
3954
});
4055

@@ -43,17 +58,19 @@ std::string proxy::converters::FormToJson::convert(const std::string_view path,
4358

4459
std::string proxy::converters::FormToJson::toRaw(const std::string_view path, const std::string_view original) const {
4560
const ordered_json object = ordered_json::parse(original);
61+
const bool shouldMask = Mod::get()->getSettingValue<bool>("mask-telemetry");
4662
std::string result;
4763

4864
for (const auto& [key, value] : object.items()) {
49-
if (result.size()) {
65+
if (!shouldMask || !this->shouldMask(key)) {
66+
result.append(key);
67+
result.push_back('=');
68+
result.append(converters::safeDump(value, 0, true));
5069
result.push_back('&');
5170
}
52-
53-
result.append(key);
54-
result.push_back('=');
55-
result.append(converters::safeDump(value, 0, true));
5671
}
5772

73+
result.pop_back();
74+
5875
return result;
5976
}

0 commit comments

Comments
 (0)