Shellharden is a syntax highlighter and a tool to semi-automate the rewriting of scripts to ShellCheck conformance, mainly focused on quoting

Overview

Build and test status

Shellharden

Shellharden is a syntax highlighter and a tool to semi-automate the rewriting of scripts to ShellCheck conformance, mainly focused on quoting.

The default mode of operation is like cat, but with syntax highlighting in foreground colors and suggestive changes in background colors:

real-world example

Above: Selected portions of xdg-desktop-menu as highlighted by Shellharden. The foreground colors are syntax highlighting, whereas the background colors (green and red) show characters that Shellharden would have added or removed if let loose with the --transform option. Below: An artificial example that shows more tricky cases and special features.

artificial example

Why

A variable in bash is like a hand grenade – take off its quotes, and it starts ticking. Hence, rule zero of bash pitfalls: Always use quotes.

Name

Shellharden can do what Shellcheck can't: Apply the suggested changes.

In other words, harden vulnerable shellscripts. The builtin assumption is that the script does not depend on the vulnerable behavior – the user is responsible for the code review.

Shellharden was previously known as "Naziquote". In the right jargon, that was the best name ever, but oh so misleading and unspeakable to outsiders.

I couldn't call it "bash cleaner" either, as that means "poo smearer" in Norwegian.

Prior art

  • Shellcheck is a wonderful tool to detect, and give general advice, about vulnerable bash code. The only thing missing is something to say yes with, and apply those advice (assuming proper review of course).

  • I asked this SO question, for a tool that could rewrite bash scripts with proper quoting. One answerer beat me to it. But if it was me, I would do a syntax highlighter in the same tool (as a way to see if the parser gets lost, and make the most out of the parser, because bash is like quantum mechanics – nobody really knows how it works).

Get it

Distro packages:

Packaging status

Official rust package:

cargo install shellharden

For those allergic to building from source, a few precompiled binaries are also available in the releases.

Build from source

cargo build --release

Run tests

cargo test --release

(requires bash)

Install

cp target/release/shellharden /usr/local/bin/

Fuzz test

cargo install afl
cargo afl build --release
cargo afl fuzz -i moduletests/original -o /tmp/fuzz-shellharden target/release/shellharden '@@'

Usage advice

Don't apply --transform blindly; code review is still necessary: A script that relies on unquoted behavior (implicit word splitting and glob expansion from variables and command substitutions) to work as intended will do none of that after getting the --transform treatment!

In that unlucky case, ask yourself whether the script has any business in doing that. All too often, it's just a product of classical shellscripting, and would be better off rewritten, such as by using arrays. Even in the opposite case, say the business logic involves word splitting; that can still be done without invoking globbing. In short: There is always a better way than the forbidden syntax (if not more explicit), but some times, a human must step in to rewrite. See how, in the accompanying how to do things safely in bash.

Comments
  • [Request] Always use curly braces for variables

    [Request] Always use curly braces for variables

    I really love shellharden so far, since that allows me to quickly rewrite scripts that I wrote too hastily :slightly_smiling_face: . But when I ran it on a script I put a lot of effort in, it suggested to remove the braces ({, }), in places that do not strictly need them, which is something I prefer to do.

    A variable in bash is like a hand grenade – take off its quotes, and it starts ticking.

    For the same reason I prefer to always use the braces. Since I do not know how the line will change in the future.

    Would it be possible to make shellharden do this? Perhaps as a configuration option?

    A simple example which would have been prevented by always using braces:

    my_file='abc.txt'
    cp "$my_file"{,_copy}
    ls "$my_file"
    
    my_file='abc.txt'
    cp "$my_file"{,_copy}
    ls "$my_file_copy"  # error, unset variable
    
    opened by techhazard 9
  • Just cats the script

    Just cats the script

    Running shellharden erratic-script on macOS (via Homebrew) simply outputs the script as-is. No syntax highlighting or no suggestions. For comparison, shellcheck erratic-script outputs a bunch of errors. What could be wrong?

    opened by forthrin 9
  • Logo Contribution

    Logo Contribution

    Hi I just saw your app and if you need a new logo or widget design i can help you You can tell me what kind of a logo do you want I am waiting for you reply

    opened by revilationer 6
  • Allow unquoted arguments to local et al

    Allow unquoted arguments to local et al

    I've grown accustom to not quoting the right hand side of variable assignments,

    var=$othervar
    var=$(subshell)
    var=value
    

    This is perfectly safe in all POSIX shells (AFAIK). Reference.

    Shellharden adds quotes to all of these. Do you consider this a bug?

    opened by pbrisbin 5
  • Why not use Cargo?

    Why not use Cargo?

    I was wondering why you didn't use Cargo. Is it a matter of choice or it is because you're not comfortable with it?

    Furthermore, using Cargo will allow you to publish your project on Crates.io and setup a test suite more easily.

    opened by kimond 5
  • Quoting not needed inside double brackets

    Quoting not needed inside double brackets

    Quoting is generally not needed when variables are used between double brackets ([[ and ]]).

    Here is a test case that does not expand:

    x='*'; if [[ $x == '*' ]]; then echo not expanded; fi
    

    While with single brackets, this is the result:

    x='*'; if [ $x == '*' ]; then echo not expanded; fi
    bash: [: too many arguments
    

    shellharden wants to add double quotes around $x in the first case, but this is not really needed.

    feature request 
    opened by xyproto 5
  • An argument for preferring curly braces

    An argument for preferring curly braces

    In reply to https://github.com/anordal/shellharden/blob/master/how_to_do_things_safely_in_bash.md#should-i-use-curly-braces :

    Correct: some_command "${arg1}" "${arg2}" "${arg3}" Better: some_command "$arg1" "$arg2" "$arg3"

    Curly braces should be preferred in order to limit the risk that a variable named a prefix of other variables does not alter other variables. An example:

    arg="example"
    some_command "$arg1" "$arg2" "$arg3"
    some_command "${arg1}" "${arg2}" "${arg3}"
    
    opened by westurner 5
  • RELEASES: 4.1.2, 4.1.3, 4.2.0 missing?

    RELEASES: 4.1.2, 4.1.3, 4.2.0 missing?

    Version 4.1.1 is the most recent release according to https://github.com/anordal/shellharden/releases, but looking at the https://github.com/anordal/shellharden/tags, it looks like there are also 4.1.2, 4.1.3, and 4.2.0?

    Is it an oversight that those versions are not "released"?

    opened by HenrikBengtsson 3
  • Request for Pacstall support

    Request for Pacstall support

    Pacstall is a community-driven AUR-like package manager for Ubuntu. We have an ongoing pull request to add shellharden to our repository.

    We have a few questions for you:

    • Would you like to maintain the pacscript (similar to a PKGBUILD) yourself? We can maintain it for you if you decide not to.
    • Could you include a section in your documentation showing Pacstall as a valid method of installation for Shellharden for Debian/Ubuntu users? We could make a pull request for that if you want.
    opened by Henryws 3
  • Rewrite examples in `printf` wherever possible?

    Rewrite examples in `printf` wherever possible?

    opened by gsklee 3
  • Use arrays, has no array use example

    Use arrays, has no array use example

    Hello,

    The section on using arrays could really do with an example of using an array in a loop.

    https://github.com/anordal/shellharden/blob/master/how_to_do_things_safely_in_bash.md#use-arrays-ftw

    maybe

    xs=(
     a
     b
    )
    for x in "${xs[@]}" ; do 
     echo "$x"
    end
    

    But I did not submit a PR because I am not sure that is actually correct.

    Thanks for the great resource!

    opened by EvanTheB 3
  • README: Add example of the calls plus maybe a section with `shellharden --help` output

    README: Add example of the calls plus maybe a section with `shellharden --help` output

    Brilliant tool. Thanks. I just learned about it today, and I found it hard to figure out exactly what the tool was, or if there were multiple tools without downloading/installing it. I'd like to suggest adding a section to the README.md that shows some example calls, e.g.

    $ shellharden script.sh
    

    maybe immediately above each screenshot example.

    Another thing that would help people "passing by" could be to add:

    # Usage
    
    ` ```
    $ shellharden --help
    Shellharden: The corrective bash syntax highlighter.
    
    Usage:
    	shellharden [options] [files]
    	cat files | shellharden [options] ''
    
    Shellharden is a syntax highlighter and a tool to semi-automate the rewriting
    of scripts to ShellCheck conformance, mainly focused on quoting.
    
    The default mode of operation is like `cat`, but with syntax highlighting in
    foreground colors and suggestive changes in background colors.
    
    Options:
    	--suggest         Output a colored diff suggesting changes.
    	--syntax          Output syntax highlighting with ANSI colors.
    	--syntax-suggest  Diff with syntax highlighting (default mode).
    	--transform       Output suggested changes.
    	--check           No output; exit with 2 if changes are suggested.
    	--replace         Replace file contents with suggested changes.
    	--                Don't treat further arguments as options.
    	-h|--help         Show help text.
    	--version         Show version.
    
    The changes suggested by Shellharden inhibits word splitting and indirect
    pathname expansion. This will make your script ShellCheck compliant in terms of
    quoting. Whether your script will work afterwards is a different question:
    If your script was using those features on purpose, it obviously won't anymore!
    
    Every script is possible to write without using word splitting or indirect
    pathname expansion, but it may involve doing things differently.
    See the accompanying file how_to_do_things_safely_in_bash.md or online:
    https://github.com/anordal/shellharden/blob/master/how_to_do_things_safely_in_bash.md
    ` ```
    
    ## Usage advice
    
    Don't apply `--transform` blindly; code review is still necessary: A script that relies on unquoted behavior
    (implicit word splitting and glob expansion from variables and command substitutions) …
    

    which of course requires more work, since you need to remember to update it whenever --help output changes

    opened by HenrikBengtsson 0
  • (feat) dockerize shellharden

    (feat) dockerize shellharden

    Enables a user to run shellharden in a Docker container.

    • Add Dockerfile & entrypoint
    • Update README.md
      • Add Docker usage
      • Wrap lines to make it easier to read from CLI
      • Correct misc. grammar & punctuation

    I did this so I can use it in a CI/CD pipeline, but thought it might be worth contributing back. If you want, I can publish it to docker hub before you accept this PR.

    Thanks for such a great tool!

    Signed-off-by: Vladislav Doster [email protected]

    opened by vladdoster 2
  • Separate out into a library?

    Separate out into a library?

    Hi there!

    shellharden looks fantastic, and I was considering integrating it into some lint infrastructure we have. However, it looks like the only stable interface is a binary. Would you consider separating out the checks into a library and providing a Rust API as well?

    A bonus would be if you could read files from memory rather than the file system -- perhaps via a trait that specifies how files should be read.

    I do something similar for a tool I'm the primary author of, cargo-guppy, where there's both a Rust interface (guppy) and a CLI tool (cargo-guppy).

    Thank you!

    opened by sunshowers 1
Releases(v4.1.1)
Owner
Andreas Nordal
Andreas Nordal
A syntax highlighter for Node powered by Tree Sitter. Written in Rust.

tree-sitter-highlight A syntax highlighter for Node.js powered by Tree Sitter. Written in Rust. Usage The following will output HTML: const treeSitter

Devon Govett 211 Dec 20, 2022
100% stream-based O(n) syntax highlighter for ANSI terminal

Lex-highlighter 100% stream-based $\mathcal O(n)$ syntax highlighter for ANSI terminal Warning This is proof-of-concept implementation and WON't be co

Abiria 10 Nov 17, 2023
Best-effort attempt at rewriting Reticulum in Rust.

reticulum-rs WIP rewrite of Reticulum in Rust explicitly targeted at the ESP32 (no tokio, avoids memory-inefficient data structures. etc). Not ready f

Ellen Poe 8 Sep 25, 2023
A cli tool to automate the building and deployment of Bitcoin nodes

ℹ️ Automate Bitcoin builds, speed up deployment Shran is an open-source cli tool being developed to address the needs of DMG Blockchain Solutions. It

Matt Williams 1 Oct 20, 2022
ufo2nft is a CLI Rust tool to automate creating on-chain SVG NFTs from UFO font sources

ufo2nft is a CLI Rust program created by Eli Heuer at the 2022 Seattle Solana Hacker House event. It uses Norad to create on-chain SVG images from UFO font sources, and prepares them for minting as Solana NFTs. For Ethereum NFTs the program can just export the SVGs and Ethereum NFTs can be built manually.

Eli Heuer 1 Feb 10, 2022
Count your code by tokens, types of syntax tree nodes, and patterns in the syntax tree. A tokei/scc/cloc alternative.

tcount (pronounced "tee-count") Count your code by tokens, types of syntax tree nodes, and patterns in the syntax tree. Quick Start Simply run tcount

Adam P. Regasz-Rethy 48 Dec 7, 2022
A collection of semi-useful tools made for GNU/Linux

DECTOOLS A collection of semi-useful tools made for GNU/Linux. Some may work on macOS, though functionality isn't a priority. Depenencies: python, bas

Decator 3 Jun 8, 2022
Semi-persistent, scoped test directories

Semi-persistent, scoped test directories This crate aims to make it easier to use temporary directories in tests, primarily by calling the testdir!()

Floris Bruynooghe 4 Nov 19, 2022
Cork is a simple command-line calculator, mainly targeted towards people who deal with hex numbers

Cork is a simple command-line calculator, mainly targeted towards people who deal with hex numbers. It deals only with integer arithmetic. Expressions may involve mixed bases (limited to decimal, hexadecimal, octal and binary numbers). The global output format may be set to a particular radix - by default it is hex.

Deep Majumder 50 Dec 22, 2022
My solution for the advent of code 2021, mainly written in Rust

Advent-of-Code-2021 My solution for the advent of code 2021, written in Rust Error Handle NOPE!!! unwrap() everything everywhere Use To run all of the

Nguyen Le Duy 0 Jan 8, 2022
A CLI tool for CIs and build scripts, making file system based caching easy and correct (locking, eviction, etc.)

FS Dir Cache A CLI tool for CIs and build scripts, making file system based caching easy and correct (locking, eviction, etc.) When working on build s

Dawid Ciężarkiewicz 5 Aug 29, 2023
Automate your business flows, support, change tickets with Automatdeck

Automatdeck agent Website: https://automatdeck.com Documentation: https://doc.automatdeck.com Automatdeck agent is a simple lightweight IT automation

Kheshav Sewnundun 5 Aug 2, 2022
A command-line tool for patching shell scripts inspired by resholve

patsh A command-line tool for patching shell scripts inspired by resholve nix run github:nix-community/patsh -- -f script.sh Usage Usage: patsh [OPTIO

Nix community projects 23 Jan 7, 2023
rip is a command-line deletion tool focused on safety, ergonomics, and performance

rip (Rm ImProved) rip is a command-line deletion tool focused on safety, ergonomics, and performance. It favors a simple interface, and does not imple

Kevin Liu 776 Jan 1, 2023
An open source, programmed in rust, privacy focused tool for reading programming resources (like stackoverflow) fast, efficient and asynchronous from the terminal.

Falion An open source, programmed in rust, privacy focused tool for reading programming resources (like StackOverFlow) fast, efficient and asynchronou

Obscurely 17 Dec 20, 2022
Self-contained template system with Handlebars and inline shell scripts

Handlematters Self-contained template system with Handlebars and inline shell scripts Introduction Handlematters is a template system that combines Ha

Keita Urashima 3 Sep 9, 2022
Non-interactive nREPL client for shell scripts and command-line

nreplops-tool (nr) nreplops-tool (nr) is a non-interactive nREPL client designed to be used in shell scripts and on the command-line. Early α warning:

Matti Hänninen 3 Jul 1, 2022
Quickly save and retrieve values for shell scripts.

Quickly save and retrieve values for shell scripts.

Alex Andrade 2 Dec 15, 2022
Adds back-and-forth jumping between current and previous focused windows to Sway.

sway-focus-back-and-forth Implements back-and-forth movement between the current and the previous focused windows. It also can be seen as a fix to thi

Vinícius Müller 4 Aug 11, 2022