Repository navigation
Commit 8a9cdcb
FIX: Redact parameter values from executemany Decimal-conversion error (#719)
### Work Item / Issue Reference
>
[AB#47300](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/47300)
-------------------------------------------------------------------
### Summary
The `executemany()` Decimal/NUMERIC conversion path embedded the
**entire parameter row** into the raised `ValueError`:
```
ValueError(f"Failed to convert parameter at row {row}, column {i} to Decimal: {e}")
```
Here `row` is the full parameter tuple, so every column value in a
failing row (potentially PII such as SSNs, emails, names, or balances)
was placed into the exception message. That message propagates to caller
error handlers, tracebacks, and APM/log shippers (Sentry, Splunk, App
Insights) **even when driver DEBUG logging is never enabled**, because
uncaught exceptions surface by default.
This change makes the error **metadata-only**: it reports the row index,
column index, and the value's type name, and never the value or the row.
**Before**
```
Failed to convert parameter at row ('Jane Doe', '123-45-6789', 'jane@x.com', 'N/A'), column 3 to Decimal: [<class 'decimal.ConversionSyntax'>]
```
**After**
```
Failed to convert parameter to Decimal at row 0, column 3 (value type: str)
```
#### Hardening: value-bearing exception cause
Redacting only the outer message is not enough. `raise ... from e`
chains the original exception, which surfaces through `__cause__` and
`traceback.format_exc()` -- exactly what APM/log shippers capture. For
an ordinary bad string the chained cause is the value-free
`decimal.InvalidOperation` (`ConversionSyntax`), but for a value whose
`str()` raises with content (or any error echoing the input) the
sensitive text would still leak via the cause.
The conversion now splits `str(val)` from the decimal parse and chains
**only** `decimal.DecimalException`, which is proven value-free (it
never echoes the input). `str(val)` failures and any other unexpected
error are re-raised with the chain suppressed (`from None`), so the
metadata-only guarantee holds across `__cause__` and formatted
tracebacks, not just `str(exc)`.
#### Changes
- `mssql_python/cursor.py`: enumerate rows for an index; raise a
value-free, metadata-only `ValueError`; chain only the value-free
`decimal.DecimalException` and suppress the cause (`from None`) for
`str(val)` / unexpected failures.
- `tests/test_004_cursor.py`: strengthen the unconvertible-value test to
assert the sensitive value and raw row are absent from both the message
and the fully formatted traceback; add
`test_setinputsizes_sql_decimal_str_raises_no_leak` covering a parameter
whose `str()` raises a secret (asserts `__cause__ is None` and the
secret is absent from the traceback).
---------
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Gaurav Sharma <sharmag@microsoft.com>1 parent 8e1f8fe commit 8a9cdcb
2 files changed
Lines changed: 211 additions & 15 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2693 | 2693 | | |
2694 | 2694 | | |
2695 | 2695 | | |
2696 | | - | |
| 2696 | + | |
2697 | 2697 | | |
2698 | 2698 | | |
2699 | 2699 | | |
| |||
2715 | 2715 | | |
2716 | 2716 | | |
2717 | 2717 | | |
| 2718 | + | |
| 2719 | + | |
| 2720 | + | |
| 2721 | + | |
| 2722 | + | |
| 2723 | + | |
| 2724 | + | |
| 2725 | + | |
| 2726 | + | |
| 2727 | + | |
| 2728 | + | |
| 2729 | + | |
| 2730 | + | |
| 2731 | + | |
| 2732 | + | |
| 2733 | + | |
| 2734 | + | |
| 2735 | + | |
| 2736 | + | |
| 2737 | + | |
2718 | 2738 | | |
2719 | | - | |
2720 | | - | |
2721 | | - | |
2722 | | - | |
2723 | | - | |
| 2739 | + | |
| 2740 | + | |
| 2741 | + | |
| 2742 | + | |
| 2743 | + | |
2724 | 2744 | | |
2725 | 2745 | | |
2726 | 2746 | | |
| |||
2729 | 2749 | | |
2730 | 2750 | | |
2731 | 2751 | | |
2732 | | - | |
| 2752 | + | |
| 2753 | + | |
| 2754 | + | |
| 2755 | + | |
| 2756 | + | |
2733 | 2757 | | |
2734 | | - | |
| 2758 | + | |
2735 | 2759 | | |
2736 | | - | |
2737 | | - | |
2738 | | - | |
2739 | | - | |
| 2760 | + | |
2740 | 2761 | | |
2741 | 2762 | | |
2742 | 2763 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
| 18 | + | |
18 | 19 | | |
19 | 20 | | |
20 | 21 | | |
| |||
10462 | 10463 | | |
10463 | 10464 | | |
10464 | 10465 | | |
10465 | | - | |
| 10466 | + | |
| 10467 | + | |
| 10468 | + | |
| 10469 | + | |
| 10470 | + | |
| 10471 | + | |
10466 | 10472 | | |
10467 | 10473 | | |
10468 | 10474 | | |
| |||
10471 | 10477 | | |
10472 | 10478 | | |
10473 | 10479 | | |
10474 | | - | |
| 10480 | + | |
| 10481 | + | |
10475 | 10482 | | |
10476 | 10483 | | |
10477 | | - | |
| 10484 | + | |
| 10485 | + | |
| 10486 | + | |
| 10487 | + | |
| 10488 | + | |
| 10489 | + | |
| 10490 | + | |
| 10491 | + | |
| 10492 | + | |
| 10493 | + | |
| 10494 | + | |
| 10495 | + | |
| 10496 | + | |
| 10497 | + | |
| 10498 | + | |
| 10499 | + | |
| 10500 | + | |
10478 | 10501 | | |
| 10502 | + | |
| 10503 | + | |
10479 | 10504 | | |
10480 | 10505 | | |
10481 | 10506 | | |
10482 | 10507 | | |
| 10508 | + | |
| 10509 | + | |
| 10510 | + | |
| 10511 | + | |
| 10512 | + | |
| 10513 | + | |
| 10514 | + | |
| 10515 | + | |
| 10516 | + | |
| 10517 | + | |
| 10518 | + | |
| 10519 | + | |
| 10520 | + | |
| 10521 | + | |
| 10522 | + | |
| 10523 | + | |
| 10524 | + | |
| 10525 | + | |
| 10526 | + | |
| 10527 | + | |
| 10528 | + | |
| 10529 | + | |
| 10530 | + | |
| 10531 | + | |
| 10532 | + | |
| 10533 | + | |
| 10534 | + | |
| 10535 | + | |
| 10536 | + | |
| 10537 | + | |
| 10538 | + | |
| 10539 | + | |
| 10540 | + | |
| 10541 | + | |
| 10542 | + | |
| 10543 | + | |
| 10544 | + | |
| 10545 | + | |
| 10546 | + | |
| 10547 | + | |
| 10548 | + | |
| 10549 | + | |
| 10550 | + | |
| 10551 | + | |
| 10552 | + | |
| 10553 | + | |
| 10554 | + | |
| 10555 | + | |
| 10556 | + | |
| 10557 | + | |
| 10558 | + | |
| 10559 | + | |
| 10560 | + | |
| 10561 | + | |
| 10562 | + | |
| 10563 | + | |
| 10564 | + | |
| 10565 | + | |
| 10566 | + | |
| 10567 | + | |
| 10568 | + | |
| 10569 | + | |
| 10570 | + | |
| 10571 | + | |
| 10572 | + | |
| 10573 | + | |
| 10574 | + | |
| 10575 | + | |
| 10576 | + | |
| 10577 | + | |
| 10578 | + | |
| 10579 | + | |
| 10580 | + | |
| 10581 | + | |
| 10582 | + | |
| 10583 | + | |
| 10584 | + | |
| 10585 | + | |
| 10586 | + | |
| 10587 | + | |
| 10588 | + | |
| 10589 | + | |
| 10590 | + | |
| 10591 | + | |
| 10592 | + | |
| 10593 | + | |
| 10594 | + | |
| 10595 | + | |
| 10596 | + | |
| 10597 | + | |
| 10598 | + | |
| 10599 | + | |
| 10600 | + | |
| 10601 | + | |
| 10602 | + | |
| 10603 | + | |
| 10604 | + | |
| 10605 | + | |
| 10606 | + | |
| 10607 | + | |
| 10608 | + | |
| 10609 | + | |
| 10610 | + | |
| 10611 | + | |
| 10612 | + | |
| 10613 | + | |
| 10614 | + | |
| 10615 | + | |
| 10616 | + | |
| 10617 | + | |
| 10618 | + | |
| 10619 | + | |
| 10620 | + | |
| 10621 | + | |
| 10622 | + | |
| 10623 | + | |
| 10624 | + | |
| 10625 | + | |
| 10626 | + | |
| 10627 | + | |
| 10628 | + | |
| 10629 | + | |
| 10630 | + | |
| 10631 | + | |
| 10632 | + | |
| 10633 | + | |
| 10634 | + | |
| 10635 | + | |
| 10636 | + | |
| 10637 | + | |
| 10638 | + | |
| 10639 | + | |
| 10640 | + | |
| 10641 | + | |
| 10642 | + | |
| 10643 | + | |
| 10644 | + | |
| 10645 | + | |
| 10646 | + | |
| 10647 | + | |
| 10648 | + | |
| 10649 | + | |
| 10650 | + | |
| 10651 | + | |
| 10652 | + | |
| 10653 | + | |
| 10654 | + | |
| 10655 | + | |
| 10656 | + | |
| 10657 | + | |
10483 | 10658 | | |
10484 | 10659 | | |
10485 | 10660 | | |
| |||
0 commit comments