Skip to content

[BED-5838] NTLM registry processing updates - #1440

Closed
definitelynotagoblin wants to merge 31 commits into
mainfrom
BED-5838
Closed

[BED-5838] NTLM registry processing updates#1440
definitelynotagoblin wants to merge 31 commits into
mainfrom
BED-5838

Conversation

@definitelynotagoblin

@definitelynotagoblin definitelynotagoblin commented May 2, 2025

Copy link
Copy Markdown
Contributor

Description

Making NTLM registry data for computer nodes nullable, defaulting values to null if not exists; skipping creation of CoerceAndRelayNTLM* edges for computers where RestrictOutboundNTLM is null or false.

Motivation and Context

Resolves BED-5838

How Has This Been Tested?

Localhost, importing Computers collections files generated on ESC 10 Lab and manually edited to check expected behaviors of ntlm registry fields.

Screenshots (optional):

Types of changes

  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

Summary by CodeRabbit

  • New Features
    • Added a configuration option to control how missing "Restrict Outbound NTLM" registry values are handled during NTLM edge processing.
    • Introduced a new UI section for managing the "Restrict Outbound NTLM Default Value" setting, including a confirmation dialog for changes.
  • Bug Fixes
    • Improved handling of optional NTLM registry data to prevent errors from missing values.
  • Tests
    • Added comprehensive tests for the new configuration UI component and extended integration tests for NTLM relay scenarios.
  • Refactor
    • Streamlined NTLM relay post-processing logic and improved test structure for better coverage and maintainability.
  • Chores
    • Added a database migration to support the new configuration parameter.

@definitelynotagoblin definitelynotagoblin self-assigned this May 2, 2025
…y don't; skip CoerceAndRelayNTLMToSMB edge gen to computers where RestrictOutboundNTLM is enabled
@definitelynotagoblin
definitelynotagoblin marked this pull request as ready for review May 16, 2025 18:18
Comment thread cmd/api/src/go.mod

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.

What is going on that's causing this file to drop libraries?

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.

Nothing exciting going on in this folder - mostly copy/paste from a CitrixRDPConfiguration component that affects the same behavior.

This does show how difficult it is though to add new BH configuration toggles, so I'll want to simplify the configutation toggle components to make it easier to add a new one in the future.

Comment thread cmd/api/src/model/appcfg/flag.go Outdated
Comment thread packages/go/ein/ad.go
Comment thread packages/go/analysis/ad/ntlm.go Outdated
@coderabbitai

coderabbitai Bot commented May 22, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

A new configuration parameter, "Restrict Outbound NTLM Default Value," was introduced across backend, database, and frontend layers. The change enables administrators to control how missing NTLM registry values are interpreted during NTLM relay analysis. Supporting logic, tests, and UI components were added or updated to propagate and manage this setting throughout the system.

Changes

File(s) / Path(s) Change Summary
cmd/api/src/analysis/ad/ntlm_integration_test.go Refactored NTLM relay integration tests to use parameterized subtests and helper functions; expanded coverage for edge cases and negative scenarios.
cmd/api/src/analysis/ad/post.go Updated Post function signature to accept a boolean flag for treating missing NTLM restriction properties; passed this flag to post-processing logic.
cmd/api/src/daemons/datapipe/analysis.go Added configuration flag retrieval and passed it to ad.Post for NTLM restriction handling.
cmd/api/src/database/parameters_test.go Added subtest to verify the new configuration parameter; minor formatting cleanup.
cmd/api/src/model/appcfg/parameter.go Added new config key and struct for NTLM restriction default; updated validation, key checks, and added getter function.
cmd/api/src/test/integration/harnesses.go Updated test harness setup to optionally set the NTLM restriction property based on input.
cmd/api/src/database/migration/migrations/v7.6.0.sql Added migration to insert the new configuration parameter with default value.
packages/go/analysis/ad/ntlm.go Refactored NTLM cache logic to use helper functions; added flag for missing NTLM restriction property; updated signatures and filtering logic.
packages/go/ein/ad.go Improved handling of optional NTLM registry fields by checking for nil before assignment.
packages/go/ein/ad_test.go Updated test to use pointer for NTLM registry field to match new struct definition.
packages/go/ein/incoming_models.go Changed all NTLM registry fields in NTLMRegistryInfo struct to pointer types.
packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/RestrictOutboundNTLMDefaultValueConfiguration.tsx Added new React component to manage and display the NTLM restriction default configuration.
packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/RestrictOutboundNTLMDefaultValueConfirmDialog.tsx Added confirmation dialog component for toggling the NTLM restriction default setting.
packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/RestrictOutboundNTLMDefaultValueConfiguration.test.tsx Added comprehensive tests for the new NTLM restriction default configuration component.
packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/index.ts Added re-export module for the new configuration component.
packages/javascript/bh-shared-ui/src/components/index.ts Exported the new NTLM restriction default configuration component.
packages/javascript/js-client-library/src/utils/config.ts Added new config key, type, union, and parser for NTLM restriction default value.
cmd/ui/src/views/BloodHoundConfiguration/BloodHoundConfiguration.tsx Rendered the new configuration component in the main configuration UI.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI
    participant API
    participant DB

    User->>UI: Toggles "Restrict Outbound NTLM Default Value" switch
    UI->>UI: Show confirmation dialog
    User->>UI: Confirms change
    UI->>API: PUT /configuration with new value
    API->>DB: Update parameter in database
    DB-->>API: Ack
    API-->>UI: Success response
    UI->>User: Update switch state
Loading
sequenceDiagram
    participant Daemon
    participant API
    participant DB

    Daemon->>API: Request NTLM post-processing
    API->>DB: Get "Restrict Outbound NTLM Default Value"
    DB-->>API: Return config value
    API->>API: Use config to interpret missing NTLM registry values
    API->>DB: Perform NTLM relay analysis with config
    DB-->>API: Analysis results
    API-->>Daemon: Return results
Loading

Suggested labels

api

Poem

In the warren, a switch appears,
NTLM’s fate now crystal clear.
A toggle for missing registry keys,
With tests and helpers, code with ease.
UI and backend, in harmony sing,
Restrict or not? Let users bring
The power of choice—what joy this brings! 🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 482597b and 11716cb.

📒 Files selected for processing (7)
  • cmd/api/src/analysis/ad/ntlm_integration_test.go (5 hunks)
  • cmd/api/src/analysis/ad/post.go (2 hunks)
  • cmd/api/src/daemons/datapipe/analysis.go (1 hunks)
  • cmd/api/src/database/migration/migrations/v7.6.0.sql (1 hunks)
  • cmd/api/src/database/parameters_test.go (1 hunks)
  • cmd/api/src/model/appcfg/parameter.go (4 hunks)
  • cmd/api/src/test/integration/harnesses.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • cmd/api/src/daemons/datapipe/analysis.go
  • cmd/api/src/database/parameters_test.go
  • cmd/api/src/analysis/ad/post.go
  • cmd/api/src/test/integration/harnesses.go
  • cmd/api/src/model/appcfg/parameter.go
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build BloodHound Container Image / Build and Package Container
  • GitHub Check: run-analysis
  • GitHub Check: run-tests
  • GitHub Check: build-ui
🔇 Additional comments (8)
cmd/api/src/database/migration/migrations/v7.6.0.sql (1)

28-30: LGTM! Well-formed database migration.

The migration correctly adds the new configuration parameter for NTLM registry processing. The parameter follows established naming conventions, uses appropriate conflict handling, and sets a sensible default value that maintains backward compatibility.

cmd/api/src/analysis/ad/ntlm_integration_test.go (7)

45-75: Excellent test coverage for the new configuration behavior.

The first test case correctly validates that when RestrictOutboundNTLM is explicitly set to false, the CoerceAndRelayNTLMToADCS edge is created regardless of the treatMissingRestrictOutboundNTLMPropertyAsRestricting flag setting.


77-99: Correctly tests the restrict outbound NTLM behavior.

This test case properly verifies that when RestrictOutboundNTLM is explicitly set to true, no CoerceAndRelayNTLMToADCS edges are created, which aligns with the security expectation that restricting outbound NTLM should prevent relay attacks.


101-130: Good coverage of the nil property scenario with permissive default.

This test case correctly validates that when RestrictOutboundNTLM is nil (missing) and treatMissingRestrictOutboundNTLMPropertyAsRestricting is false, the system treats the missing registry as non-restricting and creates the edge.


132-153: Properly tests the restrictive default behavior for missing properties.

This test case correctly validates that when RestrictOutboundNTLM is nil (missing) and treatMissingRestrictOutboundNTLMPropertyAsRestricting is true, the system treats the missing registry as restricting and does not create edges.


199-218: Well-designed helper function reduces code duplication.

The postCoerceAndRelayNTLMToADCS helper function effectively consolidates the repeated setup and execution logic, making the tests more maintainable. The function properly accepts the treatMissingRestrictOutboundNTLMPropertyAsRestricting parameter and passes it through to the NTLM cache creation.


259-294: Comprehensive test coverage for SMB relay scenarios.

The new test case for SMB relay with permissive defaults correctly validates that when treatMissingRestrictOutboundNTLMPropertyAsRestricting is false, additional computers are included in the relay analysis. The test properly expects 3 results instead of 2, indicating that computers with missing RestrictOutboundNTLM properties are now included.


369-394: Excellent helper function for SMB relay testing.

The postCoerceAndRelayNTLMToSMB helper function follows the same well-designed pattern as the ADCS helper, consolidating repeated logic while properly parameterizing the configuration behavior. The function correctly passes the treatMissingRestrictOutboundNTLMPropertyAsRestricting flag to the NTLM cache creation.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 3

🧹 Nitpick comments (9)
cmd/api/src/test/integration/harnesses.go (1)

8827-8827: Function signature change aligns with the PR objectives.

The updated signature now accepts a nullable boolean parameter for restrictOutboundNTLMComputerProperty, which supports testing scenarios where the RestrictOutboundNTLM property can be explicitly set or omitted. This change is aligned with the PR objective of making NTLM registry data nullable.

Consider adding a doc comment to explain the purpose and expected values of this parameter:

+// Setup initializes the test harness with the necessary nodes and relationships.
+// If restrictOutboundNTLMComputerProperty is non-nil, the RestrictOutboundNTLM property
+// of the Computer node is set to the provided value. If nil, the property is not set.
func (s *CoerceAndRelayNTLMtoADCS) Setup(graphTestContext *GraphTestContext, restrictOutboundNTLMComputerProperty *bool) {
packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/RestrictOutboundNTLMDefaultValueConfirmDialog.tsx (1)

51-55: Avoid mixing Markdown‐style back-ticks with HTML <b> tags

Back-ticks render as literal characters in HTML, so users will literally see “`Confirm`”.
If you intend to emphasise the words, drop the back-ticks (or use <code> if you really want monospace).

-                <Typography sx={{ fontSize: '0.75rem' }}>
-                    Select <b>`Confirm`</b> to proceed. Changes will be reflected upon completion of next analysis.
-                </Typography>
+                <Typography sx={{ fontSize: '0.75rem' }}>
+                    Select <b>Confirm</b> to proceed. Changes will be reflected upon completion of next analysis.
+                </Typography>
...
-                <Typography sx={{ fontSize: '0.75rem' }}>
-                    Select <b>`Cancel`</b> to return to previous configuration.
-                </Typography>
+                <Typography sx={{ fontSize: '0.75rem' }}>
+                    Select <b>Cancel</b> to return to previous configuration.
+                </Typography>
packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/RestrictOutboundNTLMDefaultValueConfiguration.tsx (1)

40-50: Minor readability tweak – consider hasPendingRequests

The boolean describes pending operations rather than unsettled ones.
A clearer name improves self-documentation.

No code change required – optional.

packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/RestrictOutboundNTLMDefaultValueConfiguration.test.tsx (2)

123-130: Potential flake – wait for switch state after async mutation

user.click(confirmButton) triggers an async mutateAsync call.
Immediately asserting panelSwitch is checked can race the network mock (especially on slower CI).

-            await waitFor(() => expect(panelDialogTitle).not.toBeInTheDocument());
-            expect(panelDialogDescription).not.toBeInTheDocument();
-            expect(panelSwitch).toBeChecked();
+            await waitFor(() => {
+                expect(panelDialogTitle).not.toBeInTheDocument();
+                expect(panelDialogDescription).not.toBeInTheDocument();
+                expect(panelSwitch).toBeChecked();
+            });

Apply the same pattern to the “disable” scenario below (lines 178-185).


28-35: Shared mutable serverState risks inter-test coupling

serverState is mutated by each handler and reused across tests. If a test fails before its beforeEach runs, later tests could inherit a polluted state.

Consider moving serverState into each beforeEach block or replacing it with MSW ctx.json that derives its value from the current request payload.

cmd/api/src/analysis/ad/ntlm_integration_test.go (2)

45-75: Enable sub-test concurrency for faster suites

These sub-tests are completely independent – adding t.Parallel() at the top of each t.Run body speeds execution and matches Go’s testing idioms.

t.Run("NTLMCoerceAndRelayNTLMToADCS Success - Restrict Outbound NTLM: false", func(t *testing.T) {
    t.Parallel() // 💡 run sub-test concurrently
    ...
})

Repeat for the remaining sub-tests where harness isolation is guaranteed.


199-218: Deferred operation.Done() without error inspection

operation.Done() returns an error you correctly ignore earlier with require.NoError, but if a panic happens between SubmitReader completion and here, the call may be skipped.

A safer pattern is:

defer func() {
    require.NoError(t, operation.Done())
}()

Not critical, yet increases robustness.

packages/go/analysis/ad/ntlm.go (2)

62-66: Prefer an options struct over another boolean flag

NewNTLMCache now takes a fifth boolean parameter, making the call-site hard to read (true/false conveys no intent). Consider introducing a small NTLMOptions struct (or functional options) so that future behaviour toggles can be added without turning the signature into a “Boolean-parameter soup”.

type NTLMOptions struct {
    TreatMissingRestrictOutboundNTLMAsRestricting bool
}

func NewNTLMCache(ctx context.Context, db graph.Database,
    groupExpansions impact.PathAggregator, opts NTLMOptions) (NTLMCache, error) {
    ...
}

Call sites become self-documenting:

cache, err := NewNTLMCache(ctx, db, expansions,
    NTLMOptions{TreatMissingRestrictOutboundNTLMAsRestricting: cfg.FailClosed})

140-150: isRestrictingOutboundNTLM returns both a value and ErrPropertyNotFound

When the property is missing you already synthesise the boolean according to missingPropertyMeansRestricting. Returning the ErrPropertyNotFound as well forces every caller to remember to special-case it (and several already don’t).
Consider swallowing that specific error inside the helper and return (bool, nil) instead:

-    return missingPropertyMeansRestricting, err
+    if errors.Is(err, graph.ErrPropertyNotFound) {
+        return missingPropertyMeansRestricting, nil
+    }
+    return missingPropertyMeansRestricting, err

This localises the conditional logic and simplifies callers.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3b58f55 and 2fe7815.

📒 Files selected for processing (19)
  • cmd/api/src/analysis/ad/ntlm_integration_test.go (5 hunks)
  • cmd/api/src/analysis/ad/post.go (2 hunks)
  • cmd/api/src/daemons/datapipe/analysis.go (1 hunks)
  • cmd/api/src/database/migration/migrations/schema.sql (1 hunks)
  • cmd/api/src/database/migration/migrations/v7.5.0.sql (1 hunks)
  • cmd/api/src/database/parameters_test.go (2 hunks)
  • cmd/api/src/model/appcfg/parameter.go (4 hunks)
  • cmd/api/src/test/integration/harnesses.go (2 hunks)
  • cmd/ui/src/views/BloodHoundConfiguration/BloodHoundConfiguration.tsx (2 hunks)
  • packages/go/analysis/ad/ntlm.go (6 hunks)
  • packages/go/ein/ad.go (1 hunks)
  • packages/go/ein/ad_test.go (2 hunks)
  • packages/go/ein/incoming_models.go (1 hunks)
  • packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/RestrictOutboundNTLMDefaultValueConfiguration.test.tsx (1 hunks)
  • packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/RestrictOutboundNTLMDefaultValueConfiguration.tsx (1 hunks)
  • packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/RestrictOutboundNTLMDefaultValueConfirmDialog.tsx (1 hunks)
  • packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/index.ts (1 hunks)
  • packages/javascript/bh-shared-ui/src/components/index.ts (1 hunks)
  • packages/javascript/js-client-library/src/utils/config.ts (4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (9)
packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/index.ts (1)
packages/javascript/js-client-library/src/utils/config.ts (1)
  • RestrictOutboundNTLMDefaultValueConfiguration (65-70)
cmd/ui/src/views/BloodHoundConfiguration/BloodHoundConfiguration.tsx (1)
packages/javascript/js-client-library/src/utils/config.ts (1)
  • RestrictOutboundNTLMDefaultValueConfiguration (65-70)
cmd/api/src/database/parameters_test.go (1)
cmd/api/src/model/appcfg/parameter.go (2)
  • RestrictOutboundNTLMDefaultValue (42-42)
  • Parameter (57-64)
cmd/api/src/test/integration/harnesses.go (3)
cmd/api/src/test/integration/graph.go (1)
  • GraphTestContext (46-50)
packages/go/graphschema/ad/ad.go (2)
  • Computer (31-31)
  • RestrictOutboundNTLM (233-233)
packages/go/ein/incoming_models.go (1)
  • Computer (318-338)
packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/RestrictOutboundNTLMDefaultValueConfiguration.tsx (3)
packages/javascript/js-client-library/src/utils/config.ts (2)
  • RestrictOutboundNTLMDefaultValueConfiguration (65-70)
  • parseRestrictOutboundNTLMDefaultValueConfiguration (126-133)
packages/javascript/bh-shared-ui/src/providers/NotificationProvider/hooks.ts (1)
  • useNotifications (22-38)
packages/javascript/bh-shared-ui/src/providers/NotificationProvider/actions.ts (1)
  • addNotification (31-44)
packages/go/ein/ad.go (2)
packages/go/graphschema/ad/ad.go (9)
  • RestrictOutboundNTLM (233-233)
  • RestrictReceivingNTLMTraffic (251-251)
  • RequireSecuritySignature (249-249)
  • EnableSecuritySignature (250-250)
  • NTLMMinClientSec (253-253)
  • NTLMMinServerSec (252-252)
  • LMCompatibilityLevel (254-254)
  • UseMachineID (255-255)
  • ClientAllowedNTLMServers (256-256)
packages/go/dawgs/graph/kind.go (1)
  • String (27-29)
packages/javascript/js-client-library/src/utils/config.ts (2)
cmd/api/src/model/appcfg/parameter.go (1)
  • RestrictOutboundNTLMDefaultValue (42-42)
packages/javascript/js-client-library/src/responses.ts (2)
  • GetConfigurationResponse (277-277)
  • ConfigurationWithMetadata (270-275)
packages/go/ein/incoming_models.go (1)
packages/go/graphschema/ad/ad.go (4)
  • RequireSecuritySignature (249-249)
  • EnableSecuritySignature (250-250)
  • RestrictReceivingNTLMTraffic (251-251)
  • ClientAllowedNTLMServers (256-256)
cmd/api/src/analysis/ad/ntlm_integration_test.go (4)
cmd/api/src/test/integration/harnesses.go (2)
  • HarnessDetails (9868-9980)
  • CoerceAndRelayNTLMToSMB (8878-8899)
packages/go/dawgs/ops/ops.go (2)
  • FetchRelationships (364-374)
  • FetchRelationshipNodes (416-436)
packages/go/analysis/post_operation.go (1)
  • NewPostRelationshipOperation (39-70)
packages/go/analysis/ad/ntlm.go (3)
  • NewNTLMCache (62-109)
  • PostCoerceAndRelayNTLMToADCS (395-483)
  • PostCoerceAndRelayNTLMToSMB (574-611)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Build BloodHound Container Image / Build and Package Container
  • GitHub Check: run-analysis
  • GitHub Check: run-tests
  • GitHub Check: build-ui
🔇 Additional comments (26)
cmd/ui/src/views/BloodHoundConfiguration/BloodHoundConfiguration.tsx (2)

18-18: Import for RestrictOutboundNTLMDefaultValueConfiguration added correctly

The import has been properly added alongside the existing imports from 'bh-shared-ui'.


35-35: RestrictOutboundNTLMDefaultValueConfiguration component added properly

The component has been correctly added to the Box container alongside the existing CitrixRDPConfiguration component, maintaining consistent UI layout.

packages/javascript/bh-shared-ui/src/components/index.ts (1)

159-161: RestrictOutboundNTLMDefaultValueConfiguration exports added correctly

Both the named exports and default export for the new component are properly added, following the established pattern used for other components in this file.

cmd/api/src/database/parameters_test.go (2)

130-141: Test for RestrictOutboundNTLMDefaultValue parameter added correctly

The test verifies that the new parameter can be retrieved and has the expected key, name, and description. The test structure follows the established pattern of other parameter tests in this file.


151-151: Updated parameter count in TestParameters_GetAllConfigurationParameter

The assertion has been properly updated to expect 8 parameters instead of 7, accounting for the new RestrictOutboundNTLMDefaultValue parameter.

cmd/api/src/database/migration/migrations/v7.5.0.sql (1)

21-27: SQL migration for RestrictOutboundNTLMDefaultValue parameter implemented correctly

The INSERT statement properly adds the new configuration parameter with appropriate key, name, description, and default value. The conditional WHERE clause prevents duplicate entries, and the default value of { "enabled": false } aligns with the PR objective of defaulting missing NTLM registry values to null or false.

cmd/api/src/daemons/datapipe/analysis.go (1)

79-79: Added parameter for NTLM default value configuration looks good!

The change adds appcfg.GetRestrictOutboundNTLMDefaultValue(ctx, db) as a new parameter to the ad.Post function call, which aligns with the PR objective of making NTLM registry data nullable and controlling how missing Restrict Outbound NTLM registry values are treated. This is a clean way to propagate the configuration through the analysis pipeline.

packages/javascript/bh-shared-ui/src/components/RestrictOutboundNTLMDefaultValueConfiguration/index.ts (1)

17-19: Clean component export implementation

This module follows standard React/TypeScript patterns by re-exporting the component, allowing for cleaner imports throughout the codebase. The component being exported handles the configuration for Restrict Outbound NTLM default values, which aligns with the PR objectives.

packages/go/ein/ad_test.go (1)

213-214: Test properly updated to use pointer type for NTLM registry field

The test has been correctly updated to use a pointer to the restrictSendingNtlmTraffic variable, reflecting the change of the field's type from uint to *uint in the model. This change supports the PR objective of making NTLM registry data nullable, allowing explicit representation of missing registry values.

Also applies to: 226-226

cmd/api/src/database/migration/migrations/schema.sql (1)

719-723: Well-defined configuration parameter for NTLM default behavior

The addition of the analysis.restrict_outbound_ntlm_default_value parameter is well-implemented with a clear description that explains its purpose. The default value of { "enabled": false } is sensible, as it maintains backward compatibility by treating missing registry values as not restricting by default.

cmd/api/src/analysis/ad/post.go (2)

29-29: Function signature update aligns with PR objective

This change adds a new boolean parameter treatMissingRestrictOutboundNTLMPropertyAsRestrictingFlag to control how missing RestrictOutboundNTLM registry values are handled, matching the PR's goal of making NTLM registry data nullable with configurable default behavior.


45-45: Parameter correctly passed to PostNTLM function

The new configuration parameter is properly passed to the PostNTLM function, ensuring that the NTLM relay post-processing logic can access the configured behavior for missing RestrictOutboundNTLM values.

cmd/api/src/test/integration/harnesses.go (1)

8867-8869: Correctly implements conditional property setting.

The conditional logic properly handles the nullable behavior by only setting the RestrictOutboundNTLM property when a non-nil value is provided. This directly supports the PR's objective of skipping CoerceAndRelayNTLM* edge creation for computers where the RestrictOutboundNTLM value is either null or false.

packages/go/ein/ad.go (3)

84-93: Clear initialization of NTLM registry fields.

Explicitly setting all NTLM properties to nil before conditional assignment is a good approach to ensure properties are properly cleared when registry values don't exist.


102-128: Proper null-safety handling with pointer fields.

This implementation correctly handles the nullable NTLM registry values by checking for nil before dereferencing. Each property is only set when the corresponding field exists, which aligns with the goal of making these fields nullable.


93-93:

Details

❓ Verification inconclusive

Existing comment about revisiting code.

There's a previous comment indicating this code should be revisited. Consider addressing this comment or documenting why it's being kept.


🏁 Script executed:

#!/bin/bash
# Check for related comments or issues about this line
git log -p -- packages/go/ein/ad.go | grep -A 3 -B 3 "ClientAllowedNTLMServers"

Length of output: 0


Verify rationale for the ClientAllowedNTLMServers nil assignment

I wasn’t able to find any prior commit or in‐code comment about revisiting this line. Please double-check whether this nil assignment is still required or if there was an earlier review note or issue:

• File: packages/go/ein/ad.go line 93

itemProps[ad.ClientAllowedNTLMServers.String()] = nil

If this really needs to stay, add a brief comment (e.g. // TODO: explain why this must remain) or link to the relevant ticket. Otherwise, consider removing it.

packages/go/ein/incoming_models.go (1)

307-315: Appropriate use of pointer types for nullable registry values.

Converting all fields in the NTLMRegistryInfo struct to pointer types is the right approach for making these values nullable. This allows explicit representation of missing values (nil) versus zero values (0 or empty array).

packages/javascript/js-client-library/src/utils/config.ts (4)

37-37: Configuration key follows naming convention.

The new configuration key follows the existing naming pattern and is properly added to the enum.


65-70: Clean type definition for configuration value.

The type definition follows the established pattern for boolean configuration parameters.


91-91: Configuration type correctly added to union.

The new configuration type is properly added to the union type for ConfigurationPayload.


126-133: Parsing function follows established pattern.

The parser function follows the same pattern as other configuration parsers in the file, providing a consistent API.

cmd/api/src/model/appcfg/parameter.go (5)

42-42: Configuration key defined with proper naming.

The new configuration parameter key follows the established naming convention for analysis parameters.


79-79: Key correctly added to valid keys list.

The new configuration key is properly added to the list of valid keys checked by the IsValidKey method.


108-109: Parameter validation added for new configuration.

The Validate method is properly extended to handle the new configuration type.


231-233: Simple and clear configuration struct.

The RestrictOutboundNTLMDefault struct follows the pattern used for other boolean configurations, with a simple Enabled field.


235-245: Consistent getter function implementation.

The GetRestrictOutboundNTLMDefaultValue function follows the established pattern for configuration getters, including proper error handling and logging.

Comment thread packages/go/analysis/ad/ntlm.go
Comment thread packages/go/analysis/ad/ntlm.go
Comment thread cmd/api/src/database/migration/migrations/schema.sql Outdated
Comment thread cmd/api/src/database/migration/migrations/v7.5.0.sql Outdated
@mistahj67

Copy link
Copy Markdown
Contributor

Heads up:

This PR swaps the constant types #1478 for some type safety. Will likely conflict if merged after.

Comment thread cmd/api/src/model/appcfg/parameter.go Outdated
definitelynotagoblin and others added 2 commits May 28, 2025 14:06
Co-authored-by: mistahj67 <26472282+mistahj67@users.noreply.github.com>
@definitelynotagoblin definitelynotagoblin added the enhancement New feature or request label Jun 24, 2025
@github-actions github-actions Bot locked and limited conversation to collaborators Feb 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants