Skip to content
This repository has been archived by the owner on Jan 5, 2023. It is now read-only.

Note that the %q format directive escapes newlines, and therefore prevents log injection #658

Merged

Conversation

smowton
Copy link
Contributor

@smowton smowton commented Jan 5, 2022

No description provided.

Copy link
Contributor

@owen-mc owen-mc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One copy-paste error leading to a misnamed class and two queries in existing code which you just moved.

ql/lib/semmle/go/frameworks/stdlib/Log.qll Outdated Show resolved Hide resolved
module Formatting {
/**
* Gets a regular expression for matching simple format-string components, including flags,
* width and precision specifiers, but not including `*` specifiers or explicit argument
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I know this code is just being moved, so you didn't introduce this.) It seems to me that this regex does support * specifiers, so perhaps we should update the qldoc. Looking at the history it seems it was always this way, so perhaps I am missing something.

Also, would it be worth updating this to include explicit argument indices? There are only so many places they can go, so it seems fiddly but doable to me.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've amended this to mention that * specifiers are indeed accepted, but explicit indices are not.

We can include them, but we would need to do more work besides since both * specifiers and [n] specifiers (whether on a * or on the main formatting verb) require us to do a stateful left-to-right parse rather than our current stateless parse in order to get the arg <-> format verb alignment correct. I'd suggest pursuing this as a separate task.

formatDirective = this.getComponent(n) and
formatDirective.charAt(0) = "%" and
formatDirective.charAt(1) != "%" and
result = this.getArgument((n / 2) + f.getFirstFormattedParameterIndex())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I know this code is just being moved, so you didn't introduce this.) It seems to me that the n / 2 assumes that the format string starts with a literal, and hence alternates literal, verb, literal, verb, ... . If the format string starts with a literal won't we get verb, literal, verb, literal, ... Actually I guess we could have two verbs in a row, and mess things up that way as well. I guess the fix would be to replace n / 2 with count(int m | 0 <= m and m < n and not this.getComponent(m).regexpMatch(getLiteralRegex()) | m).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two alternating cases are fine, since the verbs either have indices 0, 2, 4, 6 or 1, 3, 5, 7, and integer division rounds down, so in either case n / 2 is 0, 1, 2, 3.

The case where there are successive verbs without any interspersed literal is however broken as you say. To fix, now with somewhat increased priority since that's going to happen pretty frequently.

smowton and others added 2 commits January 10, 2022 10:24
Rename class

Co-authored-by: Owen Mansel-Chan <62447351+owen-mc@users.noreply.github.com>
@smowton
Copy link
Contributor Author

smowton commented Jan 10, 2022

I've done the easy fixes here, and suggest we make three followups with increasing difficulty and decreasing priority:

  • Handle adjacent verbs
  • Notice that using * directives causes one verb to consume 1-3 arguments
  • Support [n] directives in any of the three contexts where they can occur altering the next arg index to read.

Copy link
Contributor

@owen-mc owen-mc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants