More Jerky!

Alright, time for more beef jerky. This time I found top round roast for $3.99 per pound. I’m using the same recipe as last time, but it’s 3.5 lbs so I multiplied the marinade by about 1.5. I sliced the meat more along the grain than last time, and also slightly thicker.

1530: Meat is in the marinade.

1020 Sunday: Meat is on the smoker, 175℉, vents half open this time cause why not, that’s what I normally do.

1430: I took all but the fatty pieces of jerky off, leaving those on with temperature increased to 225℉. They were glistening still, and I’d like them to dry out more before taking them off. I’m skeptical about the slightly thicker cuts. They’re definitely done, but will they stay good to eat as long as the thinner stuff did… Did they get dessicated enough to last? Some of the chunks are very much like smoked beef… We’ll see as time passes and I start to eat it… I’m thinking I’ll leave the fatty stuff for another hour.

1540: looks done enough… Taking off the last of it.

Fatty parts got much drier, but still not like the other pieces. I think next time I should start by cutting off all fat. This time I would’ve had to start by slicing the meat along the thin internal fat layer it had, then peeling of that fat. It would’ve left one thin layer of meat and one thick, but that would’ve been ok.

Grilling a Whole Chicken

We have a leftover chicken in the freezer, so it’s time to grill up a whole chicken again! We thawed it in the fridge over a couple days, then I marinated it in a bottle of Jerk sauce. I still haven’t found a great bottle of Jerk sauce – none are even approaching the right spiciness. Oh well. The chicken is medium sized, not as large as a roaster.

1910: Started butterflied chicken on the grill, cold side, skin up, legs towards the fire. I drizzled the bag of marinade over the raw chicken. When the breasts hit 130℉ and the legs 145℉ or so, I’ll flip it over and hit the skin for 5 minutes until breasts are 145℉ or so.

1940: Breasts are at 110℉.

2000: Breasts are between 131℉ and 145℉ – time to flip it and crisp the skin.

2005: Taking chicken off to rest 10 minutes.

Delicious. After it rested, I sliced it up and put on more Jerk sauce. I heated up the sauce before basting it on. Definitely do that again.

Smoking Salmon

Smoked salmon is one of my favorite foods. A luxury, truly. But, it’s much more reasonable when you can smoke it yourself. Salmon prices are at $8.99 a pound at Costco right now, which is a couple bucks more than I’m used to. Still worth it.

I’m using the same recipe I always use, with a bit over 5 lbs of salmon. This salmon was packed a couple days ago, unusually. Normally the Costco salmon on display is all packed the same day. It must sell out quickly, it is always beautiful. This fish still had a sell by day 4 days in the future, though. And it still looked beautiful. There was little liquid in the tray, the fillets were spotless… And they were $1 less per pound than the same day-packed stuff. Unpackaging the salmon, I sniffed for any unexpected scents, and looked for any defects with the fish. I found none.

2000: Fish went into brine.

0840: Fish began drying.

1120: Fish is on the smoker at 120℉.

1530: Took fish off the smoker. It was actually at between 150℉ and 165℉, so definitely hotter than I intended… I should check at less than an hour next time.

The fish tastes great, right now, despite the temperature going too high. Time will tell if it lasts in the freezer and fridge as well as cooler fish. Visually, it looks more cooked, with some of the edges being quite dark, compared to usual. Still, tastes great, and is as most as I’m used to. My guess is, this extra temperature didn’t harm the fish at all.

Trying Out Beef Jerky

My brother-in-law gave me a taste of some of his homemade beef jerky a couple weekends ago, and it was fantastic! Apparently it was also easy to make. Easy, delicious, I’m gonna try it! He used a dehydrator, but I plan to use a smoker to keep my wife’s dehydrator from getting strong flavors stuck in it.

Jason’s Recommended Starting Recipe

I got a 2.5 lbs bottom round steak, sliced it thin, then started it in the marinade below at 2130. I plan to marinade for over 12 hours, then smoke the slices at 175℉ for 4 hours or so.

1 1/3 cup Worcestershire sauce
1 tsp paprika
1 tsp black pepper
2 tsp cayenne pepper
1 tsp garlic powder
1 tsp onion powder

I intended to use 1 Tbsp of paprika as in the recipe, and purposely left out the brown sugar for the first time.

1450: I dried the meat slices on paper towel, then put it on the smoker. The smoke holes are fully open to increase air flow and aid drying (not sure if this will really make a difference), the water pan is not even in the smoker, and the wood is hickory.

I’ll keep hickory in there for the first two hours, at least, then I suspect the meat will be as smoky as it can get. After that, I’m using the smoker like a low temperature oven.

That’s really why this method should be comprable to the recipe’s oven method. This is an electric smoker, and it can maintain temperatures up to 275℉, so 175℉ will not be a problem. Plus, the exhaust goes directly outside, so the house doesn’t smell like Worcestershire sauce for a week.

The meat took up all the smoker rack space except half of the bottom one. I’m pretty happy with how thin I got it.

1900: jerky is done! Final weight is only 11 oz! It is down to 27% of original weight.

I’ll freeze half.

The result should cost $1.59 per ounce, just in meat cost, since the original meat was $7 per pound. Normally jerky is $2.50 per ounce. While $1 per ounce is a good mark-up (and of course they aren’t buying their meat from the supermarket), it’s not preposterous. Meat seriously shrinks from water loss.

Changes for next time – maybe more flavorful if possible. Less spicy for sure (this is probably too spicy for Sarah). More spices though, and maybe a little salt. Same thickness cut I think – as thin as I could get it with the knife while being consistent.

Writing About Writing Secure Shell Scripts

I recently read this cautionary tale about shell scripts. https://www.linuxjournal.com/content/writing-secure-shell-scripts

It’s cautionary in two ways: it is intended to cause shell programmers caution, and I caution against you taking the article too seriously.

One of the biggest threats to the shell in memory was the Shellshock vulnerability. This wasn’t typically a direct threat to shell scripts, but one caused by a bug in a shell, and by other programs exposing parts of the shell to external input, often in unexpected and unlikely places.

That kind of topic is not what the Linux Journal article is about.

Instead, it provides three cautions to people writing shell scripts:

  • Know the utilities you invoke: fully specify program paths so you don’t accidentally run something out of /tmp
  • Don’t store passwords in scripts: find your own other solution, good luck sucker!
  • Beware of invoking anything the user inputs: with examples that work on no modern Linux

These are all fine recommendations, but are made in terrible ways.

Know the Utilities You Invoke

The author provides an example where a user drops a malicious “ls” script in /tmp, then scripts execute it because they do not completely specify the path of ls. The author’s recommendation is to completely specify all paths. The problems with this are two-fold…

First, to execute a program in a directory that isn’t in your path, you must specify the path of that program. If it’s your current directory, that’s just a “./”, but it still must be present. If you have “.” in your path, as the article suggests, then you have made a configuration error that can easily cause you unexpected behavior at best, and the precise security vulnerability mentioned in the article at worst.

The correct remediation for this issue is to not put “.” in your path.

The second problem with the article’s recommendation is that many programs are not in a set location on the system, and some even move around over time (decades). Many claim that the “/bin”, “/usr/bin”, “/usr/local/bin” system is set, sensible, and regular. This is not the case in practice. Usage varies between distros, and even between versions of distros. A system update can move the location of a program in the worst case. This isn’t a problem if the new location is in your path, you’ll still execute the right thing. Unless you fully specified the old location in all your scripts.

This isn’t to say that you can’t usually specify the full location. And specifying the full path might provide a greater security guarantee. However, the author’s recommendation has some practical downsides, and anyway don’t put “.” in your path!

The great /usr merge makes fully specifying paths more practical.

Don’t Store Passwords in Scripts

This is 100% correct. Anyone with read access to your scripts or your git repo or your backups can pull those passwords right out. The problem with this section of the article is that it doesn’t provide any practical solutions. Anybody that has been doing shell scripting for a time will have run into the password problem, and lots of us have just crammed the password in the script or in a readable file at some point.

There are other better solutions!

First though, another wrong way to do it: specifying passwords on the command line or in environment variables. Don’t do this either! It often seems a better solution than dropping it in the code, but both solutions still expose passwords in many ways.

If your need is for SSH (or related) authentication, consider requiring the script user to type in the password. The password is a way to ensure the user actually has permission to use the resource you’re automating access to.

Often, scripts need to run without user interaction though, so entering a password is not feasible in those cases.

Then you need to limit the damage someone malicious can do if they gain access to the target system. Consider setting up a specific user on the target system that has permissions limited to only what is required for the automated actions. Setup key-based access to that target account, don’t specify a key file password, and don’t provide the target account an actual system password. Place the key file in a location only accessible to the users that should be able to execute the script (maybe you need a custom user or group here, too) and give the file only the minimum required permissions. Now, in your script, invoke SSH, or SCP, etc. with that key file specified.

Using SSH-Agent is probably an even better solution: https://www.akadia.com/services/ssh_agent.html

What if it’s not SSH that you’re sending a password to, what if it’s sudo? I think we’ve all wanted to do this at some point, I confess that I have.

Don’t do it though!

Change your sudo configuration so that for the specific command you need a specific user to run, it doesn’t require a password! Then lock access to that user down some. Even in this case, you’re probably causing problems you don’t expect. Imagine if the target executable has a vulnerability… Now you’re opening the aperture for privilege escalation. A better solution is to change permissions to allow specific users access to the specific resources required, then reduce others’ access to those user accounts.

What if you need to script password sending to telnet or ftp? I don’t have great solutions at hand for you. At some point you may need to put passwords and usernames in files, then limit access to those files, and have your script grab the file contents.

Beware of Invoking Anything the User Inputs

The author suggests that a specific setup and command line can cause, “quite dire consequences.” Try this command for yourself though, after changing the “rm” command to something benign like a version of “ls”.

You didn’t get the output the author suggested you might? That’s because this isn’t really a problem the way he states it.

Oh, the author’s “eval” version might work, but when have you ever written code like that? Please say you haven’t.

It’s definitely possible to accidentally provide ways for users to cause command injection – it’s a very common class of vulnerabilities. Scrubbing the input, as the article author suggests, is a common solution.

One recommendation the author should have made more clear is that when scrubbing input you should permit only data that fits a minimalist whitelist. Don’t try to look for bad characters, like you would with a blacklist… Instead, fail on any characters that aren’t in your specific small set.

More often though, the use case for shell scripts is in accepting input from users already on your system. In this case, the recommendations in the article are lacking.

My main recommendation is to avoid permitting users to run anything as a higher level user, or as a different user at all. If users can only execute scripts as themselves, and the script doesn’t grab extra permissions like via SSH, any commands the user might try to get the script to run would also run with the user’s permissions. Therefore, it’s a thing they could’ve done themselves.

If there are shared resources the script needs that the user shouldn’t normally have, perhaps use sudo within the script to grab/use those resources then drop permissions (as would happen if a separate program did the permissioned work, then ended). Alternatively, create another user with only minimal permissions, including those shared resources, then have the script run as that user.

If the script does have to get extra permissions, like through SSH, avoid sending user input there, or sanitize it with a whitelist (worst case). When I say SSH provides extra permissions, I mean that it does so by providing access to another computer, and potentially another user.

You should try to avoid writing code that eval’s user input, or potentially places it on the command line as multiple arguments, and you should try to sanitize input when you have to take a risk… But the best solution is to design the environment so that even when you inevitably mess up it’s not that big a deal.

Conclusion

Good points Dave, but the recommendations are lacking.

The Apple article he links has better recommendations, and solid examples. It points out that older Bash versions were vulnerable to one of Dave’s examples that I poo-pooed. However, there are many problems with running older Bash versions (you wondered why I mentioned Shellshock?)… Don’t do that anymore. The Apple example also has a great hidden eval command in there – echoing user input to a file then executing the file is essentially eval. Avoid.