Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/list-app-federated-identity-credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func listAppFICs(ctx context.Context, client client.AzureClient, apps <-chan azu
for item := range client.ListAzureADAppFICs(ctx, app.Data.Id, params) {
if item.Error != nil {
log.Error(item.Error, "unable to continue processing federated identity credentials for this app", "appId", app.Data.AppId)
} else {
} else {
appFIC := models.AppFIC{
FIC: item.Ok,
AppId: app.Data.AppId,
Expand All @@ -95,7 +95,7 @@ func listAppFICs(ctx context.Context, client client.AzureClient, apps <-chan azu
}
}

if data.FICs != nil {
if data.FICs != nil {
if ok := pipeline.Send(ctx.Done(), out, NewAzureWrapper(
enums.KindAZFederatedIdentityCredential,
data,
Expand Down
12 changes: 6 additions & 6 deletions models/azure/user-signinactivity.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package azure

// SignInActivity represents Microsoft Graph's `signInActivity` object returned on the user entity.
type SignInActivity struct {
LastSignInDateTime *string `json:"lastSignInDateTime,omitempty"`
LastSignInRequestId *string `json:"lastSignInRequestId,omitempty"`
LastNonInteractiveSignInDateTime *string `json:"lastNonInteractiveSignInDateTime,omitempty"`
LastNonInteractiveSignInRequestId *string `json:"lastNonInteractiveSignInRequestId,omitempty"`
LastSuccessfulSignInDateTime *string `json:"lastSuccessfulSignInDateTime,omitempty"`
LastSuccessfulSignInRequestId *string `json:"lastSuccessfulSignInRequestId,omitempty"`
LastSignInDateTime string `json:"lastSignInDateTime,omitempty"`
LastSignInRequestId string `json:"lastSignInRequestId,omitempty"`
LastNonInteractiveSignInDateTime string `json:"lastNonInteractiveSignInDateTime,omitempty"`
LastNonInteractiveSignInRequestId string `json:"lastNonInteractiveSignInRequestId,omitempty"`
LastSuccessfulSignInDateTime string `json:"lastSuccessfulSignInDateTime,omitempty"`
LastSuccessfulSignInRequestId string `json:"lastSuccessfulSignInRequestId,omitempty"`
}
Comment on lines 4 to 11
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for SignInActivity usages and potential nil checks

echo "=== Finding all SignInActivity usages in Go files ==="
rg -n 'SignInActivity' --type go -B 2 -A 5

echo ""
echo "=== Searching for potential nil checks on these fields ==="
rg -n '(LastSignInDateTime|LastSignInRequestId|LastNonInteractiveSignInDateTime|LastNonInteractiveSignInRequestId|LastSuccessfulSignInDateTime|LastSuccessfulSignInRequestId)\s*(!= nil|== nil|\*\.|\&)' --type go -B 2 -A 2

echo ""
echo "=== Looking for SignInActivity struct definition and file context ==="
fd 'user-signinactivity.go' --type f | xargs cat -n

echo ""
echo "=== Checking for json.Unmarshal patterns with SignInActivity ==="
rg -n 'Unmarshal.*SignInActivity\|SignInActivity.*Unmarshal' --type go -B 3 -A 3

Repository: SpecterOps/AzureHound

Length of output: 4062


🏁 Script executed:

# Read the test file to confirm the pointer dereference issue
cat -n models/azure/user_test.go | sed -n '23,50p'

Repository: SpecterOps/AzureHound

Length of output: 1127


Test file will not compile: pointer dereferences incompatible with string fields.

The change from *string to string fields breaks test code at models/azure/user_test.go:44-45, which attempts to dereference LastSuccessfulSignInDateTime:

if *u.SignInActivity.LastSuccessfulSignInDateTime != "2025-01-27T22:20:22Z" {

This will fail to compile because string values cannot be dereferenced. Additionally, the semantic change remains: null values from the API (as shown in the test's JSON payload on lines 32-33) will now unmarshal to empty strings instead of nil, affecting how missing sign-in activity is distinguished from explicitly empty values.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@models/azure/user-signinactivity.go` around lines 4 - 11, The SignInActivity
struct fields were changed from *string to string, breaking code that
dereferences pointers (e.g., user_test.go expects
u.SignInActivity.LastSuccessfulSignInDateTime to be a *string) and changing
null-vs-empty semantics; revert the fields in SignInActivity
(LastSignInDateTime, LastSignInRequestId, LastNonInteractiveSignInDateTime,
LastNonInteractiveSignInRequestId, LastSuccessfulSignInDateTime,
LastSuccessfulSignInRequestId) back to *string so tests and JSON null handling
work as before and update any callers only if you intentionally want to change
semantics.

4 changes: 2 additions & 2 deletions models/azure/user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestUserUnmarshal_PopulatesLastSuccessfulSignInDateTimeFromSignInActivity(t
t.Fatalf("unexpected unmarshal error: %v", err)
}

if *u.SignInActivity.LastSuccessfulSignInDateTime != "2025-01-27T22:20:22Z" {
t.Fatalf("expected LastSuccessfulSignInDateTime to be populated, got %q", *u.SignInActivity.LastSuccessfulSignInDateTime)
if u.SignInActivity.LastSuccessfulSignInDateTime != "2025-01-27T22:20:22Z" {
t.Fatalf("expected LastSuccessfulSignInDateTime to be populated, got %q", u.SignInActivity.LastSuccessfulSignInDateTime)
}
}
Loading