Skip to content
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

[PM-15934] Add agent-forwarding detection and git signing detection parsers #12371

Open
wants to merge 16 commits into
base: main
Choose a base branch
from

Conversation

quexten
Copy link
Contributor

@quexten quexten commented Dec 12, 2024

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-15934
https://bitwarden.atlassian.net/browse/PM-15956
https://bitwarden.atlassian.net/browse/PM-15964

📔 Objective

This PR adds support for detecting and showing:

  • Whether a request is an SSHSIG request (for e.g. git signing)
  • Wether a request is coming from a remote server via agent forwarding

In the long term this also enables:

  • "Don't ask again for X time" (Would work for login, but not for forwarded and possibly not for signing)
  • Disable agent forwarding entirely

Note for reviewing: The callback is getting kind of long with many params. I kept it for a follow-up refactor for now (after #12166 is also merged) but let me know if you consider it blocking and we can move it to a struct in this PR.

📸 Screenshots

image

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

Copy link
Contributor

github-actions bot commented Dec 12, 2024

Logo
Checkmarx One – Scan Summary & Detailsf4f21b9c-86f7-42f4-aa2d-943e76aff1ef

New Issues

Severity Issue Source File / Package Checkmarx Insight
MEDIUM Client_Privacy_Violation /libs/vault/src/components/decryption-failure-dialog/decryption-failure-dialog.component.html: 17 Attack Vector
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts: 47 Attack Vector
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts: 47 Attack Vector
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts: 52 Attack Vector
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.ts: 52 Attack Vector
MEDIUM Client_Privacy_Violation /apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.ts: 25 Attack Vector
MEDIUM Client_Privacy_Violation /apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.ts: 25 Attack Vector
MEDIUM Client_Privacy_Violation /apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.ts: 25 Attack Vector
MEDIUM Client_Privacy_Violation /apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.ts: 25 Attack Vector
MEDIUM Client_Privacy_Violation /apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.ts: 25 Attack Vector

Fixed Issues

Severity Issue Source File / Package
MEDIUM Client_Privacy_Violation /libs/vault/src/components/decryption-failure-dialog/decryption-failure-dialog.component.html: 17
MEDIUM Client_Privacy_Violation /apps/desktop/src/platform/components/approve-ssh-request.html: 6
MEDIUM Client_Privacy_Violation /apps/browser/src/vault/popup/settings/trash-list-items-container/trash-list-items-container.component.html: 6
MEDIUM Client_Privacy_Violation /apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.html: 53
MEDIUM Client_Privacy_Violation /apps/web/src/app/vault/components/vault-items/vault-cipher-row.component.html: 31

Copy link

codecov bot commented Dec 12, 2024

Codecov Report

Attention: Patch coverage is 0% with 8 lines in your changes missing coverage. Please review.

Project coverage is 34.14%. Comparing base (67a59b6) to head (18e50de).

✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...top/src/platform/components/approve-ssh-request.ts 0.00% 5 Missing ⚠️
...desktop/src/platform/services/ssh-agent.service.ts 0.00% 2 Missing ⚠️
...esktop/src/platform/main/main-ssh-agent.service.ts 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #12371      +/-   ##
==========================================
- Coverage   34.14%   34.14%   -0.01%     
==========================================
  Files        2937     2937              
  Lines       90353    90360       +7     
  Branches    16967    16969       +2     
==========================================
  Hits        30849    30849              
- Misses      57049    57056       +7     
  Partials     2455     2455              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@quexten quexten requested a review from a team December 18, 2024 17:07
@quexten quexten requested a review from coltonhurst December 18, 2024 17:23
@quexten quexten marked this pull request as ready for review December 18, 2024 17:25
@quexten quexten requested a review from a team as a code owner December 18, 2024 17:25
@quexten quexten requested review from addisonbeck and dani-garcia and removed request for addisonbeck December 18, 2024 17:25
Copy link
Member

@dani-garcia dani-garcia left a comment

Choose a reason for hiding this comment

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

Looks pretty good to me, just some small comments

@@ -36,19 +38,43 @@ pub struct SshAgentUIRequest {
pub cipher_id: Option<String>,
pub process_name: String,
pub is_list: bool,
pub is_sig: bool,
pub is_git: bool,
Copy link
Member

@dani-garcia dani-garcia Dec 19, 2024

Choose a reason for hiding this comment

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

Tiny non-blocking nit, instead of returning an is_git boolean, would it make more sense to return the namespace directly and let the TypeScript UI choose which message to show then?

Would mean less changes if we ever need to add more messages.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, passing this through now.

apps/desktop/desktop_native/core/src/ssh_agent/mod.rs Outdated Show resolved Hide resolved

pub(crate) fn parse_request(data: &[u8]) -> Result<SshAgentSignRequest, anyhow::Error> {
let magic_header = "SSHSIG";
let mut data_iter = data.to_vec().into_iter();
Copy link
Member

@dani-garcia dani-garcia Dec 19, 2024

Choose a reason for hiding this comment

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

This is getting a clippy lint for me, I think you can change it to data.iter().copied(); to avoid it.

That said, using iterators like this is kind of unergonomic, for this type of byte handling I usually recommend the bytes crate: https://docs.rs/bytes/latest/bytes/ (tokio is using it extensively so it's already in our builds as a transitive dep)

pub(crate) fn parse_request(data: &[u8]) -> Result<SshAgentSignRequest, anyhow::Error> {
    let mut data = Bytes::copy_from_slice(data);

    let magic_header = "SSHSIG";
    // This splits the six first characters into `header` and `data` advances it's internal cursor by 6
    let header = data.split_to(magic_header.len());

    // sshsig; based on https://github.com/openssh/openssh-portable/blob/master/PROTOCOL.sshsig
    if header == magic_header.as_bytes() {
        // This automatically advances the internal cursor by 4
        let _version = data.get_u32();

        // read until null byte
        let namespace = data
            .into_iter()
            .take_while(|&x| x != 0)
            .collect::<Vec<u8>>();

PD: Another option is the byteorder crate, which we already have as a dependency, though I haven't used it much: https://docs.rs/byteorder/latest/byteorder

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice, this is exactly what I was looking for!

@quexten quexten changed the title Add agent-forwarding detection and git signing detection parsers [PM-15934] Add agent-forwarding detection and git signing detection parsers Dec 23, 2024
@quexten quexten requested a review from dani-garcia January 9, 2025 12:46
isForwarding: boolean
namespace?: string
}
export function serve(callback: (err: Error | null, arg: SshUiRequest) => any): Promise<SshAgentState>
Copy link
Member

Choose a reason for hiding this comment

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

Nice! Looks better as a separate struct this way, at least we don't get arg0, arg1, arg2 parameters.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hehe, yeah. Meant to do it sometime either-way, but in this case clippy complained.

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.

2 participants