Skip to content

Validate endpoint and dns in WireGuard config #24100

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

bsclifton
Copy link
Member

@bsclifton bsclifton commented Jun 10, 2024

Fixes brave/brave-browser#37960

Submitter Checklist:

  • I confirm that no security/privacy review is needed and no other type of reviews are needed, or that I have requested them
  • There is a ticket for my issue
  • Used GitHub auto-closing keywords in the PR description above
  • Wrote a good PR/commit description
  • Squashed any review feedback or "fixup" commits before merge, so that history is a record of what happened in the repo, not your PR
  • Added appropriate labels (QA/Yes or QA/No; release-notes/include or release-notes/exclude; OS/...) to the associated issue
  • Checked the PR locally:
    • npm run test -- brave_browser_tests, npm run test -- brave_unit_tests wiki
    • npm run presubmit wiki, npm run gn_check, npm run tslint
  • Ran git rebase master (if needed)

Reviewer Checklist:

  • A security review is not needed, or a link to one is included in the PR description
  • New files have MPL-2.0 license header
  • Adequate test coverage exists to prevent regressions
  • Major classes, functions and non-trivial code blocks are well-commented
  • Changes in component dependencies are properly reflected in gn
  • Code follows the style guide
  • Test plan is specified in PR before merging

After-merge Checklist:

Test Plan:

See brave/brave-browser#37960

@bsclifton bsclifton self-assigned this Jun 10, 2024
@bsclifton bsclifton force-pushed the bsc-wg-endpoint-verify branch from c3193ab to f680371 Compare June 10, 2024 20:32
@bsclifton
Copy link
Member Author

Whoops - just noticed this:

Using std::regex adds unnecessary binary size to Chrome. Please use
re2::RE2 instead (crbug.com/755321)

Fixing now...

@bsclifton bsclifton requested a review from a team as a code owner June 11, 2024 07:50
@bsclifton bsclifton changed the title Check hostname for WireGuard endpoint Validate endpoint and dns in WireGuard config Jun 11, 2024
@bsclifton bsclifton force-pushed the bsc-wg-endpoint-verify branch 2 times, most recently from 6cc9717 to 3c8e4fb Compare June 11, 2024 16:31
Copy link
Member

@diracdeltas diracdeltas left a comment

Choose a reason for hiding this comment

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

@bsclifton bsclifton force-pushed the bsc-wg-endpoint-verify branch 2 times, most recently from dcee495 to 2e56d56 Compare June 11, 2024 21:12
@bsclifton
Copy link
Member Author

bsclifton commented Jun 11, 2024

Fixed and added tests for those cases. Thanks @diracdeltas

@bsclifton bsclifton force-pushed the bsc-wg-endpoint-verify branch from 2e56d56 to c2418b0 Compare June 12, 2024 07:46
Copy link
Member

@diracdeltas diracdeltas left a comment

Choose a reason for hiding this comment

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

reject the entire config if it contains any unicode characters OR any # - see https://bravesoftware.slack.com/archives/C6R461GF4/p1718182338474479 and https://bravesoftware.slack.com/archives/C6R461GF4/p1718215096342729 for test cases

@bsclifton bsclifton force-pushed the bsc-wg-endpoint-verify branch from c2418b0 to 36fa9e0 Compare June 12, 2024 19:57
@bsclifton
Copy link
Member Author

Updated to add these checks

@bsclifton bsclifton force-pushed the bsc-wg-endpoint-verify branch from 36fa9e0 to ee0afea Compare June 12, 2024 21:00
@bsclifton bsclifton force-pushed the bsc-wg-endpoint-verify branch from ee0afea to 6c651ee Compare June 12, 2024 21:12
@diracdeltas diracdeltas self-requested a review June 12, 2024 21:19
@bsclifton bsclifton force-pushed the bsc-wg-endpoint-verify branch from 6c651ee to d2b85ad Compare June 13, 2024 06:46
Copy link
Member

@simonhong simonhong left a comment

Choose a reason for hiding this comment

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

++ 👍🏼

@bsclifton bsclifton force-pushed the bsc-wg-endpoint-verify branch from d2b85ad to 2da00ce Compare June 13, 2024 07:51
@bsclifton bsclifton enabled auto-merge June 13, 2024 16:21
// Match our expected `DNS` field.
absl::string_view input(config_str);
while (match_count < 2 &&
re2::RE2::FindAndConsume(&input, R"((?m)^\s*DNS = 1\.1\.1\.1$)")) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

seems a bit odd to me that we're using regex to validate things like ip address and hostnames since there are better tools for that in chromium. Wouldn't it be better to capture the field value and validate it using GURL, etc... ?

Copy link
Collaborator

@cdesouza-chromium cdesouza-chromium Jun 13, 2024

Choose a reason for hiding this comment

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

I think with GURL you still have to add a schema. There's also net::HostPortPair.

Copy link
Member Author

@bsclifton bsclifton Jun 13, 2024

Choose a reason for hiding this comment

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

With our code, we're hardcoding 1.1.1.1 as the DNS. Since that's the case, I think it's fine to do a text match like this. Unless we change the default, there's no need to validate (it's either right or wrong).

Hostname is a bit more complex. We could validate with GURL; but we just want to make sure the two expected domains are found in the domain for Endpoint. Subdomain can have any value

// low ascii (excluding CR/LF), #, high ascii
if (re2::RE2::PartialMatch(
config_str,
R"([\x00-\x09]|[\x0b-\x0c]|[\x0d-\x1f]|[\x23]|[\x7f-\xFF])")) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

same as above, shouldn't we be capturing the value and using existing utilities to validate their contents?

Copy link
Collaborator

Choose a reason for hiding this comment

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

By the way, there is a simple INI parser in chromium under chrome/common/ini_parser.h, although this one wouldn´t handle multi entry for keys.

Copy link
Member Author

Choose a reason for hiding this comment

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

With this, we just want to make sure none of these characters are in the config. It's not allowed

@@ -82,6 +143,30 @@ WireguardKeyPair GenerateNewX25519Keypair() {
EncodeBase64(std::vector<uint8_t>(privkey, privkey + 32)));
}

// See https://github.com/google/re2/wiki/Syntax for RE2 syntax
bool IsValidConfig(const wchar_t* config) {
Copy link
Collaborator

@cdesouza-chromium cdesouza-chromium Jun 13, 2024

Choose a reason for hiding this comment

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

Don't you think it would be better to have base::wcstring_view config here?

Copy link
Member Author

@bsclifton bsclifton Jun 13, 2024

Choose a reason for hiding this comment

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

We could - the COM interface that is calling this (IsValidConfig) is in browser/brave_vpn/win/brave_vpn_wireguard_service/service/brave_wireguard_manager.cc (see EnableVpn).

I didn't want to put any casting logic in the method, just passing the raw config value to the validation.

Copy link
Collaborator

@cdesouza-chromium cdesouza-chromium Jun 13, 2024

Choose a reason for hiding this comment

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

base::wcstring_view won't require any casting here though. It will act just like wchar_t*, but a little bit safer.

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried and ran into some casting issues 😦

// low ascii (excluding CR/LF), #, high ascii
if (re2::RE2::PartialMatch(
config_str,
R"([\x00-\x09]|[\x0b-\x0c]|[\x0d-\x1f]|[\x23]|[\x7f-\xFF])")) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I wonder if this is the equivalent of base::IsStringASCII

Copy link
Member Author

@bsclifton bsclifton Jun 13, 2024

Choose a reason for hiding this comment

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

Basically this is making sure something is not in ASCII range 0 - 9, 11, 12, 14-31, 35 (#), or 126+

10 and 13 allowed because config has CR (13) and LF (10)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

Would need to see what the masks evaluate to:
https://source.chromium.org/chromium/chromium/src/+/main:base/strings/string_util_impl_helpers.h;l=164-167;drc=90cac1911508d3d682a67c97aa62483eb712f69a

I think what we have is OK - but can look further if it's a blocker

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think it's better to use a well tested existing utility than a regex if it has what we're looking for

Copy link
Collaborator

@cdesouza-chromium cdesouza-chromium left a comment

Choose a reason for hiding this comment

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

LGTM % few comments

@bsclifton
Copy link
Member Author

Created brave/brave-browser#39029 as a follow up

@bsclifton
Copy link
Member Author

Talking with reviewers- a better solution would be to not pass a config to the COM interface.

Instead, only pass the required fields and then have the code generate the config (to avoid all these config parsing edge cases).

Closing PR

@bsclifton bsclifton closed this Jun 13, 2024
auto-merge was automatically disabled June 13, 2024 22:11

Pull request was closed

@bsclifton bsclifton deleted the bsc-wg-endpoint-verify branch June 13, 2024 22:11
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.

[hackerone] Harden the connect method for WireGuard tunnel service
6 participants