Relationship Graph

Relationship Graph
related to related to child of child of duplicate of duplicate of

View Issue Details

IDProjectCategoryView StatusLast Update
0036987mantisbtcsvpublic2026-04-18 10:31
Reportervicsuarez Assigned Todregad  
PrioritynormalSeverityminorReproducibilityalways
Status resolvedResolutionfixed 
Product Version2.28.1 
Target Version2.28.2Fixed in Version2.28.2 
Summary0036987: csv_escape_string: incorrect result with int/float custom values when csv_injection_protection is active
Description

Wrong casting in function csv_escape_string (csv_api.php) results in a "tab" prefixed in numeric values of custom fields. This makes more difficult manage types in created CSV files.

This issue generates a warning: "PHP Warning: Trying to access array offset on int in php shell code on line xxxxx"

Steps To Reproduce

1- Click on "CSV Export button on "View Issues" page
2- If there are numeric/float configured custom fields in "csv_columns", all non-zero values have a tab prefixed.

Additional Information

One possible solution could be replace this code:

        if( $p_string && strpos( '=-+@', $p_string[0] ) !== false ) {
            # Prefixing with a tab rather than single quote, as Excel does not show
            # the tab visually in the cell.
            $p_string = "\t" . $p_string;
        }

with this:

            if( $p_string && strpos( '=-+@', ($p_string . '')[0] ) !== false ) {
                # Prefixing with a tab rather than single quote, as Excel does not show
                # the tab visually in the cell.
                $p_string = "\t" . $p_string;
            }
TagsNo tags attached.

Relationships

related to 0029130 closeddregad CVE-2021-43257: CSV Injection with CSV Export Feature 

Activities

dregad

dregad

2026-03-19 14:02

developer   ~0070892

Last edited: 2026-03-19 14:14

Thanks for the report.

I confirm that when csv_escape_string() receives non-string data, the lack of type cast will lead to always (and sometimes incorrectly) qualifying the string as risky, resulting in tab character to be prepended.

dregad

dregad

2026-03-19 14:35

developer   ~0070893

PR https://github.com/mantisbt/mantisbt/pull/2198

@vicsuarez Please test the proposed patch let let me know your feedback.

Note that even after the fix, negative values will still be prefixed by a tab, and Excel will therefore treated them as string instead of number. This cannot be avoided while $g_csv_injection_protection = ON.

vicsuarez

vicsuarez

2026-03-19 14:47

reporter   ~0070894

Last edited: 2026-03-20 03:15

Be careful, csv_api.php is broken after patch (lines 122 to 126).

vicsuarez

vicsuarez

2026-03-19 15:03

reporter   ~0070895

Last edited: 2026-03-19 15:04

Applying the patch (as primarily intended) is working, fixing the problem from this issue.

This is the original function (I THINK):

function csv_escape_string( $p_string ) {
    $p_string = (string)$p_string;
    if( config_get( 'csv_injection_protection' )
        && $p_string && strpos( '=-+@', $p_string[0] ) !== false){
            # Prefixing with a tab rather than single quote, as Excel does not show
            # the tab visually in the cell.
            $p_string = "\t" . $p_string;
            $t_must_escape = true;
    } else {
        $t_must_escape = false;
        $t_escaped = str_split( '"' . csv_get_separator() . csv_get_newline() );
        while( ( $t_char = current( $t_escaped ) ) !== false && !$t_must_escape ) {
            $t_must_escape = strpos( $p_string, $t_char ) !== false;
            next( $t_escaped );
        }
    }

    if( $t_must_escape ) {
        $p_string = '"' . str_replace( '"', '""', $p_string ) . '"';
    }

    return $p_string;
}
dregad

dregad

2026-03-21 19:00

developer   ~0070897

Thanks for the feedback. To make it better next time:

BAD: csv_api.php is broken
GOOD: Parse error: syntax error, unexpected token "&&" in core/csv_api.php on line 125

Anyway, sorry about posting a PR with a syntax error, that was sloppy - I messed up when splitting a commit, and should have re-tested the code before pushing the branch. GitHub actions should have caught this, but for some reason the CI pipeline did not run.

I just pushed a fix to the PR's branch, hopefully it will be OK this time.

vicsuarez

vicsuarez

2026-03-21 19:42

reporter   ~0070901

Thank you very much, and excuse me for the incorrect expression.

Related Changesets

MantisBT: master-2.28 b80bd8bd

2026-03-19 14:21

dregad


Details Diff
Ensure csv_escape_string() deals with a string

This prevents a PHP warning when using array dereferencing form to get
$p_string's first character.

When this happened, the strpos() call would return 0, leading to always
(and sometimes incorrectly) qualifying the string as risky, resulting in
a tab character to be prepended.

Note: using a type cast instead of string TypeDef in function signature
to avoid regression issues in case some callers pass NULL.

Fixes 0036987
Affected Issues
0036987
mod - core/csv_api.php Diff File