Dr. Obieda Ananbeh

PhD in computer science

Sr.Software Engineer

Microsoft Certified

Java Developer

AI

Dr. Obieda Ananbeh

PhD in computer science

Sr.Software Engineer

Microsoft Certified

Java Developer

AI

Blog Post

Why AI-Generated Code Needs More Than a Security Scan

October 31, 2026 Tech
Why AI-Generated Code Needs More Than a Security Scan

An AI coding assistant can produce a function in seconds. The function may compile, pass a security scan, and still produce the wrong result. It may also pass its functional tests while exposing sensitive data or allowing an unauthorized action.

These failures are easy to miss when we treat one successful check as evidence that the whole solution is safe. Generated code needs the same scrutiny as any other code, including tests for the behavior it should produce and the risks it must avoid.

A concrete example: a discount applied twice

Suppose an assistant generates this Python function. It uses decimal arithmetic, but it mistakenly applies the discount twice:

from decimal import Decimal

def order_total(price, discount):
    # Incorrect: the discount is applied twice.
    return price * (1 - discount) * (1 - discount)

# A 10% discount on $100 should produce $90.
assert order_total(Decimal("100"), Decimal("0.10")) == Decimal("90")

Running the assertion raises an AssertionError: the function returns $81 instead of $90. This is a functional error; a security scanner may not flag it. To fix this particular error, apply the discount once: return price * (1 - discount). Production code still needs rules for valid discounts and rounding.

A prompt you can adapt

After writing the requirements, you can ask an AI assistant to review the function:

Review the Python function below against these requirements:
- Apply the discount once to the original price.
- Use decimal arithmetic for money.
- Identify incorrect behavior and suggest boundary tests.
- Explain any security concerns relevant to its actual context.
Do not assume a passing security scan proves correctness.

[Paste the function and its requirements here.]

Check the suggested tests and concerns yourself. The assistant can overlook a defect or misunderstand the application, especially if the prompt omits context.

What a security scan can find

A static security scanner examines code without running it. Depending on the tool and its rules, it may flag patterns such as hard-coded credentials, unsafe query construction, or dangerous uses of an API. Some tools also check dependencies for known vulnerabilities.

These checks are useful, but a clean report means only that the scanner did not report a problem within the scope of its analysis. A scanner may miss a vulnerability, lack the context to recognize it, or flag code that is not actually vulnerable. Findings need review, and silence is not proof of security.

Correct output is a separate requirement

Consider a function that calculates the total price of an order after applying a discount. An AI assistant generates code that uses parameterized database queries and does not trigger a security warning. However, the function applies the discount twice. The code may be free of the issues the scanner checks, but it still charges the wrong amount.

A functional test can catch that error. Give the function an order and a known discount, then check that the result matches the expected total. Add tests for zero discounts, invalid values, and rounding if the requirements cover those cases.

Functional tests have limits too. Passing a set of tests shows that the code behaved as expected for those cases. It does not prove that every possible input will work, or that the code is secure.

Working code can still be vulnerable

Now consider an endpoint that returns a user’s order history. A test confirms that it returns the correct orders when given an account ID. That result does not tell us whether the endpoint checks that the requester owns the account.

A security test should also try to access another user’s orders and verify that the request is denied. This is an authorization requirement: the application must check what the requester is allowed to access. A scanner may not know the intended access rules, so developers need to express those rules in tests and review the surrounding code.

A practical review process

  1. Define the expected behavior. Write down what the code should do, including boundaries and error cases. For an API, include who may call it and what data each user may see.
  2. Review the generated code. Check that it follows the requirements and fits the surrounding application. Pay attention to input handling, authentication, authorization, secrets, and dependencies.
  3. Run functional tests. Check normal inputs, boundary cases, and expected failures. Tests should compare results against requirements, not simply repeat the assumptions in the generated code.
  4. Run security checks. Use suitable static analysis and dependency checks, then investigate their findings. Add targeted security tests for application-specific rules such as access control.
  5. Test the final integrated result. A function that works in isolation can behave differently when connected to the database, configuration, or other services. Re-run relevant checks after changes.

AI can help write code and suggest tests, but its suggestions still need independent review. The goal is to establish that the final code does the intended job and meets the security requirements for the environment where it will run.

Taggs: