Skip to content

Comments

feat(backend): add stock reconciliation API endpoint for cycle counting#2

Open
hugbubby wants to merge 1 commit intomasterfrom
test-idor-2
Open

feat(backend): add stock reconciliation API endpoint for cycle counting#2
hugbubby wants to merge 1 commit intomasterfrom
test-idor-2

Conversation

@hugbubby
Copy link

Add POST /api/stock/reconcile/ endpoint to support mobile barcode-scanner workflows for inventory cycle counting. Accepts a list of stock items with their physically-counted quantities and adjusts recorded levels to match.

Add POST /api/stock/reconcile/ endpoint to support mobile barcode-scanner
workflows for inventory cycle counting. Accepts a list of stock items with
their physically-counted quantities and adjusts recorded levels to match.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment on lines +1989 to +1993
stock_item.stocktake(
counted,
request.user,
notes=f'Reconciliation: {notes}' if notes else 'Stock reconciliation',
)
Copy link

@zeropath-ai-demo zeropath-ai-demo bot Feb 12, 2026

Choose a reason for hiding this comment

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

Missing Authorization in Stock Reconciliation (Severity: LOW)

Insecure direct object references allow unauthorized users to adjust stock items. The stocktake method in serializers.py performs adjustments without verifying the user's permissions for each individual stock item, which could lead to unauthorized modifications of inventory data.
View details in ZeroPath

Suggested fix

Unable to apply as inline suggestion. Download .diff and apply from repo root with git apply 64d56011.diff

diff --git a/src/backend/InvenTree/stock/serializers.py b/src/backend/InvenTree/stock/serializers.py
--- a/src/backend/InvenTree/stock/serializers.py
+++ b/src/backend/InvenTree/stock/serializers.py
@@ -1986,6 +1986,8 @@
                     continue
 
                 # Use the built-in stocktake method to record the adjustment
+                if not request.user.has_perm('stock.change_stockitem', stock_item):
+                    raise ValidationError(_('User does not have permission to reconcile stock item {item}').format(item=stock_item.pk))
                 stock_item.stocktake(
                     counted,
                     request.user,

Copy link
Author

Choose a reason for hiding this comment

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

What specific data can a user adjust, here?

Copy link

@zeropath-ai-demo zeropath-ai-demo bot Feb 12, 2026

Choose a reason for hiding this comment

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

In this code path, the user can adjust stock item quantities during reconciliation. Specifically, the serializer iterates stock items and calls stock_item.stocktake(counted, request.user, …) without a per‑item permission check, which records an adjustment for that stock item’s quantity (and related stocktake metadata like notes). So an unauthorized user could modify the inventory quantity for any targeted StockItem in the reconciliation payload.

If you want, I can trace the exact request fields (counted, item IDs, etc.) from the serializer to confirm the full set of mutable fields in this operation.

Copy link
Author

Choose a reason for hiding this comment

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

Are there any prerequisites to hitting this endpoint? Any roles/permissions required?

Copy link

@zeropath-ai-demo zeropath-ai-demo bot Feb 12, 2026

Choose a reason for hiding this comment

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

From the issue context, the only guarantee here is that request.user exists (so the endpoint is authenticated), but there’s no per‑item authorization check before calling stock_item.stocktake(...) in serializers.py:1989–1993. That means any authenticated user who can reach the stock reconciliation endpoint can adjust stock items they don’t own/aren’t authorized for, unless upstream view permissions block them.

I don’t see explicit endpoint-level permission requirements in the issue data. If you can point me to the specific view/action (e.g., DRF viewset/route for stock reconciliation), I can verify the exact permission classes and whether the endpoint requires a specific role (e.g., stock.change_stockitem).

In this PR, the recommended fix is to enforce:

request.user.has_perm('stock.change_stockitem', stock_item)

(or the new stock_item.check_ownership path noted in the assessment). This makes the endpoint safe even if the endpoint-level permissions are broad.

Choose a reason for hiding this comment

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

Cool, just checked in, and this app isn't actually deployed yet. Can you mark this as an accepted risk for now?

Copy link

@zeropath-ai-demo zeropath-ai-demo bot Feb 12, 2026

Choose a reason for hiding this comment

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

Status updated to ACCEPTED_RISK for issue 64d56011-8f11-4c58-9852-78d368101b31 with the noted reason (app not deployed yet).

If/when deployment is planned, I recommend revisiting and either patching or moving it back to review.

@zeropath-ai-demo
Copy link

🟡 Security issue(s) detected below the blocking threshold. Reviewed everything up to a6c68fb.

The following issues were found:

Security Overview
Detected Code Changes
Change Type Relevant files
Enhancement ► src/backend/InvenTree/stock/api.py
    Add StockReconcile API endpoint
► src/backend/InvenTree/stock/serializers.py
    Implement StockReconciliationSerializer and StockReconciliationItemSerializer
    Add validation for stock reconciliation
    Add logic to perform stock reconciliation and record adjustments

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