CoolFace
Apppublic

Deeps-2005/java-ssl-scanner

sourceHugging Faceupdated 1y agoView on Hugging Face
0likes
Analyzer.java550 linesDownload Raw Back to java_analyzer
1import com.github.javaparser.*;2import com.github.javaparser.ast.CompilationUnit;3import com.github.javaparser.ast.body.*;4import com.github.javaparser.ast.expr.*; // This import already covers ArrayCreationExpr, ArrayAccessExpr, ArrayInitializerExpr5import com.github.javaparser.ast.stmt.*;6import com.github.javaparser.ast.visitor.ModifierVisitor;7import com.github.javaparser.ast.type.ClassOrInterfaceType;8import com.github.javaparser.ast.body.MethodDeclaration;9import com.github.javaparser.ast.type.Type;10// REMOVED these incorrect/redundant imports:11// import com.github.javaparser.ast.ArrayCreationLevel;12// import com.github.javaparser.ast.ArrayCreationExpr;13// import com.github.javaparser.ast.ArrayAccessExpr;14// import com.github.javaparser.ast.ArrayInitializerExpr;15 16 17import java.io.File;18import java.io.FileInputStream;19import java.util.Arrays;20import java.util.List;21import java.util.Set;22import java.util.HashSet;23 24 25public class Analyzer {26 27    // SSL/JSSE related constants28    private static final List<String> INSECURE_PROTOCOLS = Arrays.asList("sslv2", "sslv3", "tlsv1", "tlsv1.0", "tlsv1.1");29    private static final List<String> WEAK_CIPHER_KEYWORDS = Arrays.asList("null", "anon", "export", "rc4", "des", "md5");30    private static final List<String> NON_PFS_CIPHERS = Arrays.asList("_RSA_","_STATIC_","_DH_","_ECDH_");31 32    // NEW: Cryptography related constants33    private static final List<String> WEAK_HASHING_ALGORITHMS = Arrays.asList("md5", "sha-1");34    private static final Set<String> XML_FACTORIES = new HashSet<>(Arrays.asList(35        "DocumentBuilderFactory", "SAXParserFactory", "XMLInputFactory"36    ));37    private static final String HARDCODED_KEY_PATTERN = ".*(key|secret|password|salt|token|cipher|auth).*";38 39 40    public static void main(String[] args) throws Exception {41        if (args.length == 0) {42            System.out.println("Usage: java Analyzer <JavaFile>");43            return;44        }45 46        File file = new File(args[0]);47        if (!file.exists()) {48            System.err.println("Error: File not found - " + args[0]);49            return;50        }51        if (!file.isFile()) {52            System.err.println("Error: Not a file - " + args[0]);53            return;54        }55 56        CompilationUnit cu = StaticJavaParser.parse(new FileInputStream(file));57 58        cu.accept(new ModifierVisitor<Void>() {59 60            @Override61            public MethodCallExpr visit(MethodCallExpr mce, Void arg) {62                super.visit(mce, arg); // Call super to ensure full traversal63 64                int line = mce.getBegin().map(p -> p.line).orElse(-1);65 66                // NEW: Certificate Pinning Check67                if (mce.getNameAsString().equals("checkServerTrusted") && 68                    mce.getScope().isPresent() &&69                    (mce.getScope().get().toString().contains("X509TrustManager") ||70                     mce.getScope().get().toString().contains("TrustManager"))) {71                    72                    boolean hasPinning = mce.getParentNode()73                        .filter(parent -> parent instanceof MethodDeclaration)74                        .map(parent -> ((MethodDeclaration) parent).getBody())75                        .flatMap(body -> body.map(b -> b.toString().contains("PublicKey") && 76                                            b.toString().contains("X509Certificate")))77                        .orElse(false);78                    79                    if (!hasPinning) {80                        System.out.println("[Line " + line + "] ISSUE: Missing certificate pinning implementation - Vulnerable to MITM attacks. Implement certificate public key pinning. Severity: CRITICAL");81                    }82                }83 84                // NEW: Forward Secrecy Check85                if (mce.getNameAsString().equals("setEnabledCipherSuites") &&86                    mce.getScope().isPresent() &&87                    (mce.getScope().get().toString().contains("SSLSocket") || 88                     mce.getScope().get().toString().contains("SSLEngine"))) {89                    90                    mce.getArguments().forEach(argExpr -> {91                        if (argExpr.isArrayInitializerExpr()) {92                            argExpr.asArrayInitializerExpr().getValues().forEach(cipherExpr -> {93                                if (cipherExpr.isStringLiteralExpr()) {94                                    String cipher = cipherExpr.asStringLiteralExpr().getValue();95                                    if (NON_PFS_CIPHERS.stream().anyMatch(cipher::contains)) {96                                        System.out.println("[Line " + line + "] ISSUE: Non-PFS cipher suite enabled: " + cipher + " - Prefer ECDHE cipher suites for forward secrecy. Severity: HIGH");97                                    }98                                }99                            });100                        }101                    });102                }103 104                // NEW: HSTS Header Check105                if ((mce.getNameAsString().equals("setHeader") || 106                     mce.getNameAsString().equals("addHeader")) &&107                    mce.getArguments().size() >= 2 &&108                    mce.getArgument(0).isStringLiteralExpr()) {109                    110                    String headerName = mce.getArgument(0).asStringLiteralExpr().getValue();111                    if (headerName.equalsIgnoreCase("Strict-Transport-Security")) {112                        if (mce.getArgument(1).isStringLiteralExpr()) {113                            String headerValue = mce.getArgument(1).asStringLiteralExpr().getValue();114                            if (!headerValue.toLowerCase().contains("max-age") ||115                                headerValue.toLowerCase().contains("max-age=0")) {116                                System.out.println("[Line " + line + "] ISSUE: Weak HSTS header configuration: " + headerValue + " - Should include 'max-age' with substantial duration. Severity: HIGH");117                            }118                        }119                    }120                }121 122                // NEW: CRL/OCSP Validation Check123                if (mce.getNameAsString().equals("setRevocationEnabled") &&124                    mce.getScope().isPresent() &&125                    mce.getScope().get().toString().contains("PKIXBuilderParameters")) {126                    127                    if (mce.getArguments().size() == 1 &&128                        mce.getArgument(0).isBooleanLiteralExpr() &&129                        !mce.getArgument(0).asBooleanLiteralExpr().getValue()) {130                        System.out.println("[Line " + line + "] ISSUE: Certificate revocation checking explicitly disabled - Enables revoked certificate acceptance. Severity: CRITICAL");131                    }132                }133 134                // NEW: Server Name Indication (SNI) Check135                if (mce.getNameAsString().equals("setServerNames") &&136                    mce.getScope().isPresent() &&137                    mce.getScope().get().toString().contains("SSLParameters")) {138                    139                    if (mce.getArguments().size() == 1 &&140                        mce.getArgument(0).isNullLiteralExpr()) {141                        System.out.println("[Line " + line + "] ISSUE: SNI explicitly disabled - May cause TLS handshake failures. Severity: MEDIUM");142                    }143                }144 145 146                // Check for System.setProperty calls (debug logging, renegotiation)147                if (mce.getNameAsString().equals("setProperty") && mce.getArguments().size() == 2) {148                    Expression arg0 = mce.getArgument(0);149                    if (arg0.isStringLiteralExpr()) {150                        String propName = arg0.asStringLiteralExpr().getValue();151                        if (propName.contains("javax.net.debug")) {152                            System.out.println("[Line " + line + "] ISSUE: Debug logging enabled (javax.net.debug) - Exposes sensitive SSL/TLS handshaking details. Severity: HIGH");153                        }154                        if (propName.contains("com.ibm.jsse2.renegotiate")) {155                            System.out.println("[Line " + line + "] ISSUE: TLS renegotiation potentially enabled - Can be abused for DoS attacks. Severity: HIGH");156                        }157                    }158                }159 160                // Check for HostnameVerifier related issues161                if (mce.getNameAsString().equals("setDefaultHostnameVerifier") && mce.getArguments().size() == 1) {162                    Expression arg0 = mce.getArgument(0);163                    if (arg0.isLambdaExpr()) {164                        LambdaExpr lambda = arg0.asLambdaExpr();165                        if (lambda.getBody().isExpressionStmt() &&166                            lambda.getBody().asExpressionStmt().getExpression().isBooleanLiteralExpr() &&167                            lambda.getBody().asExpressionStmt().getExpression().asBooleanLiteralExpr().getValue()) {168                            System.out.println("[Line " + line + "] ISSUE: Insecure HostnameVerifier (lambda always returns true) - Bypasses hostname validation, vulnerable to MITM. Severity: CRITICAL");169                        } else if (lambda.getBody().isBlockStmt()) {170                            BlockStmt block = lambda.getBody().asBlockStmt();171                            for (Statement stmt : block.getStatements()) {172                                if (stmt instanceof ReturnStmt) {173                                    ReturnStmt returnStmt = (ReturnStmt) stmt;174                                    if (returnStmt.getExpression().isPresent() &&175                                        returnStmt.getExpression().get().isBooleanLiteralExpr() &&176                                        returnStmt.getExpression().get().asBooleanLiteralExpr().getValue()) {177                                        System.out.println("[Line " + line + "] ISSUE: Insecure HostnameVerifier (lambda block always returns true) - Bypasses hostname validation, vulnerable to MITM. Severity: CRITICAL");178                                        break;179                                    }180                                }181                            }182                        }183                    }184                }185 186                // Check for hardcoded password passed to keystore load()187                if (mce.getNameAsString().equals("load") &&188                    mce.getScope().isPresent() &&189                    mce.getScope().get().toString().contains("KeyStore") &&190                    mce.getArguments().size() == 2 &&191                    (mce.getArgument(1).isCharLiteralExpr() || mce.getArgument(1).isStringLiteralExpr())) {192                    System.out.println("[Line " + line + "] ISSUE: Hardcoded literal password passed to KeyStore.load() - Sensitive info in source code. Severity: HIGH");193                }194 195                // Check for outdated/weak SSL/TLS protocols in SSLContext.getInstance()196                if (mce.getNameAsString().equals("getInstance") &&197                    mce.getScope().isPresent() &&198                    mce.getScope().get().toString().contains("SSLContext") &&199                    mce.getArguments().size() >= 1) {200                    Expression arg0 = mce.getArgument(0);201                    if (arg0.isStringLiteralExpr()) {202                        String protocol = arg0.asStringLiteralExpr().getValue().toLowerCase();203                        if (INSECURE_PROTOCOLS.contains(protocol)) {204                            System.out.println("[Line " + line + "] ISSUE: Insecure SSL/TLS protocol requested: " + protocol.toUpperCase() + " - Known vulnerabilities exist. Severity: CRITICAL");205                        }206                    }207                }208 209                // Check for enabling weak/outdated PROTOCOLS via setEnabledProtocols()210                if (mce.getNameAsString().equals("setEnabledProtocols") &&211                    mce.getScope().isPresent() &&212                    (mce.getScope().get().toString().contains("SSLSocket") || mce.getScope().get().toString().contains("SSLEngine"))) {213                    214                    mce.getArguments().forEach(argExpr -> {215                        if (argExpr.isArrayInitializerExpr()) {216                            argExpr.asArrayInitializerExpr().getValues().forEach(protoExpr -> {217                                if (protoExpr.isStringLiteralExpr()) {218                                    String protocol = protoExpr.asStringLiteralExpr().getValue().toLowerCase();219                                    if (INSECURE_PROTOCOLS.contains(protocol)) {220                                        System.out.println("[Line " + line + "] ISSUE: Insecure SSL/TLS protocol enabled via setEnabledProtocols(): " + protocol.toUpperCase() + " - Known vulnerabilities exist. Severity: CRITICAL");221                                    }222                                }223                            });224                        } else if (argExpr.isStringLiteralExpr()) {225                            String protocol = argExpr.asStringLiteralExpr().getValue().toLowerCase();226                            if (INSECURE_PROTOCOLS.contains(protocol)) {227                                System.out.println("[Line " + line + "] ISSUE: Insecure SSL/TLS protocol enabled via setEnabledProtocols(): " + protocol.toUpperCase() + " - Known vulnerabilities exist. Severity: CRITICAL");228                            }229                        }230                    });231                }232 233                // Check for enabling weak CIPHER SUITES via setEnabledCipherSuites()234                if (mce.getNameAsString().equals("setEnabledCipherSuites") &&235                    mce.getScope().isPresent() &&236                    (mce.getScope().get().toString().contains("SSLSocket") || mce.getScope().get().toString().contains("SSLEngine"))) {237                    238                    mce.getArguments().forEach(argExpr -> {239                        if (argExpr.isArrayInitializerExpr()) {240                            argExpr.asArrayInitializerExpr().getValues().forEach(cipherExpr -> {241                                if (cipherExpr.isStringLiteralExpr()) {242                                    String cipherSuite = cipherExpr.asStringLiteralExpr().getValue().toLowerCase();243                                    if (WEAK_CIPHER_KEYWORDS.stream().anyMatch(cipherSuite::contains)) {244                                        System.out.println("[Line " + line + "] ISSUE: Weak cipher suite enabled via setEnabledCipherSuites(): " + cipherSuite.toUpperCase() + " - Use stronger cryptographic algorithms. Severity: CRITICAL");245                                    }246                                }247                            });248                        } else if (argExpr.isStringLiteralExpr()) {249                            String cipherSuite = argExpr.asStringLiteralExpr().getValue().toLowerCase();250                            if (WEAK_CIPHER_KEYWORDS.stream().anyMatch(cipherSuite::contains)) {251                                System.out.println("[Line " + line + "] ISSUE: Weak cipher suite enabled via setEnabledCipherSuites(): " + cipherSuite.toUpperCase() + " - Use stronger cryptographic algorithms. Severity: CRITICAL");252                            }253                        }254                    });255                }256 257                // Check for potential HttpURLConnection usage for HTTPS (insecure default)258                if (mce.getNameAsString().equals("URL") &&259                    mce.getArguments().size() == 1) {260                    Expression arg0 = mce.getArgument(0);261                    if (arg0.isStringLiteralExpr()) {262                        String urlString = arg0.asStringLiteralExpr().getValue();263                        if (urlString.startsWith("http://") && !urlString.contains("localhost") && !urlString.contains("127.0.0.1")) { // Exclude localhost264                            System.out.println("[Line " + line + "] WARNING: URL constructed with 'http://' scheme: " + urlString + " - Ensure sensitive data is not sent over insecure HTTP. Severity: MEDIUM");265                        }266                    }267                }268 269                // NEW: Weak Hashing Algorithms (MD5, SHA-1)270                if (mce.getNameAsString().equals("getInstance") &&271                    mce.getScope().isPresent() &&272                    mce.getScope().get().toString().contains("MessageDigest") &&273                    mce.getArguments().size() >= 1) {274                    Expression arg0 = mce.getArgument(0);275                    if (arg0.isStringLiteralExpr()) {276                        String algorithm = arg0.asStringLiteralExpr().getValue().toLowerCase();277                        if (WEAK_HASHING_ALGORITHMS.contains(algorithm)) {278                            System.out.println("[Line " + line + "] ISSUE: Weak hashing algorithm used: " + algorithm.toUpperCase() + " - Use stronger algorithms like SHA-256 or SHA-512. Severity: HIGH");279                        }280                    }281                }282 283                // NEW: XML External Entity (XXE) Vulnerability - factory instantiation284                // Flagging instantiation and suggesting secure features285                if (mce.getNameAsString().equals("newInstance") &&286                    mce.getScope().isPresent() &&287                    XML_FACTORIES.contains(mce.getScope().get().toString())) {288                    System.out.println("[Line " + line + "] ISSUE: XML parsing factory created without explicit XXE hardening - Potentially vulnerable to XXE attacks. Ensure external entities and DTDs are disabled. Severity: CRITICAL");289                }290 291 292                return mce;293            }294 295            @Override296            public ObjectCreationExpr visit(ObjectCreationExpr oce, Void arg) {297                super.visit(oce, arg); // Call super to ensure full traversal298 299                int line = oce.getBegin().map(p -> p.line).orElse(-1);300 301                // NEW: FIPS Compliance Check302                if (oce.getType().getNameAsString().equals("Security") &&303                    oce.getParentNode().isPresent() &&304                    oce.getParentNode().get() instanceof MethodCallExpr) {305                    306                    MethodCallExpr parentCall = (MethodCallExpr) oce.getParentNode().get();307                    if (parentCall.getNameAsString().equals("addProvider") &&308                        parentCall.getArguments().size() == 1 &&309                        parentCall.getArgument(0).isObjectCreationExpr()) {310                        311                        ObjectCreationExpr provider = parentCall.getArgument(0).asObjectCreationExpr();312                        if (!provider.getType().getNameAsString().toLowerCase().contains("fips")) {313                            System.out.println("[Line " + line + "] WARNING: Non-FIPS compliant cryptographic provider - Consider using FIPS validated modules for compliance. Severity: MEDIUM");314                        }315                    }316                }317 318                // NEW: Certificate Transparency Check319                if (oce.getType().getNameAsString().equals("CTVerifier")) {320                    boolean hasValidation = oce.getParentNode()321                        .filter(parent -> parent instanceof VariableDeclarator)322                        .map(parent -> (VariableDeclarator) parent)323                        .flatMap(varDecl -> varDecl.getParentNode()) // returns Optional<Node>324                        .filter(grandparent -> grandparent instanceof FieldDeclaration)325                        .map(grandparent -> (FieldDeclaration) grandparent)326                        .isPresent();327                    328                    if (!hasValidation) {329                        System.out.println("[Line " + line + "] ISSUE: Certificate Transparency verifier created but not used - Implement CT validation for issued certificates. Severity: HIGH");330                    }331                }332 333                // Check for Anonymous X509TrustManager/TrustManager334                if (oce.getAnonymousClassBody().isPresent() &&335                    (oce.getType().getNameAsString().equals("X509TrustManager") ||336                     oce.getType().getNameAsString().equals("TrustManager"))) {337 338                    System.out.println("[Line " + line + "] ISSUE: Anonymous X509TrustManager/TrustManager detected - Verify implementation for proper certificate validation. Severity: CRITICAL");339 340                    oce.getAnonymousClassBody().get().forEach(bodyDeclaration -> {341                        if (bodyDeclaration instanceof MethodDeclaration) {342                            MethodDeclaration md = (MethodDeclaration) bodyDeclaration;343                            String methodName = md.getNameAsString();344 345                            if (("checkClientTrusted".equals(methodName) || "checkServerTrusted".equals(methodName)) && md.getBody().isPresent()) {346                                BlockStmt methodBody = md.getBody().get();347                                for (Statement stmt : methodBody.getStatements()) {348                                    if (stmt instanceof ReturnStmt) {349                                        ReturnStmt returnStmt = (ReturnStmt) stmt;350                                        if (returnStmt.getExpression().isPresent() &&351                                            returnStmt.getExpression().get().isBooleanLiteralExpr() &&352                                            returnStmt.getExpression().get().asBooleanLiteralExpr().getValue()) {353                                            System.out.println("  [Line " + line + "]  - Method '" + methodName + "' unconditionally returns true, implying no validation. Severity: CRITICAL");354                                            break;355                                        }356                                    } else if (stmt instanceof TryStmt) {357                                        TryStmt ts = (TryStmt) stmt;358                                        ts.getCatchClauses().forEach(catchClause -> {359                                            Type caughtType = catchClause.getParameter().getType();360                                            if (caughtType instanceof ClassOrInterfaceType) {361                                                String typeName = ((ClassOrInterfaceType) caughtType).getNameAsString();362                                                if (typeName.equals("Exception") || typeName.equals("Throwable") ||363                                                    typeName.equals("CertificateException") || typeName.equals("NoSuchAlgorithmException")) {364                                                    if (catchClause.getBody().getStatements().isEmpty() ||365                                                        (catchClause.getBody().getStatements().size() == 1 &&366                                                         catchClause.getBody().getStatement(0).isExpressionStmt() &&367                                                         catchClause.getBody().getStatement(0).asExpressionStmt().getExpression().isMethodCallExpr() &&368                                                         catchClause.getBody().getStatement(0).asExpressionStmt().getExpression().asMethodCallExpr().getNameAsString().equals("printStackTrace"))) {369                                                        System.out.println("  [Line " + line + "]  - Method '" + methodName + "' catches " + typeName + " and may swallow validation errors. Severity: CRITICAL");370                                                    }371                                                }372                                            }373                                        });374                                    }375                                }376                            }377                        }378                    });379                }380 381                // Check for Unseeded SecureRandom instance382                if (oce.getType().getNameAsString().equals("SecureRandom") &&383                    oce.getArguments().isEmpty()) {384                    System.out.println("[Line " + line + "] ISSUE: Unseeded SecureRandom instance - May lead to predictable keys or nonce values if not explicitly seeded. Severity: HIGH");385                }386 387                // Check for Anonymous HostnameVerifier388                if (oce.getAnonymousClassBody().isPresent() &&389                    oce.getType().getNameAsString().equals("HostnameVerifier")) {390                    System.out.println("[Line " + line + "] ISSUE: Anonymous HostnameVerifier detected - Verify implementation for proper hostname validation. Severity: CRITICAL");391                    oce.getAnonymousClassBody().get().forEach(bodyDeclaration -> {392                        if (bodyDeclaration instanceof MethodDeclaration) {393                            MethodDeclaration md = (MethodDeclaration) bodyDeclaration;394                            if (md.getNameAsString().equals("verify") && md.getBody().isPresent()) {395                                BlockStmt methodBody = md.getBody().get();396                                for (Statement stmt : methodBody.getStatements()) {397                                    if (stmt instanceof ReturnStmt) {398                                        ReturnStmt returnStmt = (ReturnStmt) stmt;399                                        if (returnStmt.getExpression().isPresent() &&400                                            returnStmt.getExpression().get().isBooleanLiteralExpr() &&401                                            returnStmt.getExpression().get().asBooleanLiteralExpr().getValue()) {402                                            System.out.println("  [Line " + line + "]  - Method 'verify' unconditionally returns true, implying no validation. Severity: CRITICAL");403                                            break;404                                        }405                                    }406                                }407                            }408                        }409                    });410                }411 412                // NEW: Hardcoded Cryptographic Keys/Salts413                if (oce.getType().getNameAsString().equals("SecretKeySpec") ||414                    oce.getType().getNameAsString().equals("IvParameterSpec")) {415                    boolean hasLiteralArgument = false;416                    for (Expression argExpr : oce.getArguments()) {417                        if (argExpr.isStringLiteralExpr() || (argExpr.isMethodCallExpr() && argExpr.asMethodCallExpr().getNameAsString().equals("getBytes"))) {418                            // Check for "hardcoded_key".getBytes() or similar419                            if (argExpr.isStringLiteralExpr() && argExpr.asStringLiteralExpr().getValue().toLowerCase().matches(HARDCODED_KEY_PATTERN)) {420                                hasLiteralArgument = true;421                                break;422                            } else if (argExpr.isMethodCallExpr() && argExpr.asMethodCallExpr().getScope().isPresent() && argExpr.asMethodCallExpr().getScope().get().isStringLiteralExpr() && argExpr.asMethodCallExpr().getScope().get().asStringLiteralExpr().getValue().toLowerCase().matches(HARDCODED_KEY_PATTERN)) {423                                hasLiteralArgument = true;424                                break;425                            }426                        } else if (argExpr.isArrayCreationExpr()) {427                             // Check for new byte[]{...} with suspicious values428                            ArrayCreationExpr ace = argExpr.asArrayCreationExpr();429                            if (ace.getInitializer().isPresent()) {430                                ArrayInitializerExpr init = ace.getInitializer().get();431                                for (Expression valExpr : init.getValues()) {432                                    if (valExpr.isIntegerLiteralExpr() || valExpr.isCharLiteralExpr() || valExpr.isStringLiteralExpr()) {433                                        hasLiteralArgument = true; // Flag any literal here, needs manual review434                                        break;435                                    }436                                }437                            }438                        }439                    }440                    if (hasLiteralArgument) {441                        System.out.println("[Line " + line + "] ISSUE: Potentially hardcoded cryptographic key/salt/IV in " + oce.getType().getNameAsString() + " initialization. Store sensitive keys securely (e.g., environment variables, KeyVault). Severity: CRITICAL");442                    }443                }444 445                // NEW: Deserialization of Untrusted Data446                if (oce.getType().getNameAsString().equals("ObjectInputStream")) {447                    System.out.println("[Line " + line + "] ISSUE: Deserialization of untrusted data via ObjectInputStream - Vulnerable to Remote Code Execution (RCE) if input is malicious. Avoid deserializing untrusted data. Severity: CRITICAL");448                }449 450                return oce;451            }452 453 454            @Override455            public WhileStmt visit(WhileStmt ws, Void arg) {456                super.visit(ws, arg);457 458                int line = ws.getBegin().map(p -> p.line).orElse(-1);459 460                if (ws.getCondition().isBooleanLiteralExpr() &&461                    ws.getCondition().asBooleanLiteralExpr().getValue()) {462                    System.out.println("[Line " + line + "] ISSUE: Potential infinite loop (while(true)) - Could indicate a DoS vulnerability if related to resource consumption. Severity: HIGH");463                }464 465                return ws;466            }467 468            @Override469            public VariableDeclarator visit(VariableDeclarator vd, Void arg) {470                super.visit(vd, arg);471 472                int line = vd.getBegin().map(p -> p.line).orElse(-1);473 474                // NEW: HTTP/2 Protocol Check475                if (vd.getType().isArrayType() &&476                    vd.getType().asArrayType().getComponentType().toString().equals("String") &&477                    vd.getInitializer().isPresent() &&478                    vd.getInitializer().get() instanceof ArrayInitializerExpr) {479                    480                    ArrayInitializerExpr init = (ArrayInitializerExpr) vd.getInitializer().get();481                    boolean hasHttp2 = init.getValues().stream()482                        .filter(Expression::isStringLiteralExpr)483                        .map(expr -> expr.asStringLiteralExpr().getValue())484                        .anyMatch(val -> val.equalsIgnoreCase("h2"));485                    486                    if (!hasHttp2 && init.getValues().stream()487                        .filter(Expression::isStringLiteralExpr)488                        .map(expr -> expr.asStringLiteralExpr().getValue())489                        .anyMatch(val -> val.startsWith("http/1"))) {490                        System.out.println("[Line " + line + "] WARNING: HTTP/1.x protocol enabled without HTTP/2 - Prefer HTTP/2 for better security and performance. Severity: MEDIUM");491                    }492                }493 494                // Weak cipher suites in array declaration495                if (vd.getType().isArrayType() &&496                    vd.getType().asArrayType().getComponentType().toString().equals("String") &&497                    vd.getInitializer().isPresent() &&498                    vd.getInitializer().get() instanceof ArrayInitializerExpr) {499 500                    ArrayInitializerExpr init = (ArrayInitializerExpr) vd.getInitializer().get();501                    502                    for (Expression expr : init.getValues()) {503                        if (expr.isStringLiteralExpr()) {504                            String value = expr.asStringLiteralExpr().getValue().toLowerCase();505                            if (WEAK_CIPHER_KEYWORDS.stream().anyMatch(value::contains)) {506                                System.out.println("[Line " + line + "] ISSUE: Weak cipher suite keyword detected in array: '" + value + "' - Use stronger cryptographic algorithms. Severity: CRITICAL");507                                break;508                            }509                        }510                    }511                }512 513                // Check for hardcoded password assigned to variable514                if (vd.getInitializer().isPresent() && vd.getInitializer().get().isStringLiteralExpr()) {515                    String val = vd.getInitializer().get().asStringLiteralExpr().getValue().toLowerCase();516                    if (val.matches(".*(password|pass|secret|key|pwd|123).*") && val.length() > 3) {517                        System.out.println("[Line " + line + "] ISSUE: Hardcoded password/sensitive string assigned to variable: '" + val + "' - Store credentials securely (e.g., environment variables, KeyVault). Severity: CRITICAL");518                    }519                }520 521                return vd;522            }523 524            @Override525            public TryStmt visit(TryStmt ts, Void arg) {526                super.visit(ts, arg);527 528                int line = ts.getBegin().map(p -> p.line).orElse(-1);529 530                ts.getCatchClauses().forEach(catchClause -> {531                    Type caughtType = catchClause.getParameter().getType();532                    if (caughtType instanceof ClassOrInterfaceType) {533                        String typeName = ((ClassOrInterfaceType) caughtType).getNameAsString();534                        if (typeName.equals("Exception") || typeName.equals("Throwable")) {535                            if (catchClause.getBody().getStatements().isEmpty() ||536                                (catchClause.getBody().getStatements().size() == 1 &&537                                 catchClause.getBody().getStatement(0).isExpressionStmt() &&538                                 catchClause.getBody().getStatement(0).asExpressionStmt().getExpression().isMethodCallExpr() &&539                                 catchClause.getBody().getStatement(0).asExpressionStmt().getExpression().asMethodCallExpr().getNameAsString().equals("printStackTrace"))) {540                                System.out.println("[Line " + line + "] WARNING: Overly broad catch for '" + typeName + "' with minimal error handling - May hide critical exceptions. Severity: MEDIUM");541                            }542                        }543                    }544                });545                return ts;546            }547        }, null);548    }549}550