daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

code-review-tools.md (25175B)


      1 ---
      2 title: "Source Code Review / SAST Tools"
      3 section: "Network Services"
      4 sectionSlug: "network-services-pentesting"
      5 sourcePath: "src/network-services-pentesting/pentesting-web/code-review-tools.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/network-services-pentesting/pentesting-web/code-review-tools.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Source Code Review / SAST Tools
     14 
     15 ## Guidance and tool lists
     16 
     17 - [**https://owasp.org/www-community/Source_Code_Analysis_Tools**](https://owasp.org/www-community/Source_Code_Analysis_Tools)
     18 - [**https://github.com/analysis-tools-dev/static-analysis**](https://github.com/analysis-tools-dev/static-analysis)
     19 
     20 ## C/C++ Manual Review Gotchas
     21 
     22 When reviewing **C/C++** manually, look for APIs and patterns that appear safe in isolation but become exploitable when their outputs are reused later in the control flow.<sup>[[1]](#references)[[2]](#references)</sup>
     23 
     24 ### Non-reentrant libc return buffers breaking security checks
     25 
     26 Some legacy networking/string helpers return pointers to **static internal storage**. A classic example is `inet_ntoa()`: storing the returned pointer and calling the function again usually means the second call overwrites the same buffer.
     27 
     28 ```c
     29 char *user_ip = inet_ntoa(addr_from_user);
     30 char *allowed_ip = inet_ntoa(addr_from_policy);
     31 
     32 if (strcmp(user_ip, allowed_ip) != 0) {
     33     return DENY;
     34 }
     35 ```
     36 
     37 This kind of code can silently collapse an **allowlist / equality check** because both pointers may reference the same final string. During review, treat these APIs as suspicious whenever the returned pointer is:
     38 
     39 - stored for later comparison
     40 - reused across branches
     41 - relied on for policy decisions such as SSRF prevention or host allowlists
     42 
     43 Prefer APIs that write into a caller-provided buffer (`inet_ntop`, `snprintf`, explicit copies with fixed bounds).
     44 
     45 ### Validated input reused later in `system()` / shell-outs
     46 
     47 A frequent review failure is validating input with a parser and later reusing the **original raw string** in a shell command:
     48 
     49 ```c
     50 if (!inet_aton(ip_addr, &parsed)) {
     51     return 1;
     52 }
     53 
     54 snprintf(cmd, sizeof(cmd), "ping '%s'", ip_addr);
     55 system(cmd);
     56 ```
     57 
     58 Parsing the data does **not** make the original string safe. If execution reaches `system()`, `popen()`, `execl("/bin/sh", ...)`, or similar shell-backed helpers, metacharacters in the original input can still become **command injection / RCE**.
     59 
     60 During review, check for this sequence:
     61 
     62 1. Input is parsed or normalized into a structured object.
     63 2. A security decision is made using the parsed form.
     64 3. The original string is later passed to a shell.
     65 
     66 Safer patterns:
     67 
     68 - avoid the shell entirely
     69 - use `execve()`/`posix_spawn()` with a fixed argv array
     70 - derive the executed argument from the validated canonical form instead of the original input
     71 
     72 ### User-controlled registry/config source steering kernel control flow
     73 
     74 In Windows driver code, a **user-chosen registry path** or similar configuration source should not directly influence privileged control flow. Review patterns such as:
     75 
     76 - `WdfRequestRetrieveInputBuffer` or IOCTL input supplying a registry path
     77 - `RtlQueryRegistryValues(..., RTL_QUERY_REGISTRY_DIRECT, ...)` writing directly into stack/local variables
     78 - queried values selecting callbacks, operation modes, or other security-sensitive branches
     79 
     80 If the attacker controls the key path, they often control not only the data but also the **value type, size, and presence/absence semantics**. That can turn a "read config and choose a callback" workflow into **reliable DoS** and sometimes a **kernel code execution primitive**.
     81 
     82 Red flags during review:
     83 
     84 - absolute registry paths accepted from user mode
     85 - no allowlist of trusted hives/keys
     86 - no strict type/length validation before copying into integers/structs
     87 - registry-derived values stored globally and later used as function pointers, dispatch selectors, or capability flags
     88 
     89 ### Windows path handling footguns worth checking
     90 
     91 For Windows usermode reviews, explicitly audit for:<sup>[[1]](#references)[[2]](#references)</sup>
     92 
     93 - **unquoted path** issues in `CreateProcess*` call sites and service definitions
     94 - ANSI/Wide-char mismatches that let Unicode characters transform during path canonicalization
     95 - **WorstFit / Best-Fit** style issues where ANSI APIs reinterpret Unicode into separators or traversal primitives<sup>[[3]](#references)</sup>
     96 
     97 These are especially relevant when a path passes through validation in wide-char form but is later consumed by an ANSI API or command line builder.
     98 
     99 ## Multi-Language Tools
    100 
    101 ### [Naxus - AI-Gents](https://www.naxusai.com/)
    102 
    103 There is a **free package to review PRs**.
    104 
    105 ### Agentic SAST pipelines
    106 
    107 Modern **AI-assisted code review** works better as a **staged pipeline** than as a single `scan this repo` prompt. A practical pattern used by tools such as **[Visa Vulnerability Agentic Harness (VVAH)](https://github.com/visa/visa-vulnerability-agentic-harness)** is:<sup>[[4]](#references)[[5]](#references)</sup>
    108 
    109 Large defensive initiatives such as Project Glasswing also illustrate the growing use of frontier models for vulnerability discovery, but model output still needs evidence-based human validation before remediation.<sup>[[7]](#references)</sup>
    110 
    111 1. **Threat-model first**: inventory entrypoints, assets, trust boundaries, API boundaries, authz paths, taint candidates and reachable components before deep review. If available, enrich this with CMDB / known-CVE / control data so the model prioritizes realistic attack paths instead of isolated code smells.
    112 2. **Split research by lens**: run separate passes for access control, business logic, crypto, deserialization, IaC, batch/ETL, or language-specific sinks instead of trusting one generic review.
    113 3. **Require deterministic gates**: only promote a finding if it survives policy checks such as evidence completeness, majority voting, or repeated independent review.
    114 4. **Add adversarial verification**: force a second pass that tries to prove the trust-boundary crossing and exploitability: attacker-controlled input, source-to-sink reachability, missing authorization, privilege boundary crossed, and realistic impact.
    115 5. **Report chains, not only single bugs**: deduplicate related findings, map them to **CWE/CVSS**, and emit **SARIF** so the output can be ingested by code-scanning and vuln-management platforms.
    116 
    117 This usually produces fewer but **higher-signal triage candidates** and is especially useful in large repos where the bottleneck is analyst triage time rather than raw finding count.
    118 
    119 #### Quick start example with `vvaharness`
    120 
    121 ```bash
    122 python3 -m venv .venv
    123 source .venv/bin/activate
    124 pip install .
    125 vvaharness doctor
    126 vvaharness estimate --repo /path/to/target
    127 vvaharness scan --repo /path/to/target --application-id 12345
    128 ```
    129 
    130 Useful operational details:
    131 
    132 - `vvaharness scan --resume` skips completed checkpoints after an interruption.
    133 - Per-target output is written under `<target>/security-scan/` as Markdown reports, `*.sarif`, and `*_errors.jsonl`.
    134 - Treat results as **triage candidates**, not confirmed vulns: this kind of pipeline is best at prioritising manual review, not replacing it.
    135 
    136 ### [**Semgrep**](https://github.com/returntocorp/semgrep)
    137 
    138 It's an **Open Source tool**.
    139 
    140 #### Supported Languages
    141 
    142 | Category     | Languages                                                                                             |
    143 | ------------ | ----------------------------------------------------------------------------------------------------- |
    144 | GA           | C# · Go · Java · JavaScript · JSX · JSON · PHP · Python · Ruby · Scala · Terraform · TypeScript · TSX |
    145 | Beta         | Kotlin · Rust                                                                                         |
    146 | Experimental | Bash · C · C++ · Clojure · Dart · Dockerfile · Elixir · HTML · Julia · Jsonnet · Lisp ·               |
    147 
    148 #### Quick Start
    149 
    150 ```bash
    151 # Install https://github.com/returntocorp/semgrep#option-1-getting-started-from-the-cli
    152 brew install semgrep
    153 
    154 # Go to your repo code and scan
    155 cd repo
    156 semgrep scan --config auto
    157 ```
    158 
    159 You can also use the [**semgrep VSCode Extension**](https://marketplace.visualstudio.com/items?itemName=Semgrep.semgrep) to get the findings inside VSCode.
    160 
    161 ### [**SonarQube**](https://www.sonarsource.com/products/sonarqube/downloads/)
    162 
    163 There is an installable **free version**.
    164 
    165 #### Quick Start
    166 
    167 ```bash
    168 # Run the platform in Docker
    169 docker run -d --name sonarqube -e SONAR_ES_BOOTSTRAP_CHECKS_DISABLE=true -p 9000:9000 sonarqube:latest
    170 # Install cli tool
    171 brew install sonar-scanner
    172 
    173 # Go to localhost:9000 and login with admin:admin or admin:sonar
    174 # Generate a local project and then a TOKEN for it
    175 
    176 # Using the token and from the folder with the repo, scan it
    177 cd path/to/repo
    178 sonar-scanner \
    179   -Dsonar.projectKey=<project-name> \
    180   -Dsonar.sources=. \
    181   -Dsonar.host.url=http://localhost:9000 \
    182   -Dsonar.token=<sonar_project_token>
    183 ```
    184 
    185 ### CodeQL
    186 
    187 The CodeQL CLI is available for research and open-source use; review the current GitHub CodeQL terms before using it for private or commercial analysis.
    188 
    189 #### Install
    190 
    191 ```bash
    192 # Download your release from https://github.com/github/codeql-action/releases
    193 ## Example
    194 wget https://github.com/github/codeql-action/releases/download/codeql-bundle-v2.14.3/codeql-bundle-osx64.tar.gz
    195 
    196 # Move it to the destination folder
    197 mkdir ~/codeql
    198 mv codeql-bundle* ~/codeql
    199 
    200 # Decompress it
    201 cd ~/codeql
    202 tar -xzvf codeql-bundle-*.tar.gz
    203 rm codeql-bundle-*.tar.gz
    204 
    205 # Add to path
    206 echo 'export PATH="$PATH:/Users/username/codeql/codeql"' >> ~/.zshrc
    207 
    208 # Check it's correctly installed
    209 ## Open a new terminal
    210 codeql resolve qlpacks #Get paths to QL packs
    211 ```
    212 
    213 #### Quick Start - Prepare the database
    214 
    215 > [!TIP]
    216 > The first thing you need to do is to **prepare the database** (create the code tree) so later the queries are run over it.
    217 
    218 - You can allow codeql to automatically identify the language of the repo and create the database
    219 
    220 ```bash
    221 codeql database create <database> --language <language>
    222 
    223 # Example
    224 codeql database create /path/repo/codeql_db --source-root /path/repo
    225 ## DB will be created in /path/repo/codeql_db
    226 ```
    227 
    228 > [!CAUTION]
    229 > This may report an error when more than one language is specified or automatically detected. Use one of the following options.
    230 
    231 - You can do this **manually indicating** the **repo** and the **language** ([list of languages](https://docs.github.com/en/code-security/codeql-cli/getting-started-with-the-codeql-cli/preparing-your-code-for-codeql-analysis#running-codeql-database-create))
    232 
    233 ```bash
    234 codeql database create <database> --language <language> --source-root </path/to/repo>
    235 
    236 # Example
    237 codeql database create /path/repo/codeql_db --language javascript --source-root /path/repo
    238 ## DB will be created in /path/repo/codeql_db
    239 ```
    240 
    241 - If your repo is using **more than 1 language**, you can also create **1 DB per language** indicating each language.
    242 
    243 ```bash
    244 export GITHUB_TOKEN=ghp_32849y23hij4...
    245 codeql database create <database> --source-root /path/to/repo --db-cluster --language "javascript,python"
    246 
    247 # Example
    248 export GITHUB_TOKEN=ghp_32849y23hij4...
    249 codeql database create /path/repo/codeql_db --source-root /path/to/repo --db-cluster --language "javascript,python"
    250 ## DBs will be created in /path/repo/codeql_db/*
    251 ```
    252 
    253 - You can also allow `codeql` to **identify all the languages** for you and create a DB per language. You need to give it a **GITHUB_TOKEN**.
    254 
    255 ```bash
    256 export GITHUB_TOKEN=ghp_32849y23hij4...
    257 codeql database create <database> --db-cluster --source-root </path/to/repo>
    258 
    259 # Example
    260 export GITHUB_TOKEN=ghp_32849y23hij4...
    261 codeql database create /tmp/codeql_db --db-cluster --source-root /path/repo
    262 ## DBs will be created in /path/repo/codeql_db/*
    263 ```
    264 
    265 #### Quick Start - Analyze the code
    266 
    267 > [!TIP]
    268 > Now it's finally time to analyze the code
    269 
    270 If you selected several languages, CodeQL creates **one database per language** under the specified path.
    271 
    272 ```bash
    273 # Default analysis
    274 codeql database analyze <database> --format=<format> --output=</out/file/path>
    275 # Example
    276 codeql database analyze /tmp/codeql_db/javascript --format=sarif-latest --output=/tmp/graphql_results.sarif
    277 
    278 # Specify QL pack to use in the analysis
    279 codeql database analyze <database> \
    280     <qls pack> --sarif-category=<language> \
    281     --sarif-add-baseline-file-info --format=<format> \
    282     --output=/out/file/path>
    283 # Example
    284 codeql database analyze /tmp/codeql_db \
    285     javascript-security-extended --sarif-category=javascript \
    286     --sarif-add-baseline-file-info --format=sarif-latest \
    287     --output=/tmp/sec-extended.sarif
    288 ```
    289 
    290 #### Quick Start - Scripted
    291 
    292 ```bash
    293 export GITHUB_TOKEN=ghp_32849y23hij4...
    294 export REPO_PATH=/path/to/repo
    295 export OUTPUT_DIR_PATH="$REPO_PATH/codeql_results"
    296 mkdir -p "$OUTPUT_DIR_PATH"
    297 export FINAL_MSG="Results available in: "
    298 
    299 echo "Creating DB"
    300 codeql database create "$REPO_PATH/codeql_db" --db-cluster --source-root "$REPO_PATH"
    301 for db_path in "$REPO_PATH"/codeql_db/*; do
    302     db=$(basename "$db_path")
    303     echo "Analyzing $db"
    304     codeql database analyze "$db_path" --format=sarif-latest --output="${OUTPUT_DIR_PATH}/$db.sarif"
    305     FINAL_MSG="$FINAL_MSG ${OUTPUT_DIR_PATH}/$db.sarif ,"
    306     echo ""
    307 done
    308 
    309 echo $FINAL_MSG
    310 ```
    311 
    312 You can visualize the findings in [**https://microsoft.github.io/sarif-web-component/**](https://microsoft.github.io/sarif-web-component/) or using VSCode extension [**SARIF viewer**](https://marketplace.visualstudio.com/items?itemName=MS-SarifVSCode.sarif-viewer).
    313 
    314 You can also use the [**VSCode extension**](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-codeql) to get the findings inside VSCode. You will still need to create a database manually, but then you can select any files and click on `Right Click` -> `CodeQL: Run Queries in Selected Files`
    315 
    316 ### [**Snyk**](https://snyk.io/product/snyk-code/)
    317 
    318 There is an **installable free version**.
    319 
    320 #### Quick Start
    321 
    322 ```bash
    323 # Install
    324 sudo npm install -g snyk
    325 
    326 # Authenticate (you can use a free account)
    327 snyk auth
    328 
    329 # Test for open source vulns & license issues
    330 snyk test [--all-projects]
    331 
    332 # Test for code vulnerabilities
    333 ## This will upload your code and you need to enable this option in: Settings > Snyk Code
    334 snyk test code
    335 
    336 # Test for vulns in images
    337 snyk container test [image]
    338 
    339 # Test for IaC vulns
    340 snyk iac test
    341 ```
    342 
    343 You can also use the [**snyk VSCode Extension**](https://marketplace.visualstudio.com/items?itemName=snyk-security.snyk-vulnerability-scanner) to get findings inside VSCode.
    344 
    345 ### [Insider](https://github.com/insidersec/insider)
    346 
    347 It's **Open Source**, but looks **unmaintained**.
    348 
    349 #### Supported Languages
    350 
    351 Java (Maven and Android), Kotlin (Android), Swift (iOS), .NET Full Framework, C#, and Javascript (Node.js).
    352 
    353 #### Quick Start
    354 
    355 ```bash
    356 # Check the correct release for your environment
    357 $ wget https://github.com/insidersec/insider/releases/download/2.1.0/insider_2.1.0_linux_x86_64.tar.gz
    358 $ tar -xf insider_2.1.0_linux_x86_64.tar.gz
    359 $ chmod +x insider
    360 $ ./insider --tech javascript  --target <projectfolder>
    361 ```
    362 
    363 ### [**DeepSource**](https://deepsource.com/pricing)
    364 
    365 Free for **public repos**.
    366 
    367 ## NodeJS
    368 
    369 - **`yarn`**
    370 
    371 ```bash
    372 # Install
    373 brew install yarn
    374 # Run
    375 cd /path/to/repo
    376 yarn install
    377 yarn audit # In lower versions
    378 yarn npm audit # In 2+ versions
    379 
    380 npm audit
    381 ```
    382 
    383 - **`pnpm`**
    384 
    385 ```bash
    386 # Install
    387 npm install -g pnpm
    388 # Run
    389 cd /path/to/repo
    390 pnpm install
    391 pnpm audit
    392 ```
    393 
    394 - [**nodejsscan**](https://github.com/ajinabraham/nodejsscan)**:** Static security code scanner (SAST) for Node.js applications powered by [libsast](https://github.com/ajinabraham/libsast) and [semgrep](https://github.com/returntocorp/semgrep).
    395 
    396 ```bash
    397 # Install & run
    398 docker run -it -p 9090:9090 opensecurity/nodejsscan:latest
    399 # Go to localhost:9090
    400 # Upload a zip file with the code
    401 ```
    402 
    403 - [**RetireJS**](https://github.com/RetireJS/retire.js)**:** The goal of Retire.js is to help you detect the use of JS-library versions with known vulnerabilities.
    404 
    405 ```bash
    406 # Install
    407 npm install -g retire
    408 # Run
    409 cd /path/to/repo
    410 retire --colors
    411 ```
    412 
    413 ## Electron
    414 
    415 - [**electronegativity**](https://github.com/doyensec/electronegativity)**:** It's a tool to identify misconfigurations and security anti-patterns in Electron-based applications.
    416 
    417 ## Python
    418 
    419 - [**Bandit**](https://github.com/PyCQA/bandit)**:** Bandit is a tool designed to find common security issues in Python code. To do this Bandit processes each file, builds an AST from it, and runs appropriate plugins against the AST nodes. Once Bandit has finished scanning all the files it generates a report.
    420 
    421 ```bash
    422 # Install
    423 pip3 install bandit
    424 
    425 # Run
    426 bandit -r <path to folder>
    427 ```
    428 
    429 - [**safety**](https://github.com/pyupio/safety): Safety checks Python dependencies for known security vulnerabilities and suggests the proper remediations for vulnerabilities detected. Safety can be run on developer machines, in CI/CD pipelines and on production systems.
    430 
    431 ```bash
    432 # Install
    433 pip install safety
    434 # Run
    435 safety check
    436 ```
    437 
    438 - [~~**Pyt**~~](https://github.com/python-security/pyt): Unmaintained.
    439 
    440 ## .NET
    441 
    442 ```bash
    443 # dnSpy
    444 https://github.com/0xd4d/dnSpy
    445 
    446 # .NET compilation
    447 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe test.cs
    448 ```
    449 
    450 ## Rust
    451 
    452 ```bash
    453 # Install
    454 cargo install cargo-audit
    455 
    456 # Run
    457 cargo audit
    458 
    459 #Update the Advisory Database
    460 cargo audit fetch
    461 ```
    462 
    463 ## Java
    464 
    465 ```bash
    466 # JD-Gui
    467 https://github.com/java-decompiler/jd-gui
    468 
    469 # Java compilation step-by-step
    470 javac -source 1.8 -target 1.8 test.java
    471 mkdir META-INF
    472 echo "Main-Class: test" > META-INF/MANIFEST.MF
    473 jar cmvf META-INF/MANIFEST.MF test.jar test.class
    474 ```
    475 
    476 | Task            | Command                                                   |
    477 | --------------- | --------------------------------------------------------- |
    478 | Execute Jar     | java -jar \[jar]                                          |
    479 | Unzip Jar       | unzip -d \[output directory] \[jar]                       |
    480 | Create Jar      | jar -cmf META-INF/MANIFEST.MF \[output jar] \*            |
    481 | Base64 SHA256   | sha256sum \[file] \| cut -d' ' -f1 \| xxd -r -p \| base64 |
    482 | Remove Signing  | rm META-INF/_.SF META-INF/_.RSA META-INF/\*.DSA           |
    483 | Delete from Jar | zip -d \[jar] \[file to remove]                           |
    484 | Decompile class | procyon -o . \[path to class]                             |
    485 | Decompile Jar   | procyon -jar \[jar] -o \[output directory]                |
    486 | Compile class   | javac \[path to .java file]                               |
    487 
    488 ## Go
    489 
    490 ```bash
    491 https://github.com/securego/gosec
    492 ```
    493 
    494 ## PHP
    495 
    496 [Psalm](https://phpmagazine.net/2018/12/find-errors-in-your-php-applications-with-psalm.html) and [PHPStan](https://phpmagazine.net/2020/09/phpstan-pro-edition-launched.html).
    497 
    498 ### Wordpress Plugins
    499 
    500 [https://www.pluginvulnerabilities.com/plugin-security-checker/](https://www.pluginvulnerabilities.com/plugin-security-checker/)
    501 
    502 ## Solidity
    503 
    504 - [https://www.npmjs.com/package/solium](https://www.npmjs.com/package/solium)
    505 
    506 ## JavaScript
    507 
    508 ### Discovery
    509 
    510 1. Burp:
    511    - Spider and discover content
    512    - Sitemap > filter
    513    - Sitemap > right-click domain > Engagement tools > Find scripts
    514 2. [WaybackURLs](https://github.com/tomnomnom/waybackurls):
    515    - `waybackurls <domain> |grep -i "\.js" |sort -u`
    516 
    517 ### Static Analysis
    518 
    519 #### Unminimize/Beautify/Prettify
    520 
    521 - [https://prettier.io/playground/](https://prettier.io/playground/)
    522 - [https://beautifier.io/](https://beautifier.io/)
    523 - [OlaJS JavaScript Prettifier](https://olajs.com/javascript-prettifier)<sup>[[14]](#references)</sup>
    524 - See some of the tools mentioned in 'Deobfuscate/Unpack' below as well.
    525 
    526 #### Deobfuscate/Unpack
    527 
    528 **Note**: It may not be possible to fully deobfuscate.<sup>[[6]](#references)</sup>
    529 
    530 1. Find and use .map files:
    531    - If the .map files are exposed, they can be used to easily deobfuscate.
    532    - Commonly, foo.js.map maps to foo.js. Manually look for them.
    533    - Use [JS Miner](https://github.com/PortSwigger/js-miner) to look for them.
    534    - Ensure active scan is conducted.
    535    - Read '[Tips/Notes](https://github.com/minamo7sen/burp-JS-Miner/wiki#tips--notes)'
    536    - If found, use [Maximize](https://www.npmjs.com/package/maximize) to deobfuscate.
    537    - For webpack chunk structure, runtime injection, React/Vue/Angular internals, and DevTools workflows, consult the webpack reverse-engineering notes and related JavaScript research gists.<sup>[[11]](#references)[[12]](#references)</sup>
    538 2. Without .map files, try JSnice:
    539    - References: [http://jsnice.org/](http://jsnice.org/) & [https://www.npmjs.com/package/jsnice](https://www.npmjs.com/package/jsnice)
    540    - Tips:
    541      - If using jsnice.org, click on the options button next to the "Nicify JavaScript" button, and de-select "Infer types" to reduce cluttering the code with comments.
    542      - Ensure you do not leave any empty lines before the script, as it may affect the deobfuscation process and give inaccurate results.
    543 3. For some more modern alternatives to JSNice, you might like to look at the following:
    544 
    545 - [https://github.com/pionxzh/wakaru](https://github.com/pionxzh/wakaru)
    546   - > Javascript decompiler, unpacker and unminify toolkit Wakaru is the Javascript decompiler for modern frontend. It brings back the original code from a bundled and transpiled source.
    547 - [https://github.com/j4k0xb/webcrack](https://github.com/j4k0xb/webcrack)
    548   - > Deobfuscate obfuscator.io, unminify and unpack bundled javascript
    549 - [https://github.com/jehna/humanify](https://github.com/jehna/humanify)
    550   - > Un-minify JavaScript code using an LLM. The model suggests variable and function names, while Babel performs structural transformations to preserve equivalent code.
    551   - [https://thejunkland.com/blog/using-llms-to-reverse-javascript-minification.html](https://thejunkland.com/blog/using-llms-to-reverse-javascript-minification.html)
    552     - > Using LLMs to reverse JavaScript variable name minification
    553 
    554 4. Use `console.log()`:
    555    - Find the return value at the end and change it to `console.log(<packerReturnVariable>);` so the deobfuscated JavaScript is printed instead of executed.
    556    - Then, paste the modified (and still obfuscated) js into [https://jsconsole.com/](https://jsconsole.com/) to see the deobfuscated js logged to the console.
    557    - Finally, paste the deobfuscated output into [https://prettier.io/playground/](https://prettier.io/playground/) to beautify it for analysis.
    558    - **Note**: If you are still seeing packed (but different) js, it may be recursively packed. Repeat the process.
    559 
    560 #### Tools
    561 
    562 - [https://portswigger.net/burp/documentation/desktop/tools/dom-invader](https://portswigger.net/burp/documentation/desktop/tools/dom-invader)
    563 - Dynamic-analysis walkthrough: DAST JavaScript Dynamic Analysis.<sup>[[8]](#references)</sup>
    564 - Angular-specific review background: the archived “Angular for Pentesters” parts 1 and 2.<sup>[[9]](#references)[[10]](#references)</sup>
    565 - [CyberChef](https://cyberchef.org/) is useful for decoding, decompressing, and transforming captured bundle data.<sup>[[13]](#references)</sup>
    566 - [JSHint](https://jshint.com/) and its source repository provide lightweight JavaScript quality/static checks.<sup>[[15]](#references)[[16]](#references)</sup>
    567 
    568 ## References
    569 
    570 - [1] [Trail of Bits blog: Master C and C++ with our new Testing Handbook chapter](https://blog.trailofbits.com/2026/04/09/master-c-and-c-with-our-new-testing-handbook-chapter/)
    571 - [2] [Trail of Bits Testing Handbook: C/C++](https://appsec.guide/docs/languages/c-cpp/)
    572 - [3] [DEVCORE: WorstFit - Unveiling Hidden Transformers in Windows ANSI](https://devco.re/blog/2025/01/09/worstfit-unveiling-hidden-transformers-in-windows-ansi/)
    573 - [4] [Visa Vulnerability Agentic Harness](https://github.com/visa/visa-vulnerability-agentic-harness)
    574 - [5] [VVAH Architecture](https://github.com/visa/visa-vulnerability-agentic-harness/blob/main/docs/architecture.md)
    575 - [6] [devalias – Deobfuscating / Unminifying Obfuscated Web App Code (GitHub Gist)](https://gist.github.com/0xdevalias/d8b743efb82c0e9406fc69da0d6c6581#deobfuscating--unminifying-obfuscated-web-app-code)
    576 - [7] [Anthropic Project Glasswing](https://www.anthropic.com/glasswing)
    577 - [8] [YouTube: DAST - Javascript Dynamic Analysis](https://www.youtube.com/watch?v=_v8r_t4v6hQ)
    578 - [9] [nVisium Blog: Angular for Pentesters – Part 1](https://web.archive.org/web/20221226054137/https://blog.nvisium.com/angular-for-pentesters-part-1)
    579 - [10] [nVisium Blog: Angular for Pentesters – Part 2](https://web.archive.org/web/20230204012439/https://blog.nvisium.com/angular-for-pentesters-part-2)
    580 - [11] [devalias – Reverse Engineering Webpack Apps (GitHub Gist)](https://gist.github.com/0xdevalias/8c621c5d09d780b1d321bfdb86d67cdd#reverse-engineering-webpack-apps)
    581 - [12] [devalias – further JavaScript-related GitHub Gists (search)](https://gist.github.com/search?q=user:0xdevalias+javascript)
    582 - [13] [CyberChef](https://cyberchef.org/)
    583 - [14] [OlaJS JavaScript Prettifier](https://olajs.com/javascript-prettifier)
    584 - [15] [JSHint](https://jshint.com/)
    585 - [16] [jshint (GitHub repository)](https://github.com/jshint/jshint/)