F-2025-0001·access-control

Missing access control in setSubscription enables vault hijacking and revenue theft

Fixednfterc721erc20
TL;DR

The setSubscription function lacks ownership validation, letting any address create or overwrite subscription offerings for vault IDs they do not own and bypass the creator's intended monetization.

Severity
CRITICAL
Impact
HIGH
Likelihood
HIGH
Method
MManual review
CAT.
Complexity
LOW
Exploitability
HIGH
02Section · Description

Description

The setSubscription function lacks access control validation, allowing any address to create subscription offerings for vault IDs they do not own. The function only validates input parameters but does not verify that msg.sender has legitimate ownership or control over the specified vaultId.

Vulnerable Scenario:

The following steps help understand the issue:

  1. Alice creates a knowledge vault "alice-blockchain-course" on the IPAL platform and hosts content off-chain.
  2. Bob monitors the platform and identifies Alice's popular vault ID.
  3. Bob calls setSubscription("alice-blockchain-course", 0, 0, "", address(0), 0) directly on the smart contract.
  4. Bob's subscription offering makes Alice's private vault public without her consent.
  5. Users can now access Alice's premium content for free, bypassing her intended monetization.
03Section · Impact

Impact

  • A non-owner could change the price or duration of a vault's subscription, potentially setting it to zero and making private content public without the owner's consent, or altering the terms of access.
  • This would directly contradict the stated goal of the IPAL platform, which aims to create a decentralized marketplace where creators maintain control over their knowledge assets and enable content creators to monetize their knowledge.
04Section · Recommendation

Recommendation

  1. Implement a vault ownership registry that maps vault IDs to their legitimate owners.
  2. Add access control validation in setSubscription to verify the caller owns the vault.
solidity
// Recommended fix
mapping(string => address) public vaultOwners;
function registerVault(string calldata vaultId) external {
require(vaultOwners[vaultId] == address(0), "Vault already registered");
vaultOwners[vaultId] = msg.sender;
}
function setSubscription(string calldata vaultId, ...) external {
require(vaultOwners[vaultId] == msg.sender, "Not vault owner");
// ... rest of function
}
05Section · Resolution

Resolution

Ipal Network: Confirmed. The issue has been resolved by implementing a vault ownership registry and adding the necessary access control validation to the setSubscription function to prevent unauthorized modifications.

Zealynx: Fixed. Added proper access control with vault ownership registry and validation in setSubscription function, preventing unauthorized vault hijacking.

Status
Fixed
F-2025-0001

oog
zealynx

Smart Contract Security Digest

Monthly exploit breakdowns, audit checklists, and DeFi security research — straight to your inbox

© 2026 Zealynx