forked from floyd-fuh/crass
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrep-it.sh
executable file
·5473 lines (4580 loc) · 226 KB
/
grep-it.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#!/bin/bash
#
# A simple greper for code, loot, IT-tech-stuff-the-customer-throws-at-you.
# Tries to find IT security and privacy related stuff.
# For pentesters.
#
# ----------------------------------------------------------------------------
# "THE BEER-WARE LICENSE" (Revision 42):
# <floyd at floyd dot ch> wrote this file. As long as you retain this notice you
# can do whatever you want with this stuff. If we meet some day, and you think
# this stuff is worth it, you can buy me a beer in return
# floyd http://floyd.ch @floyd_ch <floyd at floyd dot ch>
# July 2013
# ----------------------------------------------------------------------------
#
# Requirements:
# - GNU grep. If you have OSX, install from ports or so. Reason: we need regex match -P
# - rm command. Reason: if grep doesn't match anything we remove the corresponding output file
# - mkdir command. Reason: we need to make the $TARGET directory
# - jobs, wait and wc command, if you want to run multiple grep in the background.
#
# Howto:
# - Customize the "OPTIONS" section below to your needs
# - Copy this file to the parent directory which you want to grep
# - run it like this: ./grep-it.sh ./directory-to-grep-through/
#
# Output:
# Default output is optimised to be viewed with "less -SR ./grep-output/*" and then you can hop from one file to the next with :n
# and :p. The cat command works fine. If you want another editor you should probably remove --color=always and other grep arguments
# Output files have the following naming conventions (separated by underscore):
# - priority: 1-9, where 1 is more interesting (low false positive rate, certainty of "vulnerability") and 9 is only "you might want to have a look when you are desperately looking for vulns"
# - section: eg. java or php
# - name of what we looked for
#
# Related work:
# - You should definitely check out https://semgrep.dev/ but be aware that if you run the default example with --config=auto it will send metrics to their servers! Here's my first imperession of semgrep as of April 2022 https://twitter.com/floyd_ch/status/1513506364357853193
# - https://www.owasp.org/index.php/Static_Code_Analysis
# - https://samate.nist.gov/index.php/Source_Code_Security_Analyzers.html
# - https://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis
###
#OPTIONS - please customize
###
#Which grep to use:
#Most people don't need to change this. Here's why:
#It first looks for the following binary file:
GREP_COMMAND="/opt/local/bin/ggrep"
#If that fails it will look for "ggrep" in $PATH
#If that fails it will look for "grep" in $PATH
#Do not remove -rP if you don't know what you are doing, otherwise you probably break this script
GREP_ARGUMENTS="-n -A 1 -B 3 -rP"
#my tests with a tool called ripgrep showed there is no real benefit in using it for this script... please go and proof me wrong
#Open the colored outputs with "less -R" or cat, otherwise remove --color=always (not recommended, colors help to find the matches in huge text files)
COLOR_ARGUMENTS="--color=always"
#Output folder if not otherwise specified on the command line
TARGET="./grep-output"
#Write the comment to each file at the beginning
WRITE_COMMENT="true"
#Sometimes we look for composite words with wildcard, eg. root.{0,20}detection, this is the maximum
#of random characters that can be in between. The higher the value the more strings will potentially be flagged.
WILDCARD_SHORT=20
WILDCARD_LONG=200
#Do all greps in background with & while only using MAX_PROCESSES subprocesses
BACKGROUND="false"
MAX_PROCESSES=2 #if you specify the number of cpu cores you have, it should roughly use 100% CPU
#Enable the least likely rules where the files start with "9_"
ENABLE_LEAST_LIKELY="false"
#In my opinion I would always leave all the options below here on true,
#because I did find strange android code in iphone apps and even entire PHP server side code in Android apps. I would only
#change it if grep needs very long, you are greping a lot of stuff
#or if you have any other performance issues with this script.
DO_JAVA="true"
DO_JSP="true"
DO_SPRING="true"
DO_STRUTS="true"
DO_FLEX="true"
DO_DOTNET="true"
DO_PHP="true"
DO_HTML="true"
DO_JAVASCRIPT="true"
DO_MODSECURITY="true"
DO_MOBILE="true"
DO_ANDROID="true"
DO_IOS="true"
DO_PYTHON="true"
DO_RUBY="true"
DO_AZURE="true"
#C and derived languages
DO_C="true"
DO_MALWARE_DETECTION="true"
DO_CRYPTO_AND_CREDENTIALS="true"
DO_API_KEYS="true"
DO_ASSEMBLY_NATIVE_API="true"
DO_GENERAL="true"
###
#END OPTIONS
#Normally you don't have to change anything below here...
###
###
#CODE SECTION
#As a user of this script you shouldn't need to care about the stuff that is coming down here...
###
# Conventions if you add new regexes:
# - First think about which sections you want to put a new rule
# - Don't use * in regex but use {0,X} instead. See WILDCARD_ variables for configurable values of X.
# - When using character classes in regexes such as [A-Za-z] and you have to include the dash, make it the last element: [A-Za-z-]
# - make sure functions calls with space before bracket will be found if the language supports it, e.g. "extract (bla)" is allowed in PHP
# - If in doubt, prefer to make two regex and output files rather then joining regexes with |. If one produces false positives it is really annoying to search for the true positives of the other regex.
# - If your regex matches less than 6 characters (eg. "salt"), do not make it case insensitive as this usually produces more false positives. Rather split into several regexes (eg. one file with case-sensitive matches for "[Ss]alt", one file with case-sensitive matches for "SALT". This way we remove false positives for removesAlternativeName and such).
# - Run this script with DEBUG_TEST_FLAG="true" to see if everything works fine or if you made copy&paste mistakes etc.
# - Take care with single/double quoted strings. From the bash manual:
# 3.1.2.2 Single Quotes
# Enclosing characters in single quotes (‘'’) preserves the literal value of each character within the quotes. A single quote may not occur between single quotes, even when preceded by a backslash.
# 3.1.2.3 Double Quotes
# Enclosing characters in double quotes (‘"’) preserves the literal value of all characters within the quotes, with the exception of ‘$’, ‘`’, ‘\’, and, when history expansion is enabled, ‘!’. The characters ‘$’ and ‘`’ retain their special meaning within double quotes (see Shell Expansions). The backslash retains its special meaning only when followed by one of the following characters: ‘$’, ‘`’, ‘"’, ‘\’, or newline. Within double quotes, backslashes that are followed by one of these characters are removed. Backslashes preceding characters without a special meaning are left unmodified. A double quote may be quoted within double quotes by preceding it with a backslash. If enabled, history expansion will be performed unless an ‘!’ appearing in double quotes is escaped using a backslash. The backslash preceding the ‘!’ is not removed. The special parameters ‘*’ and ‘@’ have special meaning when in double quotes (see Shell Parameter Expansion).
#
# TODO short term:
# - From this line on https://github.com/random-robbie/keywords/blob/master/keywords.txt#L77
# - Nothing :)
#
# TODO longterm (aka "probably never but I know I should"):
# - Improve comments everywhere
# - Add comments about case-sensitivity and whitespace behavior of languages and other syntax rules that might influence our regexes
# - Duplicate a couple of regexes to ones that *only* have true positives usually (or at least a lot less false positives)
# - Have a look at/implement&reference rules:
# - Files starting with mod* at https://github.com/nccgroup/VCG/tree/master/VisualCodeGrepper
# - http://findbugs.sourceforge.net/bugDescriptions.html
# - https://web.archive.org/web/20190110052404/https://bishopfox.com/resources/downloads/
# - https://pmd.github.io/
# - https://msdn.microsoft.com/en-us/library/aa449703.aspx
# - http://www.splint.org/
#When the following flag is enable the tool switches to testing mode and won't do the actual work
DEBUG_TEST_FLAG="false"
#A helper var for debugging purposes
DEBUG_TMP_OUTFILE_NAMES=""
if [ $# -lt 1 ]
then
echo "Usage: $(basename $0) directory-to-grep-through"
exit 0
fi
if [ "$1" = "." ]
then
echo "You are shooting yourself in the foot. Do not grep through . but rather cd into parent directory and mv $(basename $0) there."
echo "READ THE HOWTO (3 lines)"
exit 0
fi
if [ $# -eq 2 ]
then
#argument without last /
TARGET=${2%/}
fi
if [ ! -f "$GREP_COMMAND" ]
then
GREP_COMMAND="ggrep"
if ! command -v $GREP_COMMAND &> /dev/null
then
GREP_COMMAND="grep"
if ! command -v $GREP_COMMAND &> /dev/null
then
echo "Could not find a usable 'grep'"
exit 1
fi
fi
fi
echo "Using grep binary $GREP_COMMAND"
STANDARD_GREP_ARGUMENTS="$GREP_ARGUMENTS $COLOR_ARGUMENTS"
#argument without last /
SEARCH_FOLDER=${1%/}
mkdir "$TARGET"
if [ "$DEBUG_TEST_FLAG" = "true" ]; then
echo "WE ARE RUNNING IN TEST MODE. NOT DOING THE ACTUAL WORK, JUST VERIFYING THIS SCRIPT IS DOING WHAT IT SHOULD."
echo "If you want to run in normal mode, set DEBUG_TEST_FLAG to false"
fi
echo "Your standard grep arguments (customize in OPTIONS section of this script): $STANDARD_GREP_ARGUMENTS"
echo "Output will be put into this folder: $TARGET"
echo "You are currently greping through folder: $SEARCH_FOLDER"
sleep 2
function search()
{
if [ "$DEBUG_TEST_FLAG" = "true" ]; then
test_run "$@"
else
#Decide if doing in background or not
if [ "$BACKGROUND" = "true" ]; then
#make sure we don't fork-bomb, so run at max $MAX_PROCESSES at once
while true ; do
jobcnt=$(jobs -p|wc -l)
#echo "jobcnt: $jobcnt"
if [ $jobcnt -lt $MAX_PROCESSES ] ; then
actual_search "$@" &
break
else
sleep 0.25
fi
done
else
actual_search "$@"
fi
fi
}
function actual_search()
{
COMMENT="$1"
EXAMPLE="$2"
FALSE_POSITIVES_EXAMPLE="$3"
SEARCH_REGEX="$4"
OUTFILE="$5"
ARGS_FOR_GREP="$6" #usually just -i for case insensitive or empty, very rare we use -o for match-only part with no context info
#echo "$COMMENT, $SEARCH_REGEX, $OUTFILE, $ARGS_FOR_GREP, $WRITE_COMMENT, $BACKGROUND, $GREP_COMMAND, $STANDARD_GREP_ARGUMENTS, $TARGET"
if [ "$ENABLE_LEAST_LIKELY" = "false" ] && [[ $OUTFILE = 9_* ]]; then
echo "Skipping searching for $OUTFILE with regex $SEARCH_REGEX. Set ENABLE_LEAST_LIKELY to true if you would like to."
else
echo "Searching (args for grep:$ARGS_FOR_GREP) for $SEARCH_REGEX --> writing to $OUTFILE"
if [ "$WRITE_COMMENT" = "true" ]; then
echo "# Info: $COMMENT" >> "$TARGET/$OUTFILE"
echo "# Filename $OUTFILE" >> "$TARGET/$OUTFILE"
echo "# Example: $EXAMPLE" >> "$TARGET/$OUTFILE"
echo "# False positive example: $FALSE_POSITIVES_EXAMPLE" >> "$TARGET/$OUTFILE"
echo "# Grep args: $ARGS_FOR_GREP" >> "$TARGET/$OUTFILE"
echo "# Search regex: $SEARCH_REGEX" >> "$TARGET/$OUTFILE"
fi
$GREP_COMMAND $ARGS_FOR_GREP $STANDARD_GREP_ARGUMENTS -- "$SEARCH_REGEX" "$SEARCH_FOLDER" >> "$TARGET/$OUTFILE" 2>&1
if [ $? -ne 0 ]; then
#echo "Last grep didn't have a result, removing $OUTFILE"
rm "$TARGET/$OUTFILE"
fi
fi
}
function test_run()
{
COMMENT="$1"
EXAMPLE="$2"
FALSE_POSITIVES_EXAMPLE="$3"
SEARCH_REGEX="$4"
OUTFILE="$5"
ARGS_FOR_GREP="$6"
#echo "Testing: $COMMENT, $SEARCH_REGEX, $OUTFILE, $ARGS_FOR_GREP, $WRITE_COMMENT, $BACKGROUND, $GREP_COMMAND, $STANDARD_GREP_ARGUMENTS, $TARGET"
#First, test that regexes match the example
echo "$EXAMPLE" > "testing/temp_file.txt"
$GREP_COMMAND $ARGS_FOR_GREP $STANDARD_GREP_ARGUMENTS -- "$SEARCH_REGEX" "testing/temp_file.txt" > /dev/null
if [ $? -ne 0 ]; then
echo "FAIL! $EXAMPLE was not matched for regex $SEARCH_REGEX"
echo "Test file content:"
cat testing/temp_file.txt
#else
#echo "PASS! $SEARCH_REGEX"
fi
echo "AAAAA" > "testing/temp_file.txt"
$GREP_COMMAND $ARGS_FOR_GREP $STANDARD_GREP_ARGUMENTS -- "$SEARCH_REGEX" "testing/temp_file.txt" > /dev/null
if [ $? -eq 0 ]; then
echo "FAIL! Five A ('AAAAA') also matched for regex $SEARCH_REGEX"
fi
#Second, check that the OUTFILE name is unique
echo $DEBUG_TMP_OUTFILE_NAMES|$GREP_COMMAND -q $OUTFILE
if [ $? -eq 0 ]; then
echo "FAIL! $OUTFILE is specified twice in the script!"
fi
DEBUG_TMP_OUTFILE_NAMES="$DEBUG_TMP_OUTFILE_NAMES $OUTFILE"
#Third, check if comment empty
if [ "$COMMENT" = "" ]; then
echo "FAIL! $OUTFILE has no comment section!"
fi
#Four, check if example empty
if [ "$EXAMPLE" = "" ]; then
echo "FAIL! $OUTFILE has no example section!"
fi
}
#The Java stuff
if [ "$DO_JAVA" = "true" ]; then
echo "#Doing Java"
search "All Strings between double quotes. Like the command line tool 'strings' for Java code, but only catches direct declaration and initialization, because otherwise this regex would take forever." \
'String bla = "This is a Java String";' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'String\s[a-zA-Z_$]{1,1}[a-zA-Z0-9_$]{0,25}\s?=\s?"[^"]{4,500}"' \
"9_java_strings.txt" \
"-o" #Special case, we only want to show the strings themselves, therefore -o to output the match only
search "All javax.crypto usage" \
'import javax.crypto.bla;' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'javax.crypto' \
"8_java_crypto_javax-crypto.txt"
search "Bouncycastle is a common Java crypto provider" \
'import org.bouncycastle.bla;' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"bouncy.{0,$WILDCARD_SHORT}castle" \
"8_java_crypto_bouncycastle.txt" \
"-i"
search "SecretKeySpec is used to initialize a new encryption key: instance of SecretKey, often passed in the first argument as a byte[], which is the actual key" \
'new SecretKeySpec(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'new\sSecretKeySpec\(' \
"2_java_crypto_new-SecretKeySpec.txt" \
"-i"
search "PBEKeySpec(\" is used to initialize a new encryption key: instance of PBEKeySpec, often passed in the first argument as a byte[] like \"foobar\".getBytes(), which is the actual key. I leave this here for your amusement: https://github.com/wso2/wso2-synapse/blob/master/modules/securevault/src/main/java/org/apache/synapse/securevault/secret/handler/JBossEncryptionSecretCallbackHandler.java#L40 " \
'new PBEKeySpec("foobar".getBytes());' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'new\sPBEKeySpec\("' \
"2_java_crypto_new-PBEKeySpec_str.txt" \
"-i"
search "PBEKeySpec( is used to initialize a new encryption key: instance of PBEKeySpec, often passed in the first argument as a byte[], which is the actual key" \
'new PBEKeySpec(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'new\sPBEKeySpec\(' \
"4_java_crypto_new-PBEKeySpec.txt" \
"-i"
search "GenerateKey is another form of making a new instance of SecretKey, depending on the use case randomly generates one on the fly. It's interesting to see where the key goes next, where it's stored or accidentially written to a log file." \
'.generateKey()' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.generateKey\(' \
"4_java_crypto_generateKey.txt"
search "Occurences of KeyGenerator.getInstance(ALGORITHM) it's interesting to see where the key goes next, where it's stored or accidentially written to a log file. Make sure the cipher is secure." \
'KeyGenerator.getInstance(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'KeyGenerator\.getInstance\(' \
"5_java_crypto_keygenerator-getinstance.txt"
search "Occurences of Cipher.getInstance(ALGORITHM) it's interesting to see where the key goes next, where it's stored or accidentially written to a log file. Make sure the cipher is secure." \
'Cipher.getInstance("RSA/NONE/NoPadding");' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'Cipher\.getInstance\(' \
"5_java_crypto_cipher_getInstance.txt"
search "The Random class shouldn't be used for crypthography in Java, the SecureRandom should be used instead." \
'Random random = new Random();' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'new Random\(' \
"6_java_crypto_random.txt"
search "The Math.random class shouldn't be used for crypthography in Java, the SecureRandom should be used instead." \
'Math.random();' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'Math.random\(' \
"6_java_math_random.txt"
search "Message digest is used to generate hashes" \
'messagedigest' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'messagedigest' \
"5_java_crypto_messagedigest.txt" \
"-i"
search "KeyPairGenerator, well, to generate key pairs, see http://docs.oracle.com/javase/7/docs/api/java/security/KeyPairGenerator.html . It's interesting to see where the key goes next, where it's stored or accidentially written to a log file." \
'KeyPairGenerator(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'KeyPairGenerator\(' \
"5_java_crypto_keypairgenerator.txt"
search "String comparisons have to be done with .equals() in Java, not with == (won't work). Attention: False positives often occur if you used a decompiler to get the Java code, additionally it's allowed in JavaScript." \
' toString( ) ==' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"toString\(\s{0,$WILDCARD_SHORT}\)\s{0,$WILDCARD_SHORT}==" \
"9_java_string_comparison1.txt"
search "String comparisons have to be done with .equals() in Java, not with == (won't work). Attention: False positives often occur if you used a decompiler to get the Java code, additionally it's allowed in JavaScript." \
' == toString() ' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"==\s{0,$WILDCARD_SHORT}toString\(\s{0,$WILDCARD_SHORT}\)" \
"9_java_string_comparison2.txt"
search "String comparisons have to be done with .equals() in Java, not with == (won't work). Attention: False positives often occur if you used a decompiler to get the Java code, additionally it's allowed in JavaScript." \
' == "' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"==\s{0,$WILDCARD_SHORT}\"" \
"9_java_string_comparison3.txt"
search "Problem with equals and equalsIgnoreCase for checking user supplied passwords or Hashes or HMACs or XYZ is that it is not a time-consistent method, therefore allowing timing attacks." \
'.equals(hash_from_request)' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"equals\(.{0,$WILDCARD_SHORT}[Hh][Aa][Ss][Hh]" \
"2_java_string_comparison_equals_hash.txt"
search "Problem with equals and equalsIgnoreCase for checking user supplied passwords or Hashes or HMACs or XYZ is that it is not a time-consistent method, therefore allowing timing attacks." \
'.equalsIgnoreCase(hash_from_request' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"equalsIgnoreCase\(.{0,$WILDCARD_SHORT}[Hh][Aa][Ss][Hh]" \
"2_java_string_comparison_equalsIgnoreCase_hash.txt"
search "String comparisons: Filters and conditional decisions on user input should better be done with .equalsIgnoreCase() in Java in most cases, so that the clause doesn't miss something (e.g. think about string comparison in filters) or long switch case. Another problem with equals and equalsIgnoreCase for checking user supplied passwords or Hashes or HMACs or XYZ is that it is not a time-consistent method, therefore allowing timing attacks. Then there is also the question of different systems handling/doing Unicode Normalization (see for example https://gosecure.github.io/unicode-pentester-cheatsheet/ and https://www.gosecure.net/blog/2020/08/04/unicode-for-security-professionals/) or not: B\xC3\xBCcher and B\x75\xcc\x88cher is both UTF-8, but one is the character for a real Unicode u-Umlaut while the other is u[COMBINING DIAERESIS]. If the backend normalizes it could be that identifiers clash." \
'.equals(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'equals\(' \
"6_java_string_comparison_equals.txt"
search "String comparisons: Filters and conditional decisions on user input should better be done with .equalsIgnoreCase() in Java in most cases, so that the clause doesn't miss something (e.g. think about string comparison in filters) or long switch case. Another problem with equals and equalsIgnoreCase for checking user supplied passwords or Hashes or HMACs or XYZ is that it is not a time-consistent method, therefore allowing timing attacks. Then there is also the question of different systems handling/doing Unicode Normalization (see for example https://gosecure.github.io/unicode-pentester-cheatsheet/ and https://www.gosecure.net/blog/2020/08/04/unicode-for-security-professionals/) or not: B\xC3\xBCcher and B\x75\xcc\x88cher is both UTF-8, but one is the character for a real Unicode u-Umlaut while the other is u[COMBINING DIAERESIS]. If the backend normalizes it could be that identifiers clash." \
'.equalsIgnoreCase(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'equalsIgnoreCase\(' \
"6_java_string_comparison_equalsIgnoreCase.txt"
search "The syntax for SQL executions start with execute and this should as well catch generic execute calls." \
'executeBlaBla(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"execute.{0,$WILDCARD_SHORT}\(" \
"6_java_sql_execute.txt"
search "If a developer catches SQL exceptions, this could mean that she tries to hide SQL injections or similar." \
'SQLSyntaxErrorException' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"SQL.{0,$WILDCARD_SHORT}Exception" \
"6_java_sql_exception.txt"
search "SQL syntax" \
'addBatch(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"addBatch\(" \
"6_java_sql_addBatch.txt"
search "SQL prepared statements, can go wrong if you prepare after you use user supplied input in the query syntax..." \
'prepareStatement(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"prepareStatement\(" \
"6_java_sql_prepareStatement.txt"
search "Method to set HTTP headers in Java" \
'.setHeader(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.setHeader\(" \
"4_java_http_setHeader.txt"
search "Method to set HTTP headers in Java" \
'.addCookie(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.addCookie\(" \
"6_java_http_addCookie.txt"
search "Method to send HTTP redirect in Java" \
'.sendRedirect(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.sendRedirect\(" \
"5_java_http_sendRedirect.txt"
search "Java add HTTP header" \
'.addHeader(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.addHeader\(" \
"5_java_http_addHeader.txt"
search "Java add Access-Control-Allow-Origin HTTP header, if set to * then authentication should not be done with authentication sharing mechanisms such as cookies in browsers" \
'.addHeader("Access-Control-Allow-Origin", "*")' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.addHeader\(\"Access-Control-Allow-Origin" \
"3_java_http_addHeader_access_control_allow_origin.txt"
search "Java get HTTP header" \
'.getHeaders(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.getHeaders\(" \
"5_java_http_getHeaders.txt"
search "Java get HTTP cookies" \
'.getCookies(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.getCookies\(" \
"5_java_http_getCookies.txt"
search "Java get remote host" \
'.getRemoteHost(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.getRemoteHost\(" \
"5_java_http_getRemoteHost.txt"
search "Java get remote user" \
'.getRemoteUser(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.getRemoteUser\(" \
"5_java_http_getRemoteUser.txt"
search "Java is secure" \
'.isSecure(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.isSecure\(" \
"5_java_http_isSecure.txt"
search "Java get requested session ID" \
'.getRequestedSessionId(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.getRequestedSessionId\(" \
"5_java_http_getRequestedSessionId.txt"
search "Java get content type" \
'.getContentType(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.getContentType\(" \
"6_java_http_getContentType.txt"
search "Java HTTP or XML local name" \
'.getLocalName(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.getLocalName\(" \
"6_java_http_getLocalName.txt"
search "Java generic parameter fetching" \
'.getParameterBlabla(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.getParameter.{0,$WILDCARD_SHORT}\(" \
"7_java_http_getParameter.txt"
search "Potential tainted input in string format." \
'String.format("bla-%s"+taintedInput, variable);' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"String\.format\(\s{0,$WILDCARD_SHORT}\"[^\"]{1,$WILDCARD_LONG}\"\s{0,$WILDCARD_SHORT}\+" \
"4_java_format_string1.txt"
search "Potential tainted input in string format." \
'String.format(variable)' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"String\.format\(\s{0,$WILDCARD_SHORT}[^\"]" \
"5_java_format_string2.txt"
search "Java ProcessBuilder" \
'ProcessBuilder' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'ProcessBuilder' \
"6_java_ProcessBuilder.txt" \
"-i"
search "HTTP session timeout" \
'setMaxInactiveInterval()' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'setMaxInactiveInterval\(' \
"4_java_servlet_setMaxInactiveInterval.txt"
#Take care with the following regex, @ has a special meaning in double quoted strings, but not in single quoted strings
search "Find out which Java Beans get persisted with javax.persistence" \
'@Entity' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'@Entity|@ManyToOne|@OneToMany|@OneToOne|@Table|@Column' \
"7_java_persistent_beans.txt" \
"-l" #Special case, we only want to know matching files to know which beans get persisted, therefore -l to output matching files
#Take care with the following regex, @ has a special meaning in double quoted strings, but not in single quoted strings
search "The source code shows the database table/column names... e.g. if you find a sql injection later on, this will help for the exploitation" \
'@Column(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'@Column\(' \
"6_java_persistent_columns_in_database.txt"
#Take care with the following regex, @ has a special meaning in double quoted strings, but not in single quoted strings
search "The source code shows the database table/column names... e.g. if you find a sql injection later on, this will help for the exploitation" \
'@Table(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'@Table\(' \
"6_java_persistent_tables_in_database.txt"
search "Find out which Java classes do any kind of io" \
'java.net.' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'java\.net\.' \
"8_java_io_java_net.txt" \
"-l" #Special case, we only want to know matching files to know which beans get persisted, therefore -l to output matching files
search "Find out which Java classes do any kind of io" \
'java.io.' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'java\.io\.' \
"8_java_io_java_io.txt" \
"-l" #Special case, we only want to know matching files to know which beans get persisted, therefore -l to output matching files
search "Find out which Java classes do any kind of io" \
'javax.servlet' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'javax\.servlet' \
"8_java_io_javax_servlet.txt" \
"-l" #Special case, we only want to know matching files to know which beans get persisted, therefore -l to output matching files
search "Find out which Java classes do any kind of io" \
'org.apache.http' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'org\.apache\.http' \
"8_java_io_apache_http.txt" \
"-l" #Special case, we only want to know matching files to know which beans get persisted, therefore -l to output matching files
search "Especially for high security applications. From http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx : \"It would seem logical to collect and store the password in an object of type java.lang.String. However, here's the caveat: Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead.\" " \
'String password' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"string .{0,$WILDCARD_SHORT}password" \
"9_java_confidential_data_in_strings_password.txt" \
"-i"
search "Especially for high security applications. From http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx : \"It would seem logical to collect and store the password in an object of type java.lang.String. However, here's the caveat: Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead.\" " \
'String secret' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"string .{0,$WILDCARD_SHORT}secret" \
"9_java_confidential_data_in_strings_secret.txt" \
"-i"
search "Especially for high security applications. From http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx : \"It would seem logical to collect and store the password in an object of type java.lang.String. However, here's the caveat: Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead.\" " \
'String key' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"string .{0,$WILDCARD_SHORT}key" \
"9_java_confidential_data_in_strings_key.txt" \
"-i"
search "Especially for high security applications. From http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx : \"It would seem logical to collect and store the password in an object of type java.lang.String. However, here's the caveat: Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead.\" " \
'String cvv' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"string .{0,$WILDCARD_SHORT}cvv" \
"9_java_confidential_data_in_strings_cvv.txt" \
"-i"
search "Especially for high security applications. From http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx : \"It would seem logical to collect and store the password in an object of type java.lang.String. However, here's the caveat: Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead.\" " \
'String user' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"string .{0,$WILDCARD_SHORT}user" \
"9_java_confidential_data_in_strings_user.txt" \
"-i"
search "Especially for high security applications. From http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx : \"It would seem logical to collect and store the password in an object of type java.lang.String. However, here's the caveat: Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead.\" " \
'String passcode' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"string .{0,$WILDCARD_SHORT}passcode" \
"9_java_confidential_data_in_strings_passcode.txt" \
"-i"
search "Especially for high security applications. From http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx : \"It would seem logical to collect and store the password in an object of type java.lang.String. However, here's the caveat: Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead.\" " \
'String passphrase' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"string .{0,$WILDCARD_SHORT}passphrase" \
"9_java_confidential_data_in_strings_passphrase.txt" \
"-i"
search "Especially for high security applications. From http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx : \"It would seem logical to collect and store the password in an object of type java.lang.String. However, here's the caveat: Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead.\" " \
'String pin' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"string .{0,$WILDCARD_SHORT}pin" \
"9_java_confidential_data_in_strings_pin.txt" \
"-i"
search "Especially for high security applications. From http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#PBEEx : \"It would seem logical to collect and store the password in an object of type java.lang.String. However, here's the caveat: Objects of type String are immutable, i.e., there are no methods defined that allow you to change (overwrite) or zero out the contents of a String after usage. This feature makes String objects unsuitable for storing security sensitive information such as user passwords. You should always collect and store security sensitive information in a char array instead.\" " \
'String creditcard_number' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"string .{0,$WILDCARD_SHORT}credit" \
"9_java_confidential_data_in_strings_credit.txt" \
"-i"
search "SSLSocketFactory means in general you will skip SSL hostname verification because the SSLSocketFactory can't know which protocol (HTTP/LDAP/etc.) and therefore can't lookup the hostname. Even Apache's HttpClient version 3 for Java is broken: see https://crypto.stanford.edu/~dabo/pubs/abstracts/ssl-client-bugs.html" \
'SSLSocketFactory' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'SSLSocketFactory' \
"6_java_SSLSocketFactory.txt"
search "Apache's NoopHostnameVerifier makes TLS verification ignore the hostname, which is obviously very bad and allow MITM" \
'import org.apache.http.conn.ssl.NoopHostnameVerifier' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'NoopHostnameVerifier' \
"3_java_NoopHostnameVerifier.txt"
search "It's very easy to construct a backdoor in Java with Unicode \u characters, even within multi line comments, see http://pastebin.com/iGQhuUGd and https://plus.google.com/111673599544007386234/posts/ZeXvRCRZ3LF ." \
'\u0041\u0042' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\\u00..\\u00..' \
"9_java_backdoor_as_unicode.txt" \
"-i"
search "CheckValidity method of X509Certificate in Java is a very confusing naming for developers new to SSL/TLS and has been used as the *only* check to see if a certificate is valid or not in the past. This method *only* checks the date-validity, see http://docs.oracle.com/javase/7/docs/api/java/security/cert/X509Certificate.html#checkValidity%28%29 : 'Checks that the certificate is currently valid. It is if the current date and time are within the validity period given in the certificate.'" \
'paramArrayOfX509Certificate[0].checkValidity(); return;' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.checkValidity\(" \
"4_java_ssl_checkValidity.txt"
search "CheckServerTrusted, often used for certificate pinning on Java and Android, however, this is very very often insecure and not effective, see https://www.cigital.com/blog/ineffective-certificate-pinning-implementations/ . The correct method is to replace the system's TrustStore." \
'checkServerTrusted(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"checkServerTrusted\(" \
"4_java_checkServerTrusted.txt"
search "getPeerCertificates, often used for certificate pinning on Java and Android, however, this is very very often insecure and not effective, see https://www.cigital.com/blog/ineffective-certificate-pinning-implementations/ . The correct method is to replace the system's TrustStore." \
'getPeerCertificates(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"getPeerCertificates\(" \
"4_java_getPeerCertificates.txt"
search "getPeerCertificateChain, often used for certificate pinning on Java and Android, however, this is very very often insecure and not effective, see https://www.cigital.com/blog/ineffective-certificate-pinning-implementations/ . The correct method is to replace the system's TrustStore." \
'getPeerCertificateChain(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"getPeerCertificateChain\(" \
"4_java_getPeerCertificateChain.txt"
search "A simple search for getRuntime(), which is often used later on for .exec()" \
'getRuntime()' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'getRuntime\(' \
"7_java_getruntime.txt"
search "A simple search for getRuntime().exec()" \
'getRuntime().exec()' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'getRuntime\(\)\.exec\(' \
"6_java_runtime_exec_1.txt"
search "A search for Process p = r.exec()" \
'Process p = r.exec(args1);' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"Process.{0,$WILDCARD_SHORT}\.exec\(" \
"6_java_runtime_exec_2.txt"
search "The function openProcess is included in apache commons and does a getRuntime().exec" \
'p = openProcess(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"openProcess\(" \
"7_java_apache_common_openProcess.txt"
search "Validation in Java can be done via javax.validation. " \
'import javax.validation.bla;' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"javax.validation" \
"5_java_javax-validation.txt"
#Take care with the following regex, @ has a special meaning in double quoted strings, but not in single quoted strings
search 'Setting values in Java objects from HTTP/JSON requests directly can be very dangerous. This is usually a fasterxml.jackson binding. These properties might be secret inputs the server accepts, but are unlinked in the client side JavaScript code. For example imagine such an annotation on the username attribute of a User Java class. This would allow to fake the username by sending a username attribute in the JSON payload.' \
'@JsonProperty("version")' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'@JsonProperty\(' \
"4_java_jsonproperty_annotation.txt"
#Take care with the following regex, @ has a special meaning in double quoted strings, but not in single quoted strings
search 'Validation in Java can be done via certain @constraint' \
'@constraint' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'@constraint' \
"5_java_constraint_annotation.txt"
#Take care with the following regex, @ has a special meaning in double quoted strings, but not in single quoted strings
search 'Lint will sometimes complain about security related stuff, this annotation deactivates the warning' \
'@SuppressLint' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'@SuppressLint' \
"6_java_suppresslint.txt"
search 'Deserialization is something that can result in remote command execution, there are various exploits for such things, see http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ and https://github.com/mbechler/marshalsec for example' \
'new ObjectOutputStream(abc);' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'new ObjectOutputStream' \
"5_java_serialization-objectOutputStream.txt"
search 'Deserialization is something that can result in remote command execution, there are various exploits for such things, see http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ and https://github.com/mbechler/marshalsec for example' \
'abc.writeObject(def);' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.writeObject\(' \
"5_java_serialization-writeObject.txt"
search 'Deserialization is something that can result in remote command execution, there are various exploits for such things, see http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ and https://github.com/mbechler/marshalsec for example' \
'abc.readObject(def);' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.readObject\(' \
"7_java_serialization-readObject.txt"
search 'Deserialization is something that can result in remote command execution, there are various exploits for such things, see http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ and https://github.com/mbechler/marshalsec for example' \
' @SerializedName("variableName")' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'@SerializedName\(' \
"5_java_serialization-SerializedName.txt"
search 'Deserialization is something that can result in remote command execution, readResolve is a one of the Java APIs' \
'.readResolve(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.readResolve\(' \
"5_java_serialization-readResolve.txt"
search 'Deserialization is something that can result in remote command execution, readExternal is a one of the Java APIs' \
'.readExternal(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.readExternal\(' \
"5_java_serialization-readExternal.txt"
search 'Deserialization is something that can result in remote command execution, readUnshared is a one of the Java APIs' \
'.readUnshared(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.readUnshared\(' \
"5_java_serialization-readUnshared.txt"
search 'Deserialization is something that can result in remote command execution, XStream is a one of the Java APIs' \
'XStream(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'XStream' \
"5_java_serialization-XStream.txt"
search 'Java serialized data? Usually Java serialized data in base64 format starts with rO0 or non-base64 with hex ACED0005. Deserialization is something that can result in remote command execution, there are various exploits for such things, see http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ and https://github.com/mbechler/marshalsec for example' \
'rO0ABXNyABpodWRzb24ucmVtb3RpbmcuQ2FwYWJpbGl0eQAAAAAAAAABAgABSgAEbWFza3hwAAAAAAAAAJP4=' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'rO0' \
"4_java_serialization-base64serialized-data.txt"
search 'Java serialized data? Usually Java serialized data in base64 format starts with rO0 or non-base64 with hex ACED0005. Deserialization is something that can result in remote command execution, there are various exploits for such things, see http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ and https://github.com/mbechler/marshalsec for example' \
'ACED0005' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'AC ?ED ?00 ?05' \
"4_java_serialization-hexserialized-data.txt" \
"-i"
search 'Java serialized data? Usually Java serialized data in base64 format starts with rO0 or non-base64 with hex ACED0005. Decidezation is something that can result in remote command execution, there are various exploits for such things, see http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ and https://github.com/mbechler/marshalsec for example' \
'\xAC\xED\x00\x05' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\\xAC\\xED\\x00\\x05' \
"4_java_serialization-serialized-data.txt"
search 'JMXInvokerServlet is a JBoss interface that is usually vulnerable to Java deserialization attacks. There are various exploits for such things, see http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ and https://github.com/mbechler/marshalsec for example' \
'JMXInvokerServlet' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'JMXInvokerServlet' \
"2_java_serialization-JMXInvokerServlet.txt"
search 'InvokerTransformer is a vulnerable commons collection class that can be exploited if the web application has a Java object deserialization interface/issue, see http://foxglovesecurity.com/2015/11/06/what-do-weblogic-websphere-jboss-jenkins-opennms-and-your-application-have-in-common-this-vulnerability/ and https://github.com/mbechler/marshalsec for example' \
'InvokerTransformer' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'InvokerTransformer' \
"2_java_serialization-invokertransformer.txt"
search 'File.createTempFile is prone to race condition under certain circumstances, see https://sonarqube.com/coding_rules#types=VULNERABILITY|languages=java' \
'File.createTempFile();' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.createTempFile\(' \
"7_java_createTempFile.txt"
search 'HttpServletRequest.getRequestedSessionId returns the session ID requested by the client in the HTTP cookie header, not the one set by the server, see https://sonarqube.com/coding_rules#types=VULNERABILITY|languages=java' \
'HttpServletRequest.getRequestedSessionId();' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.getRequestedSessionId\(' \
"4_java_getRequestedSessionId.txt"
search 'NullCipher is obviously a cipher that is not secure, see https://sonarqube.com/coding_rules#types=VULNERABILITY|languages=java' \
'new NullCipher();' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'NullCipher' \
"4_java_NullCipher.txt"
search 'Dynamic class loading/reflection, maybe from untrusted source?, see https://sonarqube.com/coding_rules#types=VULNERABILITY|languages=java' \
'Class c = Class.forName(cn);' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'Class\.forName' \
"4_java_class_forName.txt"
search 'Dynamic class loading/reflection and then invoking method? Maybe from untrusted source?' \
'meth.invoke(obj, ...);' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.invoke\(' \
"5_java_invoke.txt"
search 'New cookie should automatically be followed by c.setSecure(true); to make sure the secure flag ist set, see https://sonarqube.com/coding_rules#types=VULNERABILITY|languages=java' \
'Cookie c = new Cookie(a, b);' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'new\sCookie\(' \
"5_java_new_cookie.txt"
search 'Servlet methods that throw exceptions might reveal sensitive information, see https://sonarqube.com/coding_rules#types=VULNERABILITY|languages=java' \
'public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"void do.{0,$WILDCARD_LONG}throws.{0,$WILDCARD_LONG}ServletException" \
"5_java_servlet_exception.txt"
search 'Security decisions should not be done based on the HTTP referer header as it is attacker chosen, see https://sonarqube.com/coding_rules#types=VULNERABILITY|languages=java' \
'String referer = request.getHeader("referer");' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.getHeader\("referer' \
"4_java_getHeader_referer.txt"
search 'Usually it is a bad idea to subclass cryptographic implementation, developers might break the implementation, see https://sonarqube.com/coding_rules#types=VULNERABILITY|languages=java' \
'MyCryptographicAlgorithm extends MessageDigest {' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"extends.{0,$WILDCARD_LONG}MessageDigest" \
"5_java_extends_MessageDigest.txt"
search 'Usually it is a bad idea to subclass cryptographic implementation, developers might break the implementation, see https://sonarqube.com/coding_rules#types=VULNERABILITY|languages=java' \
'MyCryptographicAlgorithm extends WhateverCipher {' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"extends.{0,$WILDCARD_LONG}cipher" \
"5_java_extends_cipher.txt" \
"-i"
search "printStackTrace logs and should not be in production (also logs to Android log), information leakage, etc." \
'.printStackTrace()' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.printStackTrace\(' \
"7_java_printStackTrace.txt"
search "setAttribute is usually used to set an attribute of a session object, untrusted data should not be added to a session object" \
'session.setAttribute("abc", untrusted_input);' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.setAttribute\(' \
"6_java_setAttribute.txt"
search "StreamTokenizer, look for parsing errors, see https://docs.oracle.com/javase/7/docs/api/java/io/StreamTokenizer.html" \
'StreamTokenizer' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'StreamTokenizer' \
"6_java_StreamTokenizer.txt"
search "getResourceAsStream, see http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#getResourceAsStream(java.lang.String)" \
'getResourceAsStream' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'getResourceAsStream' \
"6_java_getResourceAsStream.txt"
search "JWT in Java set the signing key incorrectly. An insecurity as happened in Apache Pulsar bug CVE-2021-22160 insecurity with algorithm none meaning no signature (just nothing after the second dot in JWT)" \
'Jwts.parserBuilder().setSigningKey(key).build().parse(jwt)' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"parserBuilder\(\)\.setSigningKey\(" \
"1_java_jwt_setSigningKey_vuln.txt"
search "JWT in Java set the signing key. An example of an insecurity happened in Apache Pulsar bug CVE-2021-22160 insecurity with algorithm none meaning no signature (just nothing after the second dot in JWT)" \
'Jwts.parserBuilder().setSigningKey(key).build().parse(jwt)' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"\.setSigningKey\(" \
"3_java_jwt_setSigningKey.txt"
fi
#The JSP specific stuff
if [ "$DO_JSP" = "true" ]; then
echo "#Doing JSP"
search "JSP redirect" \
'.sendRedirect(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.sendRedirect\(' \
"5_java_jsp_redirect.txt"
search "JSP redirect" \
'.forward(' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
'\.forward\(' \
"5_java_jsp_forward_1.txt"
search "JSP redirect" \
':forward' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
':forward' \
"5_java_jsp_forward_2.txt"
search "Can introduce XSS" \
'escape=false' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"escape\s{0,$WILDCARD_SHORT}=\s{0,$WILDCARD_SHORT}'?\"?\s{0,$WILDCARD_SHORT}false" \
"2_java_jsp_xss_escape.txt" \
"-i"
search "Can introduce XSS" \
'escapeXml=false' \
'FALSE_POSITIVES_EXAMPLE_PLACEHOLDER' \
"escapeXml\s{0,$WILDCARD_SHORT}=\s{0,$WILDCARD_SHORT}'?\"?\s{0,$WILDCARD_SHORT}false" \
"2_java_jsp_xss_escapexml.txt" \
"-i"
search "Can introduce XSS when simply writing a bean property to HTML without escaping. Attention: there are now client-side JavaScript libraries using the same tags for templates!" \
'<%=bean.getName()%>' \
'Attention: there are now client-side JavaScript libraries using the same tags for templates!' \
"<%=\s{0,$WILDCARD_SHORT}[A-Za-z0-9_]{1,$WILDCARD_LONG}.get[A-Za-z0-9_]{1,$WILDCARD_LONG}\(" \
"1_java_jsp_property_to_html_xss.txt" \
"-i"
search "Java generic JSP parameter get" \
'.getParameter(' \