#2 Security & Stability Test: where() and having() #5
decMuc
announced in
Compare & Tests
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Discovery of a potential persistence bug in MysqliDb
While running a new series of comparison tests between PDOdb and ThingEngineer's MysqliDb, we encountered a potentially serious issue within the original MysqliDb class.
Test Purpose
The test suite was originally intended to benchmark and validate:
Typing safety (whereInt(), whereDate() etc.) in PDOdb
SQL injection resistance
Comparison of performance and behavior in edge-case WHERE/HAVING conditions
However, during the initial invalid-WHERE tests, MysqliDb began to accumulate internal state across queries — even though each test should be independent. From that point onward, subsequent test results became polluted and unpredictable.
Root Cause (Assumed)
We suspect that once an invalid query (e.g. price === 100) is sent to MySQL and causes a syntax error, the internal
_where,_join, or_queryproperties inside the MysqliDb object are not properly reset.As a result:
Old WHERE clauses remain attached to future queries.
getLastQuery()outputs a concatenated mix of past and current fragments.The class appears to continue operating, but returns incorrect and dangerous queries.
Reproducibility
The issue is reproducible via the attached script. Specifically, the problem starts after this test:
The resulting query string is invalid (price === ?), and from that point onward, the internal state in Thing's MysqliDb object begins to accumulate instead of resetting.
Temporary Workaround
We introduced a custom method inside Thing's class for testing:
Calling this before each test resets the internal state and temporarily solves the issue. However, this is not part of the original class and must not be seen as a final fix.
Important Difference to PDOdb
Our own PDOdb implementation stops execution early via throw if a query appears suspicious or syntactically invalid — no query is built at all in such cases. However, this also means that no lastQuery can be generated.
We now added a manual fallback by calling:
...before each test, until internal reset handling is fully implemented.
Heuristic WHERE Evaluation (PDOdb only)
PDOdb optionally attempts to analyze suspicious WHERE values heuristically, for example:
Instead of immediately blocking, PDOdb checks:
This feature is toggled in the next release via:
Disabling it (false) will block any suspicious input outright without type inspection.
⚠ However, enabling this adds a small overhead:
In our test case, time increased from 0.02 ms to 3.4 ms per WHERE call. In contrast, MysqliDb crashed at around 0.6 ms due to raw MySQL errors.
Summary
PDOdb is stricter but more stable and secure under invalid input.
MysqliDb shows persistent internal state pollution after query errors.
The issue appears to be reproducible, serious, and not yet reported upstream.
Test Output Snapshot
Below is the raw output of the executed test suite (PDOdb vs MysqliDb) including query strings, result counts, exceptions and status:
This represents the actual $results[] array generated by the benchmark script.
Beta Was this translation helpful? Give feedback.
All reactions