Hey folks, hitting a weird Semgrep error and could use a second pair of eyes. I'm trying to write a rule to catch a specific Express.js middleware misconfiguration.
My pattern looks like this:
`app.use(session({ cookie: { secure: false } }))`
But I keep getting "invalid pattern" with a parse error pointing at the curly braces. I've tried escaping them, using metavariables, but no luck. Feels like it should be straightforward?
Anyone run into this with nested objects in patterns? Is there a specific syntax for matching object literals inside function calls? Thanks! 😅
measure twice, ship once
Yep, curly braces in Semgrep patterns are tricky. For nested objects, try using metavariables for the inner structure. Something like `app.use(session({ cookie: $C }))` and then add a `metavariable-regex` for `$C` to match `{ secure: false }`. The parser often stumbles on literal braces inside a call.
Also, make sure your pattern language is set to JavaScript, not generic. That got me once.
Automate the boring stuff.
Oh, using a metavariable with a regex for the inner part is smart. I haven't tried `metavariable-regex` before.
Just to clarify, for the regex pattern, would it be something like `secure:s*false`? Or does it need to match the braces too?
Still learning.
Yeah, curly braces in Semgrep patterns are the worst. I had the same issue last week trying to match a config object. The parser really doesn't like them inside function calls.
What finally worked for me was using a metavariable for the whole argument, like `app.use(session($CONFIG))`. Then I added a `pattern` inside the rule to match `$CONFIG` against `{ cookie: { secure: false } }`. That way the braces are in a separate pattern and the parser doesn't get confused.
Maybe give that a shot? Let me know if it works for you!
CloudNewbie
That nested object syntax is a known headache. I ran into the same thing trying to match a DynamoDB config.
Following user254's approach of moving the whole object to a separate `pattern` clause works, but I've also had luck with a simpler metavariable. Try `app.use(session($ARG))` and then define the inner pattern in the rule's `patterns` list.
Does the error go away if you just target the outer function call first?
Yep, the curly braces in Semgrep patterns are a classic tripwire. The parser just isn't built to handle nested object literals as part of a direct expression.
While the metavariable workarounds folks are suggesting will technically work, it's honestly a pretty stark reminder of the limits of these free-tier SaaS tools. You're jumping through hoops to match a basic, valid JavaScript pattern because their parser can't handle it.
Sometimes the simplest answer is that the tool's core pattern language is... finicky. Makes you wonder what you're really getting in the paid tiers, doesn't it? More parser exceptions?
—DW
The regex would indeed need to match the braces and the whitespace pattern. For a `metavariable-regex` on `$C`, the pattern would look like `{.*secure:s*false.*}`. Be mindful that this is quite permissive and will match any object containing that key-value pair anywhere inside it, which might be too broad.
A more precise alternative is to use the `metavariable-pattern` key, which lets you nest a full Semgrep pattern for the metavariable. This avoids regex entirely and allows for exact structural matching.
```yaml
patterns:
- pattern: app.use(session({ cookie: $C }))
- metavariable-pattern:
metavariable: $C
pattern: '{ secure: false }'
```
That's typically safer than a regex for this use case.
throughput is truth