Weakness reference
CWE-472

External Control of Assumed-Immutable Web Parameter

This weakness occurs when a web application trusts that certain inputs—typically hidden form fields, cookies, or URL parameters marked as "internal"—cannot be…

01Summary

This weakness occurs when a web application trusts that certain inputs—typically hidden form fields, cookies, or URL parameters marked as "internal"—cannot be changed by users, but an attacker can modify them anyway. The application fails to validate these inputs on the server side, assuming their integrity is guaranteed by their hidden or "system-level" nature. This false assumption can lead to unauthorized actions, data manipulation, or privilege escalation.

02How It Happens

Developers often assume that hidden HTML form fields, client-side session tokens, or parameters not directly visible to users are inherently protected from tampering. In reality, an attacker can inspect and modify any data sent from the browser—hidden fields are hidden only from casual users, not from tools like browser developer consoles or HTTP proxies. When the server accepts these values without re-validating them against server-side state or business logic, an attacker can forge or alter them to bypass intended restrictions. The root cause is a misunderstanding of the trust boundary: the client is not a trusted environment, and no data from the client should be assumed immutable without explicit server-side verification.

03Real-World Impact

An attacker exploiting this weakness can modify prices in a shopping cart before checkout, change user IDs in hidden fields to access another user's account, alter role or permission flags to escalate privileges, or manipulate order totals or discount codes. In financial or administrative contexts, this can result in unauthorized transactions, data theft, or unauthorized access to sensitive functions. The impact ranges from minor data integrity issues to complete account takeover or fraud, depending on what the "immutable" parameter controls.

04Vulnerable & Fixed Patterns

Vulnerable pattern
from flask import Flask, request

app = Flask(__name__)

@app.route('/checkout', methods=['POST'])
def checkout():
    user_id = request.form.get('user_id')  # Hidden field, assumed immutable
    total = request.form.get('total')      # Hidden field, assumed immutable
    
    # Process order without verifying user_id or total
    order = create_order(user_id, total)
    return f"Order created for user {user_id}: ${total}"

Why it's vulnerable:
The user_id and total are taken directly from the form without server-side validation. An attacker can modify these hidden fields in the HTML before submission, changing the user ID to another account or the total to a lower price.

Fixed pattern
from flask import Flask, request, session

app = Flask(__name__)

@app.route('/checkout', methods=['POST'])
def checkout():
    # Retrieve user_id from server-side session, not from form
    user_id = session.get('user_id')
    
    # Recalculate total from cart items stored server-side
    cart_items = session.get('cart', [])
    total = calculate_total(cart_items)
    
    # Verify the submitted total matches the server-side calculation
    submitted_total = float(request.form.get('total', 0))
    if abs(submitted_total - total) > 0.01:
        return "Total mismatch. Order rejected.", 400
    
    order = create_order(user_id, total)
    return f"Order created for user {user_id}: ${total}"
Vulnerable pattern
<?php
// Assume user_id and discount_code are hidden form fields
$user_id = $_POST['user_id'];
$discount_code = $_POST['discount_code'];
$order_total = $_POST['order_total'];

// Apply discount without verifying it against server records
$discount = get_discount_value($discount_code);
$final_total = $order_total - $discount;

// Create order with attacker-controlled values
create_order($user_id, $final_total);
echo "Order placed for user $user_id";
?>

Why it's vulnerable:
The user_id, discount_code, and order_total are all taken directly from POST data without server-side verification. An attacker can modify these hidden fields to change the user, apply invalid discounts, or alter the total.

Fixed pattern
<?php
// Retrieve user_id from server-side session
session_start();
$user_id = $_SESSION['user_id'];

// Retrieve and validate discount code against database
$submitted_code = sanitize_input($_POST['discount_code']);
$discount = get_valid_discount($submitted_code, $user_id);

// Recalculate order total from server-side cart data
$cart_items = $_SESSION['cart'] ?? [];
$order_total = calculate_total_from_cart($cart_items);

// Apply only valid, server-verified discount
$final_total = max(0, $order_total - $discount);

// Create order with server-verified values
create_order($user_id, $final_total);
echo "Order placed for user " . esc_html($user_id);
?>

05Prevention Checklist

Never trust hidden form fields, cookies, or client-side tokens for security decisions.
Always re-validate critical data on the server side.
Store authoritative state server-side.
Keep user ID, role, permissions, and calculated totals in server-side sessions or databases, not in the client.
Recalculate derived values.
If a value is computed (e.g., order total, discount), recalculate it server-side from source data rather than accepting the client's version.
Validate against business logic.
Check that submitted values are consistent with the user's actual permissions, cart contents, or account state.
Use cryptographic signatures or HMACs for non-sensitive immutable data.
If you must send data to the client and expect it unchanged, sign it server-side and verify the signature on return.
Audit parameter handling in forms.
Review all form submissions and identify which fields are assumed immutable; ensure each is validated server-side.

06Signs You May Already Be Affected

Check your application logs and database for unusual patterns: orders with mismatched totals, users accessing accounts or data that don't belong to them, or discount codes applied that were never issued. Review your form handling code for any parameters taken directly from $_POST, $_GET, or request.form without subsequent server-side validation against session or database state. If you find hidden fields or cookies being used to determine user identity, permissions, or financial amounts, that is a strong indicator of this weakness.

07Related Recent Vulnerabilities