├── .img └── shrooms.jpg ├── LICENSE └── README.md /.img/shrooms.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xdea/weggli-patterns/HEAD/.img/shrooms.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 raptor 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # weggli-patterns 2 | 3 | [![](https://img.shields.io/github/stars/0xdea/weggli-patterns.svg?style=flat&color=yellow)](https://github.com/0xdea/weggli-patterns) 4 | [![](https://img.shields.io/github/forks/0xdea/weggli-patterns.svg?style=flat&color=green)](https://github.com/0xdea/weggli-patterns) 5 | [![](https://img.shields.io/github/watchers/0xdea/weggli-patterns.svg?style=flat&color=red)](https://github.com/0xdea/weggli-patterns) 6 | [![](https://img.shields.io/badge/twitter-%400xdea-blue.svg)](https://twitter.com/0xdea) 7 | [![](https://img.shields.io/badge/mastodon-%40raptor-purple.svg)](https://infosec.exchange/@raptor) 8 | 9 | > "No one cares about the old scene people anymore, I’m sure, 10 | > bunch of old people grepping for the last of the memcpy." 11 | > 12 | > -- Bas Alberts 13 | 14 | A collection of my weggli patterns to facilitate vulnerability research. 15 | 16 | ![](https://raw.githubusercontent.com/0xdea/weggli-patterns/main/.img/shrooms.jpg) 17 | 18 | ## Blog post 19 | 20 | * 21 | 22 | ## See also 23 | 24 | * 25 | * 26 | * 27 | * 28 | * 29 | * 30 | 31 | *Note: By default, weggli scans `.c` and `.h` files. To enable C++ mode and thus scan `.cc`, `.cpp`, `.cxx`, `.h`, and `.hpp` files, you must specify the `-X` command-line flag. Alternative file endings can be specified using the `-e` flag. Please refer to weggli's [usage documentation](https://github.com/weggli-rs/weggli?tab=readme-ov-file#usage) for additional information.* 32 | 33 | ## Patterns 34 | 35 | ### buffer overflows 36 | 37 | #### call to unbounded copy functions (CWE-120, CWE-242, CWE-676) 38 | 39 | ``` 40 | weggli -R 'func=^gets$' '{$func();}' . 41 | weggli -R 'func=st(r|p)(cpy|cat)$' '{$func();}' . 42 | weggli -R 'func=wc(s|p)(cpy|cat)$' '{$func();}' . 43 | weggli -R 'func=mb(s|p)(cpy|cat)$' '{$func();}' . 44 | weggli -R 'func=sprintf$' '{$func();}' . 45 | weggli -R 'func=scanf$' '{$func();}' . 46 | ``` 47 | 48 | #### incorrect use of strncat (CWE-193, CWE-787) 49 | 50 | ``` 51 | weggli '{strncat(_,_,sizeof(_));}' . 52 | weggli '{strncat(_,_,strlen(_));}' . 53 | weggli '{strncat($dst,$src,sizeof($dst)-strlen($dst));}' . 54 | weggli '{_ $buf[$len]; strncat($buf,_,$len);}' . 55 | ``` 56 | 57 | The last pattern won't work with integer literals due to [known limitations](https://github.com/weggli-rs/weggli/issues/59). 58 | 59 | #### destination buffer access using size of source buffer (CWE-806) 60 | 61 | ``` 62 | weggli -R 'func=cpy$' '{$func(_,$src,_($src));}' . 63 | weggli -R 'func=cpy$' '{$len=_($src); $func(_,$src,$len);}' . 64 | weggli -R 'func=cpy$' '{_ $src[$len]; $func($dst,$src,$len);}' . 65 | ``` 66 | 67 | The last pattern won't work with integer literals due to [known limitations](https://github.com/weggli-rs/weggli/issues/59). 68 | 69 | #### use of sizeof() on a pointer type (CWE-467) 70 | 71 | ``` 72 | weggli '{_* $ptr; sizeof($ptr);}' . 73 | weggli '{_* $ptr=_; sizeof($ptr);}' . 74 | weggli '_ $func(_* $ptr) {sizeof($ptr);}' . 75 | ``` 76 | 77 | Apparently, global variables are not supported so this won't work: 78 | 79 | ``` 80 | weggli '_* $ptr=_; _ $func(_) {sizeof($ptr);}' . 81 | ``` 82 | 83 | #### use of sizeof() on a character constant 84 | 85 | ``` 86 | weggli "sizeof('_')" . 87 | ``` 88 | 89 | In C (but not in C++) character constants have type int. 90 | 91 | #### lack of explicit NUL-termination after strncpy(), etc. (CWE-170) 92 | 93 | ``` 94 | weggli -R 'func=ncpy$' '{$func($buf,_); not:$buf[_]=_;}' . 95 | ``` 96 | 97 | Some possible variants: memcpy, read, readlink, fread, etc. 98 | 99 | #### off-by-one error (CWE-193) 100 | 101 | ``` 102 | weggli '{$buf[sizeof($buf)];}' . 103 | weggli '{_ $buf[$len]; $buf[$len]=_;}' . 104 | weggli '{strlen($src)>sizeof($dst);}' . 105 | weggli '{strlen($src)<=sizeof($dst);}' . 106 | weggli '{sizeof($dst)=strlen($src);}' . 108 | weggli '{$buf[strlen($buf)-1];}' . 109 | weggli -R 'func=allocf?$' '{$func(strlen($buf));}' . 110 | weggli -R 'func=allocf?$' '{$len=strlen(_); $ptr=$func($len);}' . 111 | weggli -R 'func=allocf?$' '{$len=snprintf(_); $ptr=$func($len);}' . 112 | ``` 113 | 114 | The second pattern won't work with integer literals due to [known limitations](https://github.com/weggli-rs/weggli/issues/59). 115 | `<` should also cover `>` and `<=` should also cover `>=`; however, let's keep all variants just to be sure. 116 | 117 | #### use of pointer subtraction to determine size (CWE-469) 118 | 119 | ``` 120 | weggli '{_* $ptr1; $ptr1-$ptr2;}' . 121 | weggli '{_* $ptr2; $ptr1-$ptr2;}' . 122 | weggli '{_* $ptr1=_; $ptr1-$ptr2;}' . 123 | weggli '{_* $ptr2=_; $ptr1-$ptr2;}' . 124 | weggli '_ $func(_* $ptr1) {$ptr1-$ptr2;}' . 125 | weggli '_ $func(_* $ptr2) {$ptr1-$ptr2;}' . 126 | ``` 127 | 128 | #### potentially unsafe use of the return value of snprintf(), etc. (CWE-787) 129 | 130 | ``` 131 | weggli -R 'func=(nprintf|lcpy|lcat)$' '{$ret=$func();}' . 132 | ``` 133 | 134 | #### direct write into buffer allocated on the stack (CWE-121) 135 | 136 | ``` 137 | weggli -R 'func=(cpy|cat|memmove|memset|sn?printf)$' '{_ $buf[_]; $func($buf,_);}' . 138 | weggli '{_ $buf[_]; $buf[_]=_;}' . 139 | ``` 140 | 141 | Some possible variants: bcopy, gets, fgets, getwd, getcwd, fread, read, pread, recv, recvfrom, etc. 142 | 143 | ### integer overflows 144 | 145 | #### incorrect unsigned comparison (CWE-697) 146 | 147 | ``` 148 | weggli -R '$type=(unsigned|size_t)' '{$type $var; $var<0;}' . 149 | weggli -R '$type=(unsigned|size_t)' '{$type $var; $var<=0;}' . 150 | weggli -R '$type=(unsigned|size_t)' '{$type $var; $var>=0;}' . 151 | weggli -R '$type=(unsigned|size_t)' '{$type $var=_; $var<0;}' . 152 | weggli -R '$type=(unsigned|size_t)' '{$type $var=_; $var<=0;}' . 153 | weggli -R '$type=(unsigned|size_t)' '{$type $var=_; $var>=0;}' . 154 | ``` 155 | 156 | `<` should also cover `>` and `<=` should also cover `>=`; however, let's keep all variants just to be sure. 157 | 158 | #### signed/unsigned conversion (CWE-195, CWE-196) 159 | 160 | ``` 161 | weggli -R '$copy=(cpy|ncat)$' '{int $len; $copy(_,_,$len);}' . 162 | weggli -R '$copy=(cpy|ncat)$' '{int $len=_; $copy(_,_,$len);}' . 163 | weggli -R '$copy=(cpy|ncat)$' '_ $func(int $len) {$copy(_,_,$len);}' . 164 | 165 | weggli -R '$copy=nprintf$' '{int $len; $copy(_,$len);}' . 166 | weggli -R '$copy=nprintf$' '{int $len=_; $copy(_,$len);}' . 167 | weggli -R '$copy=nprintf$' '_ $func(int $len) {$copy(_,$len);}' . 168 | 169 | weggli -R '$type=(unsigned|size_t)' '{$type $var1; int $var2; $var2=_($var1);}' . 170 | weggli -R '$type=(unsigned|size_t)' '{$type $var1; int $var2; $var1=_($var2);}' . 171 | weggli -R '$type=(unsigned|size_t)' '{$type $var1; int $var2=_($var1);}' . 172 | weggli -R '$type=(unsigned|size_t)' '{int $var1; $type $var2; $var2=_($var1);}' . 173 | weggli -R '$type=(unsigned|size_t)' '{int $var1; $type $var2; $var1=_($var2);}' . 174 | weggli -R '$type=(unsigned|size_t)' '{int $var1=_; $type $var2=_($var1);}' . 175 | 176 | weggli -R '$type=(unsigned|size_t)' '_ $func(int $var2) {$type $var1; $var1=_($var2);}' . 177 | weggli -R '$type=(unsigned|size_t)' '_ $func(int $var2) {$type $var1=_($var2);}' . 178 | 179 | weggli -R '$type=(unsigned|size_t)' '$type $func(_) {int $var; return $var;}' . 180 | weggli -R '$type=(unsigned|size_t)' 'int $func(_) {$type $var; return $var;}' . 181 | ``` 182 | 183 | There are many possible variants of these patterns... 184 | 185 | #### integer truncation (CWE-197) 186 | 187 | ``` 188 | weggli -R 'type=(short|int|long)' '{$type $large; char $narrow; $narrow = $large; }' . 189 | weggli -R 'type=(short|int|long)' '{$type $large; char $narrow = $large; }' . 190 | weggli -R 'type=(int|long)' '{$type $large; short $narrow; $narrow = $large; }' . 191 | weggli -R 'type=(int|long)' '{$type $large; short $narrow = $large; }' . 192 | weggli '{long $large; int $narrow; $narrow = $large; }' . 193 | weggli '{long $large; int $narrow = $large; }' . 194 | 195 | weggli -R 'type=(short|int|long)' '_ $func($type $large) {char $narrow; $narrow = $large; }' . 196 | weggli -R 'type=(short|int|long)' '_ $func($type $large) {char $narrow = $large; }' . 197 | weggli -R 'type=(int|long)' '_ $func($type $large) {short $narrow; $narrow = $large; }' . 198 | weggli -R 'type=(int|long)' '_ $func($type $large) {short $narrow = $large; }' . 199 | weggli '_ $func(long $large) {int $narrow; $narrow = $large; }' . 200 | weggli '_ $func(long $large) {int $narrow = $large; }' . 201 | ``` 202 | 203 | There are many possible variants of these patterns... 204 | 205 | #### use of signed or short sizes, lengths, offsets, counts (CWE-190, CWE-680) 206 | 207 | ``` 208 | weggli 'short _' . 209 | weggli 'int _' . 210 | ``` 211 | 212 | Some possible variants: short int, unsigned short, unsigned short int, int. 213 | 214 | #### cast of the return value of strlen(), wcslen(), _mbslen(), etc. to short (CWE-190, CWE-680) 215 | 216 | ``` 217 | weggli -R 'func=(str|wcs|mbs)n?len$' '{short $len; $len=$func();}' . 218 | ``` 219 | 220 | Some possible variants: short int, unsigned short, unsigned short int, even signed int. 221 | 222 | #### integer wraparound (CWE-128, CWE-131, CWE-190, CWE-680) 223 | 224 | ``` 225 | weggli -R 'func=allocf?$' '{$func(_*_);}' . 226 | weggli -R 'func=allocf?$' '{$func(_+_);}' . 227 | weggli -R 'func=allocf?$' '{$n=_*_; $func($n);}' . 228 | weggli -R 'func=allocf?$' '{$n=_+_; $func($n);}' . 229 | 230 | weggli -R 'alloc=allocf?$' -R 'copy=cpy$' '{$alloc($x*_); $copy(_,_,$x);}' . 231 | weggli -R 'alloc=allocf?$' -R 'copy=cpy$' '{$alloc($x+_); $copy(_,_,$x);}' . 232 | weggli -u -R 'alloc=allocf?$' -R 'copy=cpy$' '{$n=_*_; $alloc($n); $copy(_,_,$x);}' . 233 | weggli -u -R 'alloc=allocf?$' -R 'copy=cpy$' '{$n=_+_; $alloc($n); $copy(_,_,$x);}' . 234 | 235 | weggli '{$x>_||($x+$y)>_;}' . 236 | weggli '{$x>=_||($x+$y)>_;}' . 237 | weggli '{$x>_||($x+$y)>=_;}' . 238 | weggli '{$x>=_||($x+$y)>=_;}' . 239 | weggli '{$x<_&&($x+$y)<_;}' . 240 | weggli '{$x<=_&&($x+$y)<_;}' . 241 | weggli '{$x<_&&($x+$y)<=_;}' . 242 | weggli '{$x<=_&&($x+$y)<=_;}' . 243 | 244 | weggli '{$x>_||($x*$y)>_;}' . 245 | weggli '{$x>=_||($x*$y)>_;}' . 246 | weggli '{$x>_||($x*$y)>=_;}' . 247 | weggli '{$x>=_||($x*$y)>=_;}' . 248 | weggli '{$x<_&&($x*$y)<_;}' . 249 | weggli '{$x<=_&&($x*$y)<_;}' . 250 | weggli '{$x<_&&($x*$y)<=_;}' . 251 | weggli '{$x<=_&&($x*$y)<=_;}' . 252 | ``` 253 | 254 | `<` should also cover `>` and `<=` should also cover `>=`; however, let's keep all variants just to be sure. 255 | 256 | ### format strings 257 | 258 | #### call to printf(), scanf(), syslog() family functions (CWE-134) 259 | 260 | ``` 261 | weggli -R 'func=(printf|scanf|syslog)$' '{$func();}' . 262 | ``` 263 | 264 | Some possible variants: printk, warn, vwarn, warnx, vwarnx, err, verr, errx, verrx, warnc, vwarnc, errc, verrc, etc. 265 | 266 | ### memory management 267 | 268 | #### call to alloca() (CWE-676, CWE-1325) 269 | 270 | ``` 271 | weggli -R 'func=alloca$' '{$func();}' . 272 | ``` 273 | 274 | #### use after free (CWE-416) 275 | 276 | ``` 277 | weggli '{free($ptr); not:$ptr=_; not:free($ptr); _($ptr);}' . 278 | ``` 279 | 280 | #### double free (CWE-415) 281 | 282 | ``` 283 | weggli '{free($ptr); not:$ptr=_; free($ptr);}' . 284 | ``` 285 | 286 | #### calling free() on memory not allocated in the heap (CWE-590) 287 | 288 | ``` 289 | weggli '{_ $ptr[]; free($ptr);}' . 290 | weggli '{_ $ptr[]=_; free($ptr);}' . 291 | 292 | weggli '{_ $ptr[]; $ptr2=$ptr; free($ptr2);}' . 293 | weggli '{_ $ptr[]=_; $ptr2=$ptr; free($ptr2);}' . 294 | 295 | weggli '{_ $var; free(&$var);}' . 296 | weggli '{_ $var=_; free(&$var);}' . 297 | weggli '{_ $var[]; free(&$var);}' . 298 | weggli '{_ $var[]=_; free(&$var);}' . 299 | weggli '{_ *$var; free(&$var);}' . 300 | weggli '{_ *$var=_; free(&$var);}' . 301 | 302 | weggli '{$ptr=alloca(_); free($ptr);}' . 303 | ``` 304 | 305 | #### returning the address of a stack-allocated variable (CWE-562) 306 | 307 | ``` 308 | weggli '{_ $ptr[]; return $ptr;}' . 309 | weggli '{_ $ptr[]=_; return $ptr;}' . 310 | 311 | weggli '{_ $ptr[]; $ptr2=$ptr; return $ptr2;}' . 312 | weggli '{_ $ptr[]=_; $ptr2=$ptr; return $ptr2;}' . 313 | 314 | weggli '{_ $var; return &$var;}' . 315 | weggli '{_ $var=_; return &$var;}' . 316 | weggli '{_ $var[]; return &$var;}' . 317 | weggli '{_ $var[]=_; return &$var;}' . 318 | weggli '{_ *$var; return &$var;}' . 319 | weggli '{_ *$var=_; return &$var;}' . 320 | ``` 321 | 322 | #### unchecked return code of malloc(), etc. (CWE-252, CWE-690) 323 | 324 | ``` 325 | weggli -R 'func=allocf?$' '{$ret=$func(); not:if(_($ret)){};}' . 326 | ``` 327 | 328 | #### call to putenv() with a stack-allocated variable (CWE-686) 329 | 330 | ``` 331 | weggli '{_ $ptr[]; putenv($ptr);}' . 332 | weggli '{_ $ptr[]=_; putenv($ptr);}' . 333 | 334 | weggli '{_ $ptr[]; $ptr2=$ptr; putenv($ptr2);}' . 335 | weggli '{_ $ptr[]=_; $ptr2=$ptr; putenv($ptr2);}' . 336 | ``` 337 | 338 | #### exposure of underlying memory addresses (CWE-200, CWE-209, CWE-497) 339 | 340 | ``` 341 | weggli -R 'func=printf$' -R 'fmt=(.*%\w*x.*|.*%\w*X.*|.*%\w*p.*)' '{$func("$fmt");}' . 342 | ``` 343 | 344 | #### mismatched memory management routines (CWE-762) 345 | 346 | ``` 347 | weggli -R 'func=allocf?$|strdn?up$' '{not:$ptr=$func(); free($ptr);}' . 348 | 349 | weggli --cpp -R 'func=allocf?$|strn?dup$' '{not:$ptr=$func(); free($ptr);}' . 350 | weggli --cpp '{not:$ptr=new $obj; delete $ptr;}' . 351 | ``` 352 | 353 | Apparently, delete[] is not supported so this won't work properly: 354 | 355 | ``` 356 | weggli --cpp '{not:$ptr=new $obj[$len]; delete[] $ptr;}' . 357 | ``` 358 | 359 | #### use of uninitialized pointers (CWE-457, CWE-824, CWE-908) 360 | 361 | ``` 362 | weggli '{_* $ptr; not:$ptr=_; not:_(&$ptr); $func($ptr);}' . 363 | weggli '{_* $ptr; not:$ptr=_; not:_(&$ptr); _($ptr);}' . 364 | ``` 365 | 366 | These patterns might generate many false positives that should be manually investigated. 367 | 368 | ### command injection 369 | 370 | #### call to system(), popen() (CWE-78, CWE-88, CWE-676) 371 | 372 | ``` 373 | weggli -R 'func=(system|popen)$' '{$func();}' . 374 | weggli -R 'func=(system|popen)$' '{$func($arg);}' . 375 | ``` 376 | 377 | The second pattern is meant to filter out string literals, but it might cause some false negatives. 378 | 379 | ### race conditions 380 | 381 | #### call to access(), stat(), lstat() (CWE-367) 382 | 383 | ``` 384 | weggli -R 'func=(access|l?stat)$' '{$func();}' . 385 | ``` 386 | 387 | #### call to mktemp(), tmpnam(), tempnam() (CWE-377) 388 | 389 | ``` 390 | weggli -R 'func=(mktemp|te?mpnam)$' '{$func();}' . 391 | ``` 392 | 393 | #### call to signal() (CWE-364, CWE-479, CWE-828) 394 | 395 | ``` 396 | weggli -R 'func=signal$' '{$func();}' . 397 | ``` 398 | 399 | ### privilege management 400 | 401 | #### privilege management functions called in the wrong order (CWE-696) 402 | 403 | ``` 404 | weggli '{not:setuid(0); setuid(); setgid();}' . 405 | weggli '{not:seteuid(0); seteuid(); not:seteuid(0); setegid();}' . 406 | weggli '{not:seteuid(0); seteuid(); not:seteuid(0); setuid();}' . 407 | weggli '{not:seteuid(0); seteuid(); not:seteuid(0); seteuid();}' . 408 | ``` 409 | 410 | #### unchecked return code of setuid(), seteuid() (CWE-252) 411 | 412 | ``` 413 | weggli -R 'func=sete?uid$' '{strict:$func();}' . 414 | ``` 415 | 416 | ### miscellaneous 417 | 418 | #### wrong order of arguments in call to memset() 419 | 420 | ``` 421 | weggli -R 'func=memset(_explicit)?$' '{$func(_,_,0);}' . 422 | weggli -R 'func=memset(_explicit)?$' '{$func(_,sizeof(_),_);}' . 423 | ``` 424 | 425 | #### call to rand(), srand() (CWE-330, CWE-338) 426 | 427 | ``` 428 | weggli -R 'func=s?rand$' '{$func();}' . 429 | ``` 430 | 431 | #### source and destination overlap in sprintf(), snprintf() 432 | 433 | ``` 434 | weggli -R 'func=^sn?printf$' '{$func($dst,_,$dst);}' . 435 | weggli -R 'func=^sn?printf$' '{$func($dst,_,_,$dst);}' . 436 | weggli -R 'func=^sn?printf$' '{$func($dst,_,_,_,$dst);}' . 437 | ``` 438 | 439 | And so on... 440 | 441 | #### size check implemented with an assertion macro 442 | 443 | ``` 444 | weggli -R 'assert=(?i)^\w*assert\w*\s*$' '{$assert(_<_);}' . 445 | weggli -R 'assert=(?i)^\w*assert\w*\s*$' '{$assert(_<=_);}' . 446 | weggli -R 'assert=(?i)^\w*assert\w*\s*$' '{$assert(_>_);}' . 447 | weggli -R 'assert=(?i)^\w*assert\w*\s*$' '{$assert(_>=_);}' . 448 | ``` 449 | 450 | `<` should also cover `>` and `<=` should also cover `>=`; however, let's keep all variants just to be sure. 451 | 452 | #### unchecked return code of scanf(), etc. (CWE-252) 453 | 454 | ``` 455 | weggli -R 'func=scanf$' '{strict:$func();}' . 456 | ``` 457 | 458 | #### call to atoi(), atol(), atof(), atoll() 459 | 460 | ``` 461 | weggli -R 'func=ato(i|ll?|f)$' '{$func();}' . 462 | ``` 463 | 464 | #### command-line argument or environment variable access 465 | 466 | ``` 467 | weggli -R 'var=argv|envp' '{$var[_];}' . 468 | ``` 469 | 470 | #### missing default case in a switch construct (CWE-478) 471 | 472 | ``` 473 | weggli -l 'switch(_) {_; not:default:_; _;}' . 474 | ``` 475 | 476 | `-l` might be overkill and lead to missing additional matches in the same function. 477 | 478 | #### missing break or equivalent statement in a switch construct (CWE-484) 479 | 480 | ``` 481 | weggli -l 'switch(_) {case _: not:break; not:exit; not:return; not:goto _; case _:_;}' . 482 | ``` 483 | 484 | `-l` might be overkill and lead to missing additional matches in the same function. 485 | 486 | #### missing return statement in a non-void function (CWE-393, CWE-394) 487 | 488 | ``` 489 | weggli -R 'type!=void' '$type $func(_) {_; not:return;}' . 490 | ``` 491 | 492 | #### typos with security implications (CWE-480, CWE-481, CWE-482, CWE-483) 493 | 494 | ``` 495 | weggli '{for (_==_;_;_) {}}' . 496 | weggli 'if (_=_) {}' . 497 | weggli 'if (_&_) {}' . 498 | weggli 'if (_|_) {}' . 499 | weggli '{_=+_;}' . 500 | weggli '{_=-_;}' . 501 | weggli -R 'func=strn?cpy$' 'if ($func()==_) {}' . 502 | ``` 503 | 504 | There are many possible additional patterns in this category... 505 | 506 | #### keywords that suggest the presence of bugs 507 | 508 | ``` 509 | weggli -R 'pattern=(?i)(unsafe|insecure|dangerous|warning|overflow)' '$pattern' . 510 | 511 | weggli -R 'func=(?i)(encode|decode|convert|interpret|compress|fragment|reassemble)' '_ $func(_) {}' . 512 | weggli -R 'func=(?i)(mutex|lock|toctou|parallelism|semaphore|retain|release|garbage|mutual)' '_ $func(_) {}' . 513 | ``` 514 | 515 | There are many possible additional patterns in this category... 516 | --------------------------------------------------------------------------------