Skip to content

Escaping is broken #187

Open
Open
@zeripath

Description

@zeripath

Please give general description of the problem

Go-ini does not properly cope with characters that need to be escaped.

Please provide code snippets to reproduce the problem described above

  • Let's look at key name escaping:

ini/file.go

Lines 332 to 339 in 3be5ad4

switch {
case key.isAutoIncrement:
kname = "-"
case strings.Contains(kname, "\"") || strings.ContainsAny(kname, f.options.KeyValueDelimiters):
kname = "`" + kname + "`"
case strings.Contains(kname, "`"):
kname = `"""` + kname + `"""`
}

Say you have a key name which contains a " and a `, lines 335 and 336 will mean that you wrap the key in `, however, leading to an unescaped component. So for example the key:

A pathological `c"as"`e

becomes:

`A pathological `c"as"`e`

Which is likely to be interpreted as:

A pathological case

Let's try a value injection say you provide a key named like this:

KEY`=FAKE_VALUE ;"`

This becomes:

`KEY`=FAKE_VALUE ;"`` = ACTUAL_VALUE

If say you simply promote the """ case higher - then you're not protecting against embedded """ strings within the key.

I presume that key names are not allowed to have newlines in them and that this is prevented elsewhere. If not then this is also a major problem.

  • Key values

These are more of a problem because these can contain new lines and are far more likely to be exploited as most users of this library will not allow arbitrary keys.

ini/file.go

Lines 358 to 366 in 3be5ad4

// In case key value contains "\n", "`", "\"", "#" or ";"
if strings.ContainsAny(val, "\n`") {
val = `"""` + val + `"""`
} else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") {
val = "`" + val + "`"
}
if _, err := buf.WriteString(equalSign + val + LineBreak); err != nil {
return nil, err
}

A value containing """\n can rewrite arbitrary sections of the config file.

e.g. the value

VALUE"""
[ANOTHER SECTION]
KEYS=VALUES
...
; more arbitrary content

; """

Do you have any suggestion to fix the problem?

If there is no proper mechanism for escaping these cases, (I suspect that in general that this is the case as ini files are very poorly documented - but I guess an option could given to backslash escape) go-ini should simply return an error saying that there is no safe delimiter.

Check that the chosen delimiter is not included in the value and not just assume that because one delimiter is included you can just use another without checking.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is needed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions