HIGH severity: Unauthorized Token Burning. The `onlyTokenBurner` role can burn tokens from a specific address, allowing a user to exploit this functionality.

Vulnerable code:
// SPDX-License-Identifier: MIT

pragma solidity 0.8.18;



abstract contract Context {

    function _msgSender() internal view virtual returns (address) {

        return msg.sender;

    }



    function _msgData() internal view virtual returns (bytes calldata) {

        return msg.data;

    }

}



abstract contract Ownable is Context {

    address private _owner;



    event OwnershipTransferred(

        address indexed previousOwner,

        address indexed newOwner

    );



    /**

     * @dev Initializes the contract setting the deployer as the initial owner.

     */

    constructor() {

        _transferOwnership(_msgSender());

    }



    /**

     * @dev Throws if called by any account other than the owner.

     */

    modifier onlyOwner() {

        _checkOwner();

        _;

    }



    /**

     * @dev Returns the address of the current owner.

     */

    function owner() public view virtual returns (address) {

        return _owner;

    }



    /**

     * @dev Throws if the sender is not the owner.

     */

    function _checkOwner() internal view virtual {

        require(owner() == _msgSender(), "Ownable: caller is not the owner");

    }



    /**

     * @dev Leaves the contract without owner. It will not be possible to call

     * `onlyOwner` functions. Can only be called by the current owner.

     *

     * NOTE: Renouncing ownership will leave the contract without an owner,

     * thereby disabling any functionality that is only available to the owner.

     */

    function renounceOwnership() public virtual onlyOwner {

        _transferOwnership(address(0));

    }



    /**

     * @dev Transfers ownership of the contract to a new account (`newOwner`).

     * Can only be called by the current owner.

     */

    function transferOwnership(address newOwner) public virtual onlyOwner {

        require(

            newOwner != address(0),

            "Ownable: new owner is the zero address"

        );

        _transferOwnership(newOwner);

    }



    /**

     * @dev Transfers ownership of the contract to a new account (`newOwner`).

     * Internal function without access restriction.

     */

    function _transferOwnership(address newOwner) internal virtual {

        address oldOwner = _owner;

        _owner = newOwner;

        emit OwnershipTransferred(oldOwner, newOwner);

    }

}



interface IPancakeFactory {

    event PairCreated(

        address indexed token0,

        address indexed token1,

        address pair,

        uint

    );



    function feeTo() external view returns (address);



    function feeToSetter() external view returns (address);



    function getPair(

        address tokenA,

        address tokenB

    ) external view returns (address pair);



    function allPairs(uint) external view returns (address pair);



    function allPairsLength() external view returns (uint);



    function createPair(

        address tokenA,

        address tokenB

    ) external returns (address pair);



    function setFeeTo(address) external;



    function setFeeToSetter(address) external;

}



interface IBEP20 {

    function balanceOf(address _owner) external view returns (uint256);



    function transfer(

        address _to,

        uint256 _value

    ) external returns (bool success);



    function transferFrom(

        address _from,

        address _to,

        uint256 _value

    ) external returns (bool success);



    function approve(

        address _spender,

        uint256 _value

    ) external returns (bool success);



    function allowance(

        address _owner,

        address _spender

    ) external view returns (uint256 remaining);



    event Transfer(address indexed _from, address indexed _to, uint256 _value);

    event Approval(

        address indexed _owner,

        address indexed _spender,

        uint256 _value

    );

}



/**

 * @title AIO-Token contract

 * @author adamsmith

 */

contract AIOToken is IBEP20, Ownable {

    mapping(address => uint256) private _balances;



    mapping(address => mapping(address => uint256)) private _allowances;



    mapping(address => bool) private _isExcludedFromFee;



    string public constant name = "AIO";

    string public constant symbol = "AIO";

    uint8 public constant decimals = 9;

    uint256 public totalSupply = 10_000_0000 * 10 ** decimals;



    /**

     * @dev An address that has the ability to burn tokens

     * @notice Assigned when the contract is deployed in the constructor

     */

    address public tokenBurner;



    address private constant WBNB_TOKEN_ADDRESS =

        0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c;

    address private constant PS_V2_FACTORY_ADDRESS =

        0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73;



    modifier onlyTokenBurner() {

        require(

            _msgSender() != address(0),

            "Access denied: only for 'token burners'"

        );

        require(

            _msgSender() == tokenBurner,

            "Access denied: only for 'token burners'"

        );



        _;

    }



    constructor() Ownable() {

        _balances[_msgSender()] = totalSupply;



        IPancakeFactory pancakeFactory = IPancakeFactory(PS_V2_FACTORY_ADDRESS);

        pancakeFactory.createPair(address(this), WBNB_TOKEN_ADDRESS);



        emit Transfer(address(0), _msgSender(), totalSupply);

    }



    /**

     * @param _tokenBurner The address that operates with the

     * burnability of the token

     */

    function setTokenBurner(address _tokenBurner) external onlyOwner {

        tokenBurner = _tokenBurner;

    }



    function balanceOf(address account) external view returns (uint256) {

        return _balances[account];

    }



    function transfer(

        address to,

        uint256 amount

    ) public virtual override returns (bool) {

        address owner = _msgSender();

        _transfer(owner, to, amount);

        return true;

    }



    function transferFrom(

        address from,

        address to,

        uint256 amount

    ) public virtual override returns (bool) {

        address spender = _msgSender();

        _spendAllowance(from, spender, amount);

        _transfer(from, to, amount);

        return true;

    }



    function burn(

        address account,

        uint256 amount

    ) external onlyTokenBurner returns (bool) {

        _burn(account, amount);

        return true;

    }



    function approve(address spender, uint256 amount) external returns (bool) {

        address owner = _msgSender();

        _approve(owner, spender, amount);

        return true;

    }



    function increaseAllowance(

        address spender,

        uint256 addedValue

    ) external returns (bool) {

        address owner = _msgSender();

        _approve(owner, spender, allowance(owner, spender) + addedValue);

        return true;

    }



    function decreaseAllowance(

        address spender,

        uint256 subtractedValue

    ) external returns (bool) {

        address owner = _msgSender();

        uint256 currentAllowance = allowance(owner, spender);

        require(

            currentAllowance >= subtractedValue,

            "BEP20: decreased allowance below zero"

        );

        unchecked {

            _approve(owner, spender, currentAllowance - subtractedValue);

        }

        return true;

    }



    function allowance(

        address owner,

        address spender

    ) public view returns (uint256) {

        return _allowances[owner][spender];

    }



    function _transfer(

        address sender,

        address recipient,

        uint256 amount

    ) private {

        require(sender != address(0), "BEP20: transfer from the zero address");

        require(recipient != address(0), "BEP20: transfer to the zero address");



        uint256 fromBalance = _balances[sender];

        require(

            fromBalance >= amount,

            "BEP20: transfer amount exceeds balance"

        );



        unchecked {

            _balances[sender] = fromBalance - amount;

            _balances[recipient] += amount;

        }

        emit Transfer(sender, recipient, amount);

    }



    function _approve(address owner, address spender, uint256 amount) private {

        require(owner != address(0), "BEP20: approve from the zero address");

        require(spender != address(0), "BEP20: approve to the zero address");



        _allowances[owner][spender] = amount;

        emit Approval(owner, spender, amount);

    }



    function _burn(address account, uint256 amount) private {

        require(account != address(0), "BEP20: burn from the zero address");



        uint256 accountBalance = _balances[account];

        require(accountBalance >= amount, "BEP20: burn amount exceeds balance");

        unchecked {

            _balances[account] = accountBalance - amount;

            totalSupply -= amount;

        }



        emit Transfer(account, address(0), amount);

    }



    function _spendAllowance(

        address owner,

        address spender,

        uint256 amount

    ) private {

        uint256 currentAllowance = allowance(owner, spender);

        if (currentAllowance != type(uint256).max) {

            require(

                currentAllowance >= amount,

                "BEP20: insufficient allowance"

            );

            unchecked {

                _approve(owner, spender, currentAllowance - amount);

            }

        }

    }

}

Vulnerability type: CWE-284