<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Possible Vulnerabilities :: Unofficial EVE Frontier Development Notes</title>
    <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/index.html</link>
    <description>This section documents 34 vulnerability classes commonly found in Sui Move smart contracts. Each vulnerability has its own dedicated page with detailed explanations, vulnerable code examples, and recommended mitigations.&#xA;Overview Sui Move contracts face unique security challenges due to the object-centric model, capability-based access control, and programmable transaction blocks (PTBs). Understanding these vulnerabilities is essential for writing secure smart contracts.</description>
    <generator>Hugo</generator>
    <language>en-US</language>
    <lastBuildDate>Wed, 26 Nov 2025 21:46:35 +0000</lastBuildDate>
    <atom:link href="https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>1. Object Transfer Misuse</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/object-transfer-misuse/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/object-transfer-misuse/index.html</guid>
      <description>Overview Any address-owned object with key (especially combined with store) can be freely transferred using sui::transfer::transfer or public_transfer. This breaks assumptions about invariants, capability possession, and ownership that your contract may depend on.&#xA;Risk Level High — Can lead to complete bypass of access control mechanisms.</description>
    </item>
    <item>
      <title>2. Object Freezing Misuse</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/object-freezing-misuse/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/object-freezing-misuse/index.html</guid>
      <description>Overview Objects with key + store abilities can be frozen by any holder using sui::transfer::public_freeze_object. Once frozen, an object becomes immutable and globally readable. This can be exploited to permanently disable critical protocol functionality or expose sensitive data.&#xA;Risk Level High — Can permanently break protocol functionality with no recovery path.</description>
    </item>
    <item>
      <title>3. Numeric / Bitwise Pitfalls</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/numeric-bitwise-pitfalls/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/numeric-bitwise-pitfalls/index.html</guid>
      <description>Overview Move’s numeric and bitwise operations have specific semantics that differ from other languages. Arithmetic operations abort on overflow/underflow (rather than wrapping), while bitwise shifts beyond the type width silently produce zero. These behaviors can lead to unexpected results and security vulnerabilities.&#xA;Risk Level Medium to High — Can cause denial of service or bypass access control checks.</description>
    </item>
    <item>
      <title>4. Ability Misconfiguration</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/ability-misconfiguration/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/ability-misconfiguration/index.html</guid>
      <description>Overview Move’s four abilities (copy, drop, store, key) control what operations can be performed on types. Misconfiguring these abilities can allow duplication of assets, unintended destruction of resources, wrapping of objects, or unauthorized global storage access.&#xA;Risk Level Critical — Incorrect abilities can break fundamental economic invariants.</description>
    </item>
    <item>
      <title>5. Access-Control Mistakes</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/access-control-mistakes/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/access-control-mistakes/index.html</guid>
      <description>Overview Access control mistakes occur when authorization checks are missing, incorrectly implemented, or rely on wrong assumptions about TxContext::sender(). These vulnerabilities allow unauthorized users to perform privileged operations.&#xA;Risk Level Critical — Direct path to unauthorized access and fund theft.&#xA;OWASP / CWE Mapping OWASP Top 10 MITRE CWE A01 (Broken Access Control) CWE-285 (Improper Authorization), CWE-639 (Authorization Bypass) The Problem Common Access Control Mistakes Missing authorization checks — Functions accessible to anyone Checking wrong sender — Confusing gas sponsor with transaction sender Hardcoded addresses — Addresses that cannot be updated or rotated Race conditions — Authorization state changes between check and use Inconsistent models — Mixing capability-based and address-based checks Vulnerable Example module vulnerable::vault { use sui::object::{Self, UID}; use sui::tx_context::{Self, TxContext}; use sui::coin::{Self, Coin}; use sui::sui::SUI; use sui::transfer; const ADMIN: address = @0xDEADBEEF; public struct Vault has key { id: UID, funds: Coin&lt;SUI&gt;, admin: address, } public struct AdminCap has key, store { id: UID, } /// VULNERABLE: No access control at all! public entry fun withdraw_all( vault: &amp;mut Vault, ctx: &amp;mut TxContext ) { let amount = coin::value(&amp;vault.funds); let withdrawn = coin::split(&amp;mut vault.funds, amount, ctx); transfer::public_transfer(withdrawn, tx_context::sender(ctx)); } /// VULNERABLE: Hardcoded address cannot be updated public entry fun emergency_withdraw( vault: &amp;mut Vault, ctx: &amp;mut TxContext ) { // What if ADMIN key is compromised? No way to rotate! assert!(tx_context::sender(ctx) == ADMIN, E_NOT_ADMIN); // ... withdraw logic } /// VULNERABLE: Checks sender but ignores capability public entry fun update_admin( vault: &amp;mut Vault, _cap: &amp;AdminCap, // Cap is ignored! new_admin: address, ctx: &amp;mut TxContext ) { // This checks sender even though cap is passed // If cap was transferred, wrong person might have access assert!(tx_context::sender(ctx) == vault.admin, E_NOT_ADMIN); vault.admin = new_admin; } /// VULNERABLE: Time-of-check to time-of-use issue public entry fun conditional_withdraw( vault: &amp;mut Vault, amount: u64, ctx: &amp;mut TxContext ) { let sender = tx_context::sender(ctx); // Check is performed... assert!(is_authorized(sender), E_NOT_AUTHORIZED); // ...but in a PTB, authorization might change before this executes let withdrawn = coin::split(&amp;mut vault.funds, amount, ctx); transfer::public_transfer(withdrawn, sender); } } Secure Example module secure::vault { use sui::object::{Self, UID}; use sui::tx_context::{Self, TxContext}; use sui::coin::{Self, Coin}; use sui::sui::SUI; use sui::transfer; use sui::event; const E_NOT_ADMIN: u64 = 0; const E_ZERO_AMOUNT: u64 = 1; const E_INSUFFICIENT_FUNDS: u64 = 2; /// SECURE: No `store` — only this module controls the cap public struct AdminCap has key { id: UID, vault_id: ID, // Tied to specific vault } public struct Vault has key { id: UID, funds: Coin&lt;SUI&gt;, } public struct WithdrawEvent has copy, drop { vault_id: ID, amount: u64, recipient: address, } fun init(ctx: &amp;mut TxContext) { let vault = Vault { id: object::new(ctx), funds: coin::zero(ctx), }; let vault_id = object::id(&amp;vault); // Create admin cap tied to this vault let admin_cap = AdminCap { id: object::new(ctx), vault_id, }; transfer::share_object(vault); transfer::transfer(admin_cap, tx_context::sender(ctx)); } /// SECURE: Capability-based access control public entry fun withdraw( cap: &amp;AdminCap, vault: &amp;mut Vault, amount: u64, recipient: address, ctx: &amp;mut TxContext ) { // Verify cap is for this vault assert!(cap.vault_id == object::id(vault), E_NOT_ADMIN); assert!(amount &gt; 0, E_ZERO_AMOUNT); assert!(coin::value(&amp;vault.funds) &gt;= amount, E_INSUFFICIENT_FUNDS); let withdrawn = coin::split(&amp;mut vault.funds, amount, ctx); event::emit(WithdrawEvent { vault_id: object::id(vault), amount, recipient, }); transfer::public_transfer(withdrawn, recipient); } /// SECURE: Explicit admin transfer with cap consumption public entry fun transfer_admin( cap: AdminCap, new_admin: address, ctx: &amp;mut TxContext ) { // Old cap is consumed, new one is created let AdminCap { id, vault_id } = cap; object::delete(id); transfer::transfer( AdminCap { id: object::new(ctx), vault_id, }, new_admin ); } /// SECURE: Multi-sig pattern for critical operations public struct MultiSigProposal has key { id: UID, action: vector&lt;u8&gt;, approvals: vector&lt;address&gt;, threshold: u64, vault_id: ID, } public entry fun approve_and_execute( proposal: &amp;mut MultiSigProposal, cap: &amp;AdminCap, ctx: &amp;TxContext ) { let sender = tx_context::sender(ctx); // Add approval if not already present if (!vector::contains(&amp;proposal.approvals, &amp;sender)) { vector::push_back(&amp;mut proposal.approvals, sender); }; // Execute if threshold reached if (vector::length(&amp;proposal.approvals) &gt;= proposal.threshold) { // ... execute action } } } Access Control Patterns Pattern 1: Pure Capability-Based /// Best for most cases — clear, composable public entry fun admin_action(cap: &amp;AdminCap, ...) { // Whoever holds the cap can perform the action // No sender checks needed } Pattern 2: Capability + Sender Verification /// For soul-bound capabilities public struct SoulBoundCap has key { id: UID, owner: address, } public entry fun action(cap: &amp;SoulBoundCap, ctx: &amp;TxContext) { assert!(tx_context::sender(ctx) == cap.owner, E_NOT_OWNER); // Both cap possession AND sender match required } Pattern 3: Role-Based Access public struct RoleRegistry has key { id: UID, admins: vector&lt;address&gt;, operators: vector&lt;address&gt;, } public fun is_admin(registry: &amp;RoleRegistry, addr: address): bool { vector::contains(&amp;registry.admins, &amp;addr) } public entry fun admin_action( registry: &amp;RoleRegistry, ctx: &amp;TxContext ) { assert!(is_admin(registry, tx_context::sender(ctx)), E_NOT_ADMIN); } Pattern 4: Time-Locked Operations public struct TimeLock has key { id: UID, operation: vector&lt;u8&gt;, execute_after: u64, } public entry fun execute_timelock( lock: TimeLock, clock: &amp;Clock, ) { assert!(clock::timestamp_ms(clock) &gt;= lock.execute_after, E_TOO_EARLY); let TimeLock { id, operation, execute_after: _ } = lock; object::delete(id); // ... execute operation } Recommended Mitigations 1. Choose One Authorization Model // GOOD: Consistent capability-based public entry fun action1(cap: &amp;AdminCap, ...) { } public entry fun action2(cap: &amp;AdminCap, ...) { } public entry fun action3(cap: &amp;AdminCap, ...) { } // BAD: Mixed models public entry fun action1(cap: &amp;AdminCap, ...) { } public entry fun action2(ctx: &amp;TxContext) { // sender check assert!(sender(ctx) == ADMIN, 0); } 2. Tie Capabilities to Resources public struct VaultCap has key { id: UID, vault_id: ID, // Can only control this specific vault } 3. Implement Emergency Procedures public struct EmergencyConfig has key { id: UID, guardians: vector&lt;address&gt;, pause_threshold: u64, } public entry fun emergency_pause( config: &amp;EmergencyConfig, signatures: vector&lt;vector&lt;u8&gt;&gt;, // ... verify multi-sig ) { } Testing Checklist Every state-modifying function has explicit access control No hardcoded addresses without upgrade path Capabilities are tied to specific resources where appropriate No mixing of authorization models Emergency procedures exist for key rotation All access control paths are tested with unauthorized callers Related Vulnerabilities Object Transfer Misuse Sponsored Transaction Pitfalls Capability Leakage</description>
    </item>
    <item>
      <title>6. Shared Object DoS</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/shared-object-dos/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/shared-object-dos/index.html</guid>
      <description>Overview Shared objects in Sui can be mutated by any transaction, leading to contention when many actors try to modify the same object simultaneously. This can cause performance degradation or complete denial of service (DoS) for protocols that rely heavily on shared state.&#xA;Risk Level High — Can make protocols unusable during high-demand periods.</description>
    </item>
    <item>
      <title>7. Improper Object Sharing</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/improper-object-sharing/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/improper-object-sharing/index.html</guid>
      <description>Overview Accidentally exposing objects as shared via transfer::share_object enables global mutation by anyone. Once an object is shared, it cannot be unshared — this is a permanent, irreversible change to the object’s ownership model.&#xA;Risk Level High — Shared objects are accessible to all, potentially exposing sensitive operations.</description>
    </item>
    <item>
      <title>8. Dynamic Field Misuse</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/dynamic-field-misuse/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/dynamic-field-misuse/index.html</guid>
      <description>Overview Dynamic fields and child objects in Sui allow flexible, runtime-determined storage attached to objects. Incorrect usage leads to unbounded growth, key collisions, invariant violations, and data corruption.&#xA;Risk Level High — Can cause state corruption, gas exhaustion, or security bypasses.&#xA;OWASP / CWE Mapping OWASP Top 10 MITRE CWE A01 (Broken Access Control), A05 (Security Misconfiguration) CWE-710 (Improper Adherence to Coding Standards), CWE-915 (Improperly Controlled Modification of Dynamically-Determined Object Attributes) The Problem Dynamic Fields vs Regular Fields Aspect Regular Fields Dynamic Fields Defined at Compile time Runtime Type safety Full Partial (key type determines value type) Enumeration Yes No (must know keys) Growth Fixed Unbounded Common Mistakes Unbounded growth — No limit on dynamic field additions Key collisions — User-controlled keys overwrite existing data Type confusion — Same key used for different value types Orphaned data — Parent deleted without removing dynamic fields Access control bypass — Dynamic fields circumvent intended restrictions Vulnerable Example module vulnerable::inventory { use sui::object::{Self, UID}; use sui::tx_context::TxContext; use sui::dynamic_field as df; public struct Inventory has key { id: UID, owner: address, } public struct Item has store { name: vector&lt;u8&gt;, value: u64, } /// VULNERABLE: User-controlled key allows overwriting public entry fun add_item( inventory: &amp;mut Inventory, item_name: vector&lt;u8&gt;, // User-controlled key! value: u64, ctx: &amp;mut TxContext ) { // Attacker can overwrite existing items! df::add(&amp;mut inventory.id, item_name, Item { name: item_name, value }); } /// VULNERABLE: No ownership check for item modification public entry fun update_item_value( inventory: &amp;mut Inventory, item_name: vector&lt;u8&gt;, new_value: u64, ) { // Anyone can modify any item if they know the key let item: &amp;mut Item = df::borrow_mut(&amp;mut inventory.id, item_name); item.value = new_value; } /// VULNERABLE: No limit on items — gas exhaustion attack public entry fun bulk_add( inventory: &amp;mut Inventory, count: u64, ctx: &amp;mut TxContext ) { let i = 0; while (i &lt; count) { let key = i; // Sequential keys df::add(&amp;mut inventory.id, key, Item { name: b&#34;spam&#34;, value: 0 }); i = i + 1; } // Inventory now has unbounded number of items } } module vulnerable::storage { use sui::dynamic_field as df; use sui::dynamic_object_field as dof; public struct Container has key { id: UID, } /// VULNERABLE: Same key used for different types public entry fun store_string( container: &amp;mut Container, key: vector&lt;u8&gt;, value: vector&lt;u8&gt;, ) { df::add(&amp;mut container.id, key, value); } public entry fun store_number( container: &amp;mut Container, key: vector&lt;u8&gt;, value: u64, ) { // If key already exists with string value, this will fail // OR worse — type confusion if not properly checked df::add(&amp;mut container.id, key, value); } } Attack Scenarios Key Collision Attack:</description>
    </item>
    <item>
      <title>9. Sponsored Transaction Pitfalls</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/sponsored-transaction-pitfalls/index.html</link>
      <pubDate>Wed, 26 Nov 2025 20:07:13 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/sponsored-transaction-pitfalls/index.html</guid>
      <description>Overview Sui supports sponsored transactions where one account pays gas fees for another account’s transaction. Confusing the gas sponsor with the transaction sender can lead to impersonation attacks, unauthorized actions, and broken access control.&#xA;Risk Level High — Can lead to complete access control bypass and impersonation.</description>
    </item>
    <item>
      <title>10. General Move Logic Errors</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/general-move-logic-errors/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/general-move-logic-errors/index.html</guid>
      <description>Overview General logic errors in Move contracts include PTB (Programmable Transaction Block) reordering effects, incorrect mutation order, fee miscalculations, and state inconsistencies. These bugs are often subtle and can lead to fund loss or protocol manipulation.&#xA;Risk Level Medium to Critical — Varies based on the specific logic error.</description>
    </item>
    <item>
      <title>11. Capability Leakage</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/capability-leakage/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/capability-leakage/index.html</guid>
      <description>Overview Capability leakage occurs when authority-granting objects (capabilities) are unintentionally exposed through return values, public functions, or parent struct access. Once a capability leaks, unauthorized parties can perform privileged operations.&#xA;Risk Level Critical — Direct path to unauthorized privileged access.&#xA;OWASP / CWE Mapping OWASP Top 10 MITRE CWE A01 (Broken Access Control) CWE-284 (Improper Access Control), CWE-668 (Exposure of Resource to Wrong Sphere) The Problem How Capabilities Leak Returning capabilities by value — Functions that return capability objects Parent struct exposure — Returning structs containing capability children Public field access — Capabilities stored in accessible fields Dynamic field exposure — Capabilities stored as retrievable dynamic fields Vulnerable Example module vulnerable::protocol { use sui::object::{Self, UID}; use sui::tx_context::TxContext; use sui::dynamic_field as df; public struct AdminCap has key, store { id: UID, } public struct ProtocolState has key { id: UID, admin_cap: AdminCap, // Capability embedded in state! } public struct CapWrapper has key, store { id: UID, cap: AdminCap, } /// VULNERABLE: Returns parent containing capability public fun get_state(state: &amp;mut ProtocolState): ProtocolState { // Caller now has access to admin_cap! *state } /// VULNERABLE: Exposes capability through wrapper public fun get_wrapper(state: &amp;ProtocolState): &amp;CapWrapper { // If wrapper is extractable, cap is leaked &amp;state.wrapper } /// VULNERABLE: Creates accessor that leaks authority public fun borrow_admin_cap(state: &amp;ProtocolState): &amp;AdminCap { // Even a reference can be used to call admin functions! &amp;state.admin_cap } /// VULNERABLE: Dynamic field stores capability public fun store_cap_in_field( parent: &amp;mut UID, cap: AdminCap, ) { df::add(parent, b&#34;admin&#34;, cap); } /// Anyone who knows the key can retrieve it public fun get_cap_from_field(parent: &amp;mut UID): &amp;AdminCap { df::borrow(parent, b&#34;admin&#34;) } } module vulnerable::treasury { use vulnerable::protocol::AdminCap; /// VULNERABLE: Accepts capability reference /// Anyone who leaked the reference can call this public entry fun drain_treasury( _cap: &amp;AdminCap, treasury: &amp;mut Treasury, ctx: &amp;mut TxContext ) { // No additional checks — trusting the capability let all_funds = treasury.balance; treasury.balance = 0; // ... transfer funds } } Attack Scenario module attack::exploit { use vulnerable::protocol; public entry fun steal_admin( state: &amp;vulnerable::protocol::ProtocolState, treasury: &amp;mut Treasury, ctx: &amp;mut TxContext ) { // Leak the capability reference let cap_ref = protocol::borrow_admin_cap(state); // Use leaked capability to drain treasury vulnerable::treasury::drain_treasury(cap_ref, treasury, ctx); } } Secure Example module secure::protocol { use sui::object::{Self, UID, ID}; use sui::tx_context::{Self, TxContext}; use sui::transfer; /// Capability with no `store` — cannot be wrapped or transferred public struct AdminCap has key { id: UID, protocol_id: ID, authorized_address: address, } /// State does NOT contain capability public struct ProtocolState has key { id: UID, admin_cap_id: ID, // Only stores the ID, not the cap itself treasury_balance: u64, } fun init(ctx: &amp;mut TxContext) { let state = ProtocolState { id: object::new(ctx), admin_cap_id: object::id_from_address(@0x0), // Placeholder treasury_balance: 0, }; let state_id = object::id(&amp;state); let cap = AdminCap { id: object::new(ctx), protocol_id: state_id, authorized_address: tx_context::sender(ctx), }; // Update state with cap ID state.admin_cap_id = object::id(&amp;cap); transfer::share_object(state); transfer::transfer(cap, tx_context::sender(ctx)); } /// SECURE: No capability return — action performed internally public entry fun admin_withdraw( cap: &amp;AdminCap, state: &amp;mut ProtocolState, amount: u64, ctx: &amp;mut TxContext ) { // Verify cap matches this protocol assert!(cap.protocol_id == object::id(state), E_WRONG_PROTOCOL); // Verify caller is authorized holder assert!(tx_context::sender(ctx) == cap.authorized_address, E_NOT_AUTHORIZED); // Perform action directly — no capability exposure assert!(state.treasury_balance &gt;= amount, E_INSUFFICIENT); state.treasury_balance = state.treasury_balance - amount; // ... transfer funds } /// SECURE: View function returns data, not capability public fun get_admin_cap_id(state: &amp;ProtocolState): ID { state.admin_cap_id } /// SECURE: Check authorization without exposing capability public fun is_admin(cap: &amp;AdminCap, state: &amp;ProtocolState): bool { cap.protocol_id == object::id(state) } } Capability Protection Patterns Pattern 1: Action Functions Instead of Capability Exposure /// BAD: Exposes capability public fun get_admin_cap(state: &amp;State): &amp;AdminCap { &amp;state.admin_cap } /// GOOD: Performs action with internal capability public entry fun perform_admin_action( cap: &amp;AdminCap, state: &amp;mut State, action_params: ActionParams, ) { verify_cap(cap, state); // Perform action internally } Pattern 2: Separate Capability Storage /// Capabilities stored separately, not in protocol state public struct CapabilityRegistry has key { id: UID, // Only IDs, not actual capabilities admin_cap_ids: vector&lt;ID&gt;, } /// Capabilities owned by users, not stored centrally public struct AdminCap has key { id: UID, registry_id: ID, } Pattern 3: Witness Pattern for One-Time Auth /// Witness can only be created once (in init) public struct PROTOCOL has drop {} /// Auth checked via witness possession public fun authorized_action&lt;T: drop&gt;( _witness: T, state: &amp;mut State, ) { // Only code with the witness type can call } Pattern 4: Hot Potato for Scoped Authority /// Hot potato — must be consumed in same transaction public struct AdminSession { state_id: ID, action_count: u64, max_actions: u64, } public fun start_admin_session( cap: &amp;AdminCap, state: &amp;State, ): AdminSession { verify_cap(cap, state); AdminSession { state_id: object::id(state), action_count: 0, max_actions: 10, } } public fun admin_action( session: &amp;mut AdminSession, state: &amp;mut State, ) { assert!(session.state_id == object::id(state), E_WRONG_STATE); assert!(session.action_count &lt; session.max_actions, E_MAX_ACTIONS); session.action_count = session.action_count + 1; // Perform action } public fun end_admin_session(session: AdminSession) { let AdminSession { state_id: _, action_count: _, max_actions: _ } = session; // Session consumed } Recommended Mitigations 1. Never Return Capabilities // BAD public fun get_cap(): AdminCap { ... } public fun borrow_cap(): &amp;AdminCap { ... } // GOOD public entry fun use_cap_for_action(cap: &amp;AdminCap, ...) { ... } 2. Remove store from Capabilities /// Without `store`, cap cannot be wrapped or dynamically stored public struct AdminCap has key { id: UID, } 3. Tie Capabilities to Specific Resources public struct VaultAdminCap has key { id: UID, vault_id: ID, // Only valid for this specific vault } 4. Use Capability References, Not Values /// Functions should borrow capabilities, not consume them public entry fun action(cap: &amp;AdminCap, ...) { } // Borrow /// Only transfer functions should consume public entry fun transfer_admin(cap: AdminCap, new_admin: address) { } Testing Checklist Verify no functions return capability objects Confirm no functions return structs containing capabilities Check that capabilities lack store ability Verify capabilities are not stored in dynamic fields accessibly Test that leaked references cannot bypass access control Audit all places where capability references are passed Related Vulnerabilities Object Transfer Misuse Ability Misconfiguration Access-Control Mistakes</description>
    </item>
    <item>
      <title>12. Phantom Type Confusion</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/phantom-type-confusion/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/phantom-type-confusion/index.html</guid>
      <description>Overview Phantom type parameters in Move are type parameters that don’t affect the runtime representation of a struct. Attackers can inject structurally-identical types with different phantom parameters, bypassing type-based security checks.&#xA;Risk Level High — Can bypass type-based access control and asset isolation.</description>
    </item>
    <item>
      <title>13. Unsafe Object ID Usage</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unsafe-object-id-usage/index.html</link>
      <pubDate>Wed, 26 Nov 2025 20:11:50 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unsafe-object-id-usage/index.html</guid>
      <description>Overview Object IDs (object::ID) in Sui are unique identifiers, but using them as stable identity anchors for child objects or in access control can lead to vulnerabilities. Child object IDs can change when objects are unwrapped, rewrapped, or transferred between parents.&#xA;Risk Level Medium — Can lead to authorization bypasses and state inconsistencies.</description>
    </item>
    <item>
      <title>14. Dynamic Field Key Collisions</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/dynamic-field-key-collisions/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/dynamic-field-key-collisions/index.html</guid>
      <description>Overview Dynamic fields in Sui use keys to store and retrieve values. When user-controlled or predictable keys are used, attackers can cause collisions that overwrite existing data, inject malicious values, or break protocol invariants.&#xA;Risk Level High — Can lead to data corruption, asset theft, or protocol takeover.</description>
    </item>
    <item>
      <title>15. Event Design Vulnerabilities</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/event-design-vulnerabilities/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/event-design-vulnerabilities/index.html</guid>
      <description>Overview Events in Sui are the primary mechanism for off-chain systems to observe on-chain state changes. Poor event design leads to missed state changes, ambiguous interpretations, replay vulnerabilities, and off-chain system failures.&#xA;Risk Level Medium — Can cause off-chain desync, incorrect UI state, or indexer failures.</description>
    </item>
    <item>
      <title>16. Unbounded Child Growth</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unbounded-child-growth/index.html</link>
      <pubDate>Wed, 26 Nov 2025 20:16:13 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unbounded-child-growth/index.html</guid>
      <description>Overview Parent objects can accumulate unlimited child objects through dynamic fields or dynamic object fields. This unbounded growth causes gas exhaustion, state bloat, and can make critical operations prohibitively expensive or impossible.&#xA;Risk Level High — Can cause denial of service and gas exhaustion.</description>
    </item>
    <item>
      <title>17. PTB Ordering Issues</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/ptb-ordering-issues/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/ptb-ordering-issues/index.html</guid>
      <description>Overview Programmable Transaction Blocks (PTBs) in Sui allow multiple operations in a single transaction. Attackers can reorder or interleave calls in unexpected ways, bypassing invariants that assume specific execution order.&#xA;Risk Level High — Can bypass access control and break protocol invariants.</description>
    </item>
    <item>
      <title>18. PTB Refund Issues</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/ptb-refund-issues/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/ptb-refund-issues/index.html</guid>
      <description>Overview Improper refund or undo patterns in Programmable Transaction Blocks (PTBs) can leave state inconsistent when partial execution occurs. Write-then-undo patterns are particularly dangerous as they can be exploited.&#xA;Risk Level Medium — Can lead to inconsistent state and protocol manipulation.&#xA;OWASP / CWE Mapping OWASP Top 10 MITRE CWE A04 (Insecure Design) CWE-841 (Improper Enforcement of Behavioral Workflow), CWE-662 (Improper Synchronization) The Problem In PTBs, if a later operation fails, earlier operations are NOT rolled back within custom logic. Sui’s atomicity ensures the transaction fails entirely, but if your code has a “refund” or “undo” function, partial execution becomes possible.</description>
    </item>
    <item>
      <title>19. Ownership Model Confusion</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/ownership-model-confusion/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/ownership-model-confusion/index.html</guid>
      <description>Overview Sui has multiple ownership models: address-owned, shared, immutable, and object-owned (wrapped/child). Incorrect transitions between these models or confusion about which model applies can break invariants and security assumptions.&#xA;Risk Level High — Can lead to complete access control bypass.&#xA;OWASP / CWE Mapping OWASP Top 10 MITRE CWE A01 (Broken Access Control) CWE-284 (Improper Access Control), CWE-266 (Incorrect Privilege Assignment) The Problem Ownership Models Model Created By Access Mutability Reversible Address-owned transfer() Owner only Yes Yes (transfer) Shared share_object() Anyone Yes No Immutable freeze_object() Anyone (read) No No Object-owned transfer_to_object() Parent object Yes Yes Common Confusion Shared → Address-owned — Not possible after sharing Immutable → Mutable — Not possible after freezing Object-owned access — Parent owner doesn’t automatically control child Wrapped objects — UID changes behavior Vulnerable Example module vulnerable::ownership { use sui::object::{Self, UID}; use sui::tx_context::TxContext; use sui::transfer; public struct Vault has key, store { id: UID, balance: u64, owner: address, } public struct VaultController has key { id: UID, } /// VULNERABLE: Attempts to &#34;unshare&#34; an object public entry fun make_private( vault: Vault, // Taking by value from shared object new_owner: address, ) { // This doesn&#39;t work as expected! // Once shared, always shared // This just moves the shared object, it&#39;s still shared transfer::transfer(vault, new_owner); } /// VULNERABLE: Assumes object ownership = child access public entry fun access_child_vault( controller: &amp;VaultController, // Can&#39;t actually access object-owned objects this way // The vault would need to be passed separately ) { // This function signature is fundamentally broken // Object ownership doesn&#39;t give direct access to children } /// VULNERABLE: Wrong ownership transition public entry fun setup_vault( ctx: &amp;mut TxContext ) { let vault = Vault { id: object::new(ctx), balance: 1000, owner: tx_context::sender(ctx), }; // Bug: sharing when should be transferring to owner // Now anyone can access the vault! transfer::share_object(vault); } /// VULNERABLE: Freezing breaks protocol public entry fun publish_vault( vault: Vault, ) { // Freezing makes it immutable forever // Can never update balance again! transfer::freeze_object(vault); } } Secure Example module secure::ownership { use sui::object::{Self, UID, ID}; use sui::tx_context::{Self, TxContext}; use sui::transfer; use sui::dynamic_object_field as dof; /// Private vault — only owner can access public struct PrivateVault has key { id: UID, balance: u64, } /// Shared pool — anyone can interact (with proper checks) public struct SharedPool has key { id: UID, balance: u64, admin_cap_id: ID, } /// Admin capability — controls the shared pool public struct PoolAdminCap has key { id: UID, pool_id: ID, } /// Published config — immutable by design public struct PublishedConfig has key { id: UID, version: u64, // Only immutable data here fee_bps: u64, name: vector&lt;u8&gt;, } /// SECURE: Clear ownership from the start public entry fun create_private_vault( initial_balance: u64, ctx: &amp;mut TxContext ) { let vault = PrivateVault { id: object::new(ctx), balance: initial_balance, }; // Private — only creator can access transfer::transfer(vault, tx_context::sender(ctx)); } /// SECURE: Shared with proper access control public entry fun create_shared_pool( ctx: &amp;mut TxContext ) { let pool = SharedPool { id: object::new(ctx), balance: 0, admin_cap_id: object::id_from_address(@0x0), // Placeholder }; let pool_id = object::id(&amp;pool); let cap = PoolAdminCap { id: object::new(ctx), pool_id, }; pool.admin_cap_id = object::id(&amp;cap); // Pool is shared, but admin actions require cap transfer::share_object(pool); transfer::transfer(cap, tx_context::sender(ctx)); } /// SECURE: Admin action requires capability public entry fun admin_withdraw( cap: &amp;PoolAdminCap, pool: &amp;mut SharedPool, amount: u64, ctx: &amp;mut TxContext ) { // Verify cap is for this pool assert!(cap.pool_id == object::id(pool), E_WRONG_POOL); pool.balance = pool.balance - amount; // ... transfer } /// SECURE: Published config is intentionally immutable public entry fun publish_config( version: u64, fee_bps: u64, name: vector&lt;u8&gt;, ctx: &amp;mut TxContext ) { let config = PublishedConfig { id: object::new(ctx), version, fee_bps, name, }; // Intentionally immutable — this is the design transfer::freeze_object(config); } /// SECURE: Use dynamic fields for parent-child relationships public struct Parent has key { id: UID, } public struct Child has key, store { id: UID, value: u64, } public entry fun add_child_to_parent( parent: &amp;mut Parent, child: Child, ) { dof::add(&amp;mut parent.id, b&#34;child&#34;, child); } public fun access_child(parent: &amp;Parent): &amp;Child { dof::borrow(&amp;parent.id, b&#34;child&#34;) } public fun access_child_mut(parent: &amp;mut Parent): &amp;mut Child { dof::borrow_mut(&amp;mut parent.id, b&#34;child&#34;) } } Ownership Decision Guide When to Use Address-Owned // User-specific assets public struct UserWallet has key { } // Individual NFTs public struct NFT has key { } // Capabilities (usually) public struct AdminCap has key { } transfer::transfer(obj, owner); When to Use Shared // Global registries public struct Registry has key { } // Liquidity pools public struct Pool has key { } // Order books public struct OrderBook has key { } transfer::share_object(obj); When to Use Immutable // Published configurations public struct Config has key { } // Static data public struct Metadata has key { } // Verified credentials public struct Credential has key { } transfer::freeze_object(obj); When to Use Object-Owned/Dynamic Fields // Parent-child relationships public struct Parent has key { id: UID, // Children via dynamic fields } // Encapsulated components dof::add(&amp;mut parent.id, key, child); Recommended Mitigations 1. Document Ownership Intent /// This object is SHARED because: /// - Multiple users need to interact /// - Admin actions protected by AdminCap /// NEVER attempt to unshare public struct SharedProtocol has key { } 2. Use Type System to Enforce Ownership /// No `store` = cannot be wrapped or transferred publicly public struct MustBeOwned has key { id: UID, } /// Has `store` = can be wrapped in other objects public struct CanBeWrapped has key, store { id: UID, } 3. Validate Ownership Before Operations public entry fun owner_only_action( obj: &amp;mut MyObject, ctx: &amp;TxContext ) { // For address-owned: ownership enforced by Sui // For shared: explicit check required assert!(tx_context::sender(ctx) == obj.owner, E_NOT_OWNER); } 4. Create Clear Ownership Transitions /// Explicit transition from private to shared public entry fun make_shared( obj: PrivateObject, ctx: &amp;TxContext ) { assert!(tx_context::sender(ctx) == obj.owner, E_NOT_OWNER); // Convert to shared form let shared = SharedObject { id: obj.id, data: obj.data, original_owner: obj.owner, }; transfer::share_object(shared); } Testing Checklist Verify ownership model matches intended access pattern Test that shared objects cannot be “unshared” Confirm immutable objects are truly immutable Test parent-child access patterns with dynamic fields Verify ownership transitions are intentional and documented Related Vulnerabilities Object Transfer Misuse Improper Object Sharing Object Freezing Misuse</description>
    </item>
    <item>
      <title>20. Weak Initializers</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/weak-initializers/index.html</link>
      <pubDate>Wed, 26 Nov 2025 20:16:25 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/weak-initializers/index.html</guid>
      <description>Overview Weak or improperly protected initialization functions can allow attackers to reinitialize protocol state, overwrite critical settings, or take control of the protocol. The init function in Sui Move has special protections, but custom initialization patterns often lack similar safeguards.&#xA;Risk Level Critical — Can lead to complete protocol takeover.</description>
    </item>
    <item>
      <title>21. Oracle Validation Failures</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/oracle-validation-failures/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/oracle-validation-failures/index.html</guid>
      <description>Overview Oracle validation failures occur when smart contracts blindly trust off-chain data sources without proper verification. In Sui Move, oracles provide critical data like prices, random numbers, or external state, but improper validation can lead to manipulation, stale data exploitation, or complete protocol compromise.&#xA;Risk Level Critical — Can lead to significant financial losses, especially in DeFi protocols.</description>
    </item>
    <item>
      <title>22. Unsafe Option Authority</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unsafe-option-authority/index.html</link>
      <pubDate>Wed, 26 Nov 2025 20:48:47 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unsafe-option-authority/index.html</guid>
      <description>Overview Unsafe Option authority occurs when developers use Option&lt;T&gt; types to toggle permissions or authority states, creating vulnerabilities where attackers can manipulate authorization by extracting, replacing, or exploiting the optional nature of authority objects. This pattern is particularly dangerous when capabilities or access tokens are wrapped in Option types.&#xA;Risk Level High — Can lead to privilege escalation or unauthorized access.</description>
    </item>
    <item>
      <title>23. Clock Time Misuse</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/clock-time-misuse/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/clock-time-misuse/index.html</guid>
      <description>Overview Clock time misuse occurs when smart contracts improperly use Sui’s Clock object for time-sensitive operations. Unlike traditional blockchains where block timestamps can be manipulated by validators, Sui provides a system Clock object with millisecond precision. However, misusing this clock—through incorrect comparisons, time zone assumptions, or precision errors—can lead to serious vulnerabilities.&#xA;Risk Level High — Can lead to premature unlocks, expired deadlines being bypassed, or time-locked funds becoming inaccessible.</description>
    </item>
    <item>
      <title>24. Transfer API Misuse</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/transfer-api-misuse/index.html</link>
      <pubDate>Wed, 26 Nov 2025 21:02:54 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/transfer-api-misuse/index.html</guid>
      <description>Overview Transfer API misuse occurs when developers incorrectly use Sui’s object transfer functions, leading to objects being sent to wrong addresses, locked permanently, or transferred with incorrect ownership semantics. Sui provides multiple transfer functions (transfer::transfer, transfer::public_transfer, transfer::share_object, transfer::freeze_object) each with specific requirements and behaviors that must be understood.&#xA;Risk Level Critical — Can result in permanent loss of assets or complete protocol failure.</description>
    </item>
    <item>
      <title>25. Unbounded Vector Growth</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unbounded-vector-growth/index.html</link>
      <pubDate>Wed, 26 Nov 2025 21:06:01 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unbounded-vector-growth/index.html</guid>
      <description>Overview Unbounded vector growth occurs when smart contracts allow vectors to grow without limits, leading to gas exhaustion attacks, denial of service, or excessive storage costs. In Sui Move, vectors stored in objects consume gas for both storage and iteration. Attackers can exploit unbounded vectors to make operations prohibitively expensive or cause transactions to fail.&#xA;Risk Level High — Can lead to denial of service or protocol unavailability.</description>
    </item>
    <item>
      <title>26. Upgrade Boundary Errors</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/upgrade-boundary-errors/index.html</link>
      <pubDate>Wed, 26 Nov 2025 21:18:20 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/upgrade-boundary-errors/index.html</guid>
      <description>Overview Upgrade boundary errors occur when package upgrades break compatibility with existing on-chain state, cause ABI mismatches, or violate upgrade policies. Sui Move packages can be upgraded, but upgrades must maintain compatibility with objects created by previous versions. Failing to handle upgrade boundaries correctly can corrupt state, break integrations, or lock funds permanently.&#xA;Risk Level Critical — Can lead to permanent protocol breakage or locked funds.</description>
    </item>
    <item>
      <title>27. Event State Inconsistency</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/event-state-inconsistency/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/event-state-inconsistency/index.html</guid>
      <description>Overview Event state inconsistency occurs when emitted events don’t accurately reflect the actual on-chain state changes. In Sui Move, events are the primary mechanism for off-chain systems (indexers, frontends, analytics) to track what happened on-chain. When events are missing, duplicated, emitted before state changes, or contain incorrect data, off-chain systems build an incorrect view of the protocol state.</description>
    </item>
    <item>
      <title>28. Read API Leakage</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/read-api-leakage/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/read-api-leakage/index.html</guid>
      <description>Overview Read API leakage occurs when view functions or public getters expose sensitive information that should remain private. In Sui Move, while direct state access requires ownership, public functions can inadvertently reveal private keys, internal state, user data, or security-critical information. Attackers can use this leaked information to plan attacks, front-run transactions, or compromise user privacy.</description>
    </item>
    <item>
      <title>29. Unsafe BCS Parsing</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unsafe-bcs-parsing/index.html</link>
      <pubDate>Wed, 26 Nov 2025 21:42:46 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unsafe-bcs-parsing/index.html</guid>
      <description>Overview Unsafe BCS (Binary Canonical Serialization) parsing occurs when smart contracts or off-chain systems improperly deserialize BCS-encoded data, leading to type confusion, buffer overflows, or malformed data acceptance. BCS is Sui’s standard serialization format, used for transaction data, object serialization, and cross-module communication. Improper parsing can lead to security vulnerabilities both on-chain and in off-chain indexers.</description>
    </item>
    <item>
      <title>30. Unsafe Test Patterns</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unsafe-test-patterns/index.html</link>
      <pubDate>Wed, 26 Nov 2025 21:44:34 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unsafe-test-patterns/index.html</guid>
      <description>Overview Unsafe test patterns occur when test-only code, debug functionality, or development shortcuts accidentally make it into production smart contracts. In Sui Move, the #[test_only] attribute should isolate test code, but improper patterns can leak test utilities, create backdoors, or leave vulnerabilities that only manifest in production environments.&#xA;Risk Level High — Can create backdoors, bypass security controls, or cause unexpected production behavior.</description>
    </item>
    <item>
      <title>31. Unvalidated Struct Fields</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unvalidated-struct-fields/index.html</link>
      <pubDate>Wed, 26 Nov 2025 21:46:35 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/unvalidated-struct-fields/index.html</guid>
      <description>Overview Unvalidated struct fields occur when smart contracts accept user-provided data to populate struct fields without proper validation, leading to invalid state, security bypasses, or protocol corruption. In Sui Move, structs often represent critical protocol state, and failing to validate inputs during construction or modification can have severe consequences.&#xA;Risk Level High — Can lead to invalid state, security bypasses, or financial losses.</description>
    </item>
    <item>
      <title>32. Inefficient PTB Composition</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/inefficient-ptb-composition/index.html</link>
      <pubDate>Wed, 26 Nov 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/inefficient-ptb-composition/index.html</guid>
      <description>Overview Inefficient PTB (Programmable Transaction Block) composition occurs when transactions are structured in ways that waste gas, hit execution limits, or create unnecessary complexity. Sui’s PTB model allows composing multiple operations in a single transaction, but poor composition can lead to gas exhaustion attacks, failed transactions, or denial of service through resource exhaustion.&#xA;Risk Level Medium to High — Can lead to gas exhaustion, transaction failures, or denial of service.</description>
    </item>
    <item>
      <title>33. Overuse of Shared Objects</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/overuse-of-shared-objects/index.html</link>
      <pubDate>Thu, 15 May 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/overuse-of-shared-objects/index.html</guid>
      <description>Overview Overuse of Shared Objects occurs when developers unnecessarily use shared objects where owned objects would suffice, or when they design systems with excessive sharing that creates contention, reduces throughput, and introduces security risks. In Sui, shared objects require consensus ordering while owned objects can be processed in parallel without consensus. Overusing shared objects not only degrades performance but can also introduce access control vulnerabilities and state manipulation risks.</description>
    </item>
    <item>
      <title>34. Parent-Child Authority</title>
      <link>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/parent-child-authority/index.html</link>
      <pubDate>Thu, 15 May 2025 00:00:00 +0000</pubDate>
      <guid>https://3bad1648.frontier-scetrov-live.pages.dev/devsecops/vulns/parent-child-authority/index.html</guid>
      <description>Overview Parent-Child Authority vulnerabilities occur when developers make incorrect assumptions about the authority relationships between parent and child objects in Sui’s object model. In Sui, objects can own other objects (dynamic fields, wrapped objects), creating hierarchical relationships. Security issues arise when code assumes that access to a parent object automatically implies authorization over child objects, or conversely, when child objects can be manipulated independently in ways that violate intended invariants.</description>
    </item>
  </channel>
</rss>