Archive for the ‘Uncategorized’ Category

Why I love OpenSource – adding CSV export capability to Mailman

August 17, 2013

So mailman is by far one of the best mailing list management packages available. One thing I love is the command line access, Because of this I can write simple scripts like:

for list in `/usr/lib/mailman/bin/list_lists -b`
do
/usr/lib/mailman/bin/list_admins $list > /root/mailman-export/$i-admins.txt
/usr/lib/mailman/bin/list_owners $list > /root/mailman-export/$i-owners.txt
/usr/lib/mailman/bin/list_members $list > /root/mailman-export/$i-members.txt
done

And get a nice list of all the admins, owners and members for each list hosted on that server. I can then do things like grep for a specific user or domain across all the lists and then put that data into further scripts (e.g. to remove every account from a specific domain from every list). But not everyone wants a big list of text files. I had one administrative user that wants to run some analytics, they wanted a CSV file for every list in the form:

"list name","email address","user name","access level"

so for example:

"announcements","[email protected]","Kurt Seifried","member"

and so on. Now I could take the above bash script and modify it sufficiently to take the output and turn it into a CSV file, but there is probably a more elegant way. If you look at the “/usr/lib/mailman/bin/list_members” script you’ll see it’s pretty simple. In order to add CSV export capability I first copied it to “/usr/lib/mailman/bin/list_members-csv” and then opened it up in an editor.

First we’ll need support for CSV and datetime (so we can timestamp the output), just go to the import statements and add:

import csv
import datetime

Then you’ll want to create a CSV file to write to, I want my files in “/root/list-exports/” in a file name  that has the list name, membership level and date (which is redundant but makes dumping all the outputs into the same dir easy and safe). Simply go into “__main_-” and find the line:

listname = args[0].lower().strip()

Then add something like:

datestring = str(datetime.date.today())
cvsoutputdir = "/root/list-output/"
cvsoutputfilename = cvsoutputdir + listname + "-members-" + datestring + ".csv"
csvoutputfile = open(cvsoutputfilename, "wb")
csvwriter = csv.writer(csvoutputfile, dialect='excel', quoting=csv.QUOTE_ALL)

you now have a file name in the form “listname-members-date.csv”, all the data will always be quoted and the output will be in the format preferred by Excel (so for escaping/etc. it’ll use the characters Excel is expecting). I could have integrated this with the “–output file” command line option,  but then I need logic to handle the datetime and membership level and list name in the wrapper using my modified version of list_members, so it’s easier (for me) to just stick that logic into my modified list_members.

Now you simply look for the lines where the output is actually handled and replace:

print >> fp, formataddr((safe(name), addr))

with:

csvwriter.writerow([listname, addr, safe(name), "member"])

And you’re done.  Now you could get fancy and make it an actual option (–csv?) in the existing program, and add some switch logic for output, but honestly, I couldn’t be bothered, this is simple enough and it works reliably.

 

 

Fedora 16 with SELinux running WordPress with Akismet

June 17, 2013

So you have WordPress and Akismet to get rid of spam. But for some reason Akismet is not working:

WordPress with Akismet failing

You can test if you have a valid key and connectivity from the command line with either wget:

wget --post-data 'key=YOURKEYGOESHERE&blog=http://example.org'\
http://rest.akismet.com/1.1/verify-key

or using curl:

curl -d 'key=YOURKEYGOESHERE' -d 'blog=http://example.org' \
http://rest.akismet.com/1.1/verify-keyd

If it works you should receieve a file called “verify-key” containing the word “valid”

If that doesn’t work then you have problems outside the scope of this article.

But if you can retrieve the key than chances are your SELinux configuration is limiting what the httpd server can do.

Luckily the fix is simple: allow httpd to make outgoing connections:

setsebool -P httpd_can_network_connect on

But wait a minute you say. Now my httpd server can connect to anything, attackers can use it to attack other systems potentially (especially if you allow CGI scripts and arbitrary WordPress plugins or themes which can contain PHP code).

So we need to limit what systems the httpd server can connect to. The good news here is that IPTables supports this.

In the case of Akissmet you’d want to add something like this to your /etc/sysconfig/iptables file:

-A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
-A OUTPUT -m owner --uid-owner apache -m tcp -p tcp --dport 80 \
--dest 66.135.58.61 -j ACCEPT
-A OUTPUT -m owner --uid-owner apache -m tcp -p tcp --dport 80 \
--dest 66.135.58.62 -j ACCEPT 
-A OUTPUT -m owner --uid-owner apache -m tcp -p tcp --dport 80 \
--dest 72.223.69.89 -j ACCEPT
-A OUTPUT -m owner --uid-owner apache -m tcp -p tcp --dport 80 \
--dest 72.223.69.88 -j ACCEPT
-A OUTPUT -m owner --uid-owner apache -j REJECT

This should allow only existing inbound connections (e.g. web clients) and outgoing connections to Akismet (you may want to add any other services you use of course).

Why Domain Specific Knowledge (DSK) is critical to writing good software – an example

May 27, 2013

Software for the police written by someone trained to be a policeman:

http://www.fastcolabs.com/3010085/this-founder-trained-at-the-police-academy-to-build-an-app-for-cops

Look for a genuine problem to be solved, not a way to leverage some technology. Really understand the problem that you seek to solve. For example, we have one of the ugliest UIs in the world, and unless you are a cop it’s very difficult to understand why. On the left hand side is what we call the pedigree: the person’s image and an image of their car model. This is designed to be used on a portable computer in a moving unmarked car, and all we want to give you is the ability to see that person on the street or the car in the driveway. Some of this information looks redundant but it isn’t, e.g., age and date of birth. The age is so I know how old the person who I am going to encounter is. The date of birth is to confirm her identity once I see her. The area on the right changes. It shows home address and home street view when you are still driving. We require almost no keystrokes. Cops hate typing, and they are in a car so they are not allowed to type while they drive. Everything is one click away except when you are parked. We are anticipating the workflow in the order in which we believe a cop will do it but we don’t require them to follow our workflow order.

I would have put a pic of the front of the car (wrong) and just the DOB (making the cop do more work to mentally figure out the age). Good thing I don’t write software for the police.

VMware update insecurity

April 16, 2013

So the good news is VMware has a built in updater, and even better the server it uses to query for information is SSL/TLS enabled. The bad news is they are using Akamai with an insecure configuration: vmware-update-overall-grade A quick note: Akamai is a huge content delivery network (CDN) used by many vendors to deliver content and software updates to end customers. Some pretty insecure configurations of SSL and TLS are supported by Akamai for the simple fact that there is still a lot of old software/clients out there, which Akamai’s customers want to support. As you can see here if you query https://www.ssllabs.com/ssltest/analyze.html?d=softwareupdate.vmware.com they use an Akamai certificate: vmware-update-akamai Nothing wrong so far, but when you look at the versions of the SSL protocol that are supported they have left SSL 2.0 enabled, and they have also left weak ciphers including several 40 bit ones enabled: vmware-update-weak-ciphers This makes an SSL downgrade attack trivial for an attacker as 40 bit keys can be broken in near real time now with even a remotely powerful computer that has a GPU.  Using this an attacker can man in the middle your upgrade session and tell the client no updates are available (forcing you to remain on an older version with security issues), or potentially send you a malicious update. I haven’t looked at the guts of the VMware updater, for all I know they may use additional protections like secure signing of the update software itself, but let’s hope they do, because the communication channels it is sent over are not very secure. The good news is that fixing this is easy, VMware just needs to make sure their updater software supports TLS and secure ciphers (which if they’re using an even moderately up to date library won’t be a problem), and they need to update their Akamai configuration to exclude SSL 2.0 and the weak ciphers.

New techniques in spam from the Harvard Business Review (HBR)

March 1, 2013

No this isn’t about an article in the Harvard Business Review (HBR), this is actually about spam from the Harvard Business Review. A long time ago I signed up for a year since I got one of those “get the magazine for $19.95 a year” offers and figured why not. I then cancelled at the end since I didn’t find the magazine terribly interesting or forward looking (it seems to mostly reflect an entrenched view of business/law that while useful for existing managers is not terribly education, unlike say the Economist which I still read).

So what’s this new spam technique from the Harvard Business Review? Well they sent me an email, informing me that I had not completed an order at their online store and that my shopping cart still had items in it. This is a pretty clever social engineering technique, they’re prompting you and leading you to believe that you had meant to renew your Harvard Business Review subscription and obviously got distracted or something so you might want to finish the process and send them some money. Except I hadn’t been shopping on their web site (my subscription lapsed a few years ago).

Harvard-Business-Review-Spam-Email

So I went to unsubscribe (who knows, they might actually stop emailing me), but that part of the process was also engineered to make it difficult, first step: make the person enter their email address rather then filling the form (and they know the email address, I mean they just spammed me):

Harvard-Business-Review-Spam-Email-Unsubscribe

But then the piece de resistance:

Harvard-Business-Review-Spam-Email-Unsubscribe-10-Days

Up to 10 days to remove you from a mailing list. What. The. Fuck? So yeah, the moral of the story is use the “spam” button in your mail client and deep six all the crap Harvard Business Review is going to try sending you.

Circuit and Logic Simulators

September 27, 2012

These look like fun

I wonder if there any good ones for the iPad.

How not to post log information, or why I shred every piece of paper I touch

July 4, 2012

So this thread just came to my attention: http://comments.gmane.org/gmane.mail.postfix.user/227441

I use postfix2.5.5 rpm to run postfix as relay server
since from last many day my application team of SAP software started complaining for the smtp email failuer
pls find the below longs
++++++++++++++++++++++++++++++++++++++++++++

Email 1

Feb  6 10:41:22 D1SNX682RL postfix/smtpd[3693]: connect from unknown[155.14.132.36]
Feb  6 10:41:23 D1SNX682RL postfix/smtpd[3693]: 20C453E00C0: client=unknown[155.14.132.36]
Feb  6 10:41:23 D1SNX682RL postfix/cleanup[10313]: 20C453E00C0: warning: header Subject: RE: RE: RE: RE: RE:// FOLLOW UP // HBL SCREENSHOT //  FINAL SI & HBL // E.R FREMANTLE 087 // HIBLOW from unknown[155.14.132.36]; from=<MANILA_DOCS <at> APL.COM> to=<crm_email_archive_apl <at> apl.com> proto=ESMTP helo=<nol.com.sg>
Feb  6 10:41:23 D1SNX682RL postfix/cleanup[10313]: 20C453E00C0: message-id=<ADR37000000104995 <at> nol.com.sg>
Feb  6 10:44:27 D1SNX682RL postfix/smtpd[3693]: lost connection after DATA (437492 bytes) from unknown[155.14.132.36]
Feb  6 10:44:27 D1SNX682RL postfix/smtpd[3693]: disconnect from unknown[155.14.132.36]

Followed by:

please at least remove from this site , there is security audit going on in my organisation i dont want to maintain this thread , please remove this .

Whoops. You may have noticed in my previous posting “Fedora 16 and Red Hat on EC2 with Sendmail using SMART_HOST with authentication” I took the time to sanitize all the IPs and hostnames presented in the examples. It was a bit of a chorse (running search and replace is simple, but reading the results three times to ensure nothing was missed is tedious), but it’s worth it. Would the information aid an attacker? A little bit. There are other ways to find this out as well (error messages from servers, etc.).

But the reason I do it is simple: if you ALWAYS sanitize information then you won’t run into a situation where you decided not to sanitize the information and later turned out to be wrong. This is exactly why I shred every single piece of paper I touch before throwing it out. Do I need to shred the envelopes my bills come in? They have no personal information/etc., they could conceivably be used to determine which banks/companies I deal with, and how much I deal with them, but I’m not overly worried about that (anyone taking the time to go through all my trash can find this out other ways). No the reason I shred everything, including envelopes is so that I never have to worry about throwing something away sensitive. Also I don’t have to spend any time/effort deciding if something needs shredding or not, it all automatically goes into a pile, and when I’m bored I feed the shredder (I actually find it oddly fun…).

Making Fedora 17 + Gnome 3 work – you can’t, it’s completely broken

June 1, 2012

Update (June 6, 2012): Gnome 3 is actually a LOT more broken than I previously thought. I have since found more problems that basically make it near impossible to configure sanely, if at all.

So to put it bluntly the Gnome 3 changes suck if you use more than one application at a time and especially if you use more than one monitor as well. Having to move the mouse over to the top left constantly to show windows/applications so you can bring another window to the front or launch an application. I typically have 5-10 (sometimes 20) xterms open (most SSH’ed in to remote hosts), at least two web browser (Firefox and Chrome, more if I have a lot of tabs open so I can actually read the titles on the tabs, a not uncommon occurrence), my mail client, and my IRC client at a bare minimum.

In other words the Fedora 17 + Gnome 3 defaults completely suck for me (and I suspect many others).

Step 1) getting my minimize and maximize buttons back:

You’ll need the UI tweak tool:

yum install gnome-tweak-tool

and then run it and go to “Shell” and then pick the “Arrangement of buttons on the titlebar” and select “All”:

which will put them on the right hand side ala Windows / Gnome 2

Step 2) getting a taskbar

I like the taskbar, most of us have been using the taskbar since Win95, and in my case since OS/2 (yeah, that was an interesting dead end OS), and most versions of Linux copied it early on because, well, it works quite well.

yum install tint2

and then have it autostart, run the gnome-session-properties program:

gnome-session-properties

and add it in:

Step 3) A dock bar for launching programs

Being able to launch applications quickly is kind of useful. A dock bar with icons is about as good as it gets.

yum install gnome-shell-extension-dock.noarch

and then .. I’m not sure, I logged out and back in and Gnome failed to load. Removing the dock extension appears to have addressed it. sigh. The good news is that Fedora 16 will be supported for another 6 months.

Added June 6, 2012:

Step 4) Customizing icon launch properties

So I also need some of my icons to have customized command line options. Usually this is easy, you right click, and change the properties of the icon such as the “command” or “execute” line. For example if you want to launch the Google Chrome web browser with Kerberos 5 support you need something like:

google-chrome --auth-server-whitelist="*.example.com"

So doing this should be easy right, simply choose icon properties… hrmm.. that isn’t available. Just “New Window” and “Add to favorites”. Ok, maybe there is an application to do this, aha, “alacarte” which is “a graphical menu editor that lets you edit, add, and delete menu entries.” This should be perfect, just install it:

yum install alacarte

and run it. Nope, it’s broken “ImportError: No module named gmenu”. Now Debian has a package called “python-gmenu” which is “an implementation of the freedesktop menu specification for GNOME”, but there doesn’t appear to be such a package for Fedora.

Worse, the alacarte program has been broken, since August of 2011: https://bugzilla.redhat.com/show_bug.cgi?id=734442 so I wouldn’t exactly hold my breath.

So if you want to customize an icon to include command line options you’ll need to copy the icon file data into your home directory and edit it by hand, this is best described at http://superuser.com/questions/304271/commandline-options-in-gnome-3-launchers and the short version is:

copy the file from /usr/share/applications/ to ~/.local/share/applications/ and modify the “Exec=” line.

Fedora 16 and Red Hat on EC2 with Sendmail using SMART_HOST with authentication

May 14, 2012

So I have a bunch of servers hosted on Amazon EC2 running Red Hat Linux / Fedora. Most of them are web front ends, so they need to be able to send email (alerts, status reports, etc.) but I don’t want to have to request that the email limit be increased on each server (as they come up and down a lot as demand requires).

So my obvious thought was to run an EC2 instance that would act as an email relay for all these servers. Easy enough, install a host with Sendmail, and allowing relaying. The trick here is that I don’t want to have to edit the access file every time a new host comes up or leaves as the level of IP address churn is quite high. So we enable email authentication, and pre-load EC2 images with the credentials to relay email through the server and we’re done.

So, foolishly, I thought I’d skip SMTP, and go straight to TLS encrypted SMTP (port 465), and require authentication. This way all the communications, email, authentication credentials and so on are well protected.I setup the Sendmail server, and tested it using Thunderbird, TLS+auth worked perfectly. However on the Sendmail client server side it did not work well, in fact I was unable to get it working at all, so if anyone knows how I’d love to hear from you.

Setting up the Sendmail Server with encryption and authentication

You’ll need to install sendmail and sasl:

yum install sendmail-cf cyrus-sasl-plain cyrus-sasl-md5 
cyrus-sasl-gssapi cyrus-sasl-lib cyrus-sasl-devel cyrus-sasl

and enable / start it:

systemctl enable saslauthd.service
systemctl enable sendmail.service
systemctl start saslauthd.service
systemctl start sendmail.service

Then you’ll need to edit /etc/mail/sendmail.mc, make sure these two lines are not commented out (they are by default):

TRUST_AUTH_MECH(`EXTERNAL DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl
define(`confAUTH_MECHANISMS', `EXTERNAL GSSAPI DIGEST-MD5 CRAM-MD5 LOGIN PLAIN')dnl

and then enable submission:

DAEMON_OPTIONS(`Port=submission, Name=MSA, M=Ea')dnl

Then you’ll need to enable encryption certificates:

define(`confCACERT_PATH', `/etc/pki/tls/certs')dnl
define(`confCACERT', `/etc/pki/tls/certs/CA_bundle.pem')dnl
define(`confSERVER_CERT', `/etc/pki/tls/certs/server.crt')dnl
define(`confSERVER_KEY', `/etc/pki/tls/private/server.key')dnl

and you’re basically done. Simply rebuild the sendmail configuration and restart it:

/etc/mail/make
systemctl restart sendmail.service

You’ll then need to ensure port 587 is not firewalled (either on the local system or in your EC2 security groups), and you’ll have to create local accounts with passwords so the clients can authenticate against them (e.g. create a user called “mail-relay” with a password and lock the account down).

You can easily test the server using an email client such as Thunderbird.

Setting up the Sendmail Client Server with encryption and authentication

First you’re going to need Sendmail and the syrus-sasl-plain rpms installed. The really annoying part is if you don’t install the cyrus-sasl-plain package email connections will fail, but the log files are less than helpful when this occurs:

May 20 23:22:48 ip-10-242-49-173 sendmail[9890]: q4L3MmFP009890: 
client.example.org [10.1.2.3] (may be forged) did not issue 
MAIL/EXPN/VRFY/ETRN during connection to MSA

To install the rpms simply:

yum install sendmail-cf cyrus-sasl-plain

So now to setup the client. This is woefully documented and there is a ton of conflicting information. To start with install the same sendmail and sasl packages as above. Then you’ll need a standard SMART_HOST entry line, but with the added options of telling it to use port 587 (submission) and a link to the file with the authentication information:

define(`SMART_HOST', `smarthost.example.org')dnl
define(`RELAY_MAILER_ARGS', `TCP $h 587')
define(`ESMTP_MAILER_ARGS', `TCP $h 587')
FEATURE(`authinfo',`Hash -o /etc/mail/authinfo.db')dnl

You’ll also need to create an /etc/mail/authinfo file with contents such as:

AuthInfo:smarthost.example.org "U:user_name" "P:password_here" "M:PLAIN"

and build it using the makemap program:

makemap hash /etc/mail/authinfo < /etc/mail/authinfo

You can then restart sendmail and it should work, the log file from the client sendmail server:

May 14 02:51:01 ip-10-10-10-10 sendmail[3188]: q4E6p1aq005188: from=ec2-user, 
size=297,, nrcpts=1, msgid=<[email protected]>, 
[email protected]

May 14 02:51:01 ip-10-10-10-10 sendmail[3189]: q4E6p12W003189: 
from=<[email protected]>, size=577,, nrcpts=1, 
msgid=<[email protected]>, 
proto=ESMTP, daemon=MTA, relay=localhost.localdomain [127.0.0.1]

May 14 02:51:01 ip-10-10-10-10 sendmail[3188]: q4E6p1aq003188: 
[email protected], ctladdr=ec2-user (1000/1000), delay=00:00:00, 
xdelay=00:00:00, mailer=relay, pri=30297, relay=[127.0.0.1] [127.0.0.1], 
dsn=2.0.0, stat=Sent (q4E6p12W003189 Message accepted for delivery)

May 14 02:51:01 ip-10-10-10-10 sendmail[3191]: STARTTLS=client, 
relay=smarthost.example.org., version=TLSv1/SSLv3, verify=FAIL, 
cipher=DHE-RSA-AES256-SHA, bits=256/256

May 14 02:51:02 ip-10-10-10-10 sendmail[3191]: q4E6p52W003189: 
to=<[email protected]>, ctladdr=<[email protected]> 
(1000/1000), delay=00:00:01, xdelay=00:00:01, mailer=relay, pri=120577, 
relay=smarthost.example.org. [1.2.3.4], dsn=2.0.0, stat=Sent 
(q4E6p1ZE001355 Message accepted for delivery)

And on the server:

May 14 02:49:48 ip-1-2-3-4 sendmail[1349]: STARTTLS=server, 
relay=ec2-1-2-3-4.compute-1.amazonaws.com [1.2.3.4] (may be forged), 
version=TLSv1/SSLv3, verify=NO, cipher=DHE-RSA-AES256-SHA, bits=256/256

May 14 02:49:48 ip-1-2-3-4 sendmail[1349]: AUTH=server, 
relay=ec2-1-2-3-4.compute-1.amazonaws.com [1.2.3.4] (may be forged), 
authid=email-client, mech=PLAIN, bits=0

May 14 02:49:48 ip-1-2-3-4 sendmail[1349]: q4E6nmgg001349: 
from=<[email protected]>, size=795,, nrcpts=1, 
msgid=<[email protected]>, 
proto=ESMTP, daemon=MSA, relay=ec2-1-2-3-4.compute-1.amazonaws.com 
[1.2.3.4] (may be forged)

May 14 02:49:49 ip-1-2-3-4 sendmail[1354]: STARTTLS=client, 
relay=aspmx.l.google.com., version=TLSv1/SSLv3, verify=FAIL, 
cipher=RC4-SHA, bits=128/128

May 14 02:49:49 ip-1-2-3-4 sendmail[1354]: q4E6nmgg001349: 
to=<[email protected]>, delay=00:00:01, xdelay=00:00:01, mailer=esmtp, 
pri=120795, relay=aspmx.l.google.com. [173.194.68.26], dsn=2.0.0, 
stat=Sent (OK 1336912345 gs11si19555555aaa.999)

As you can see the email comes in, and is then handed off to gmail.

Creating temporary files securely

March 14, 2012

Creating temporary files  is a common use case in virtually every program. Virtually every programming language has a simple and secure way to create temporary files. Sadly many programmers fail to use them, creating security vulnerabilities in their applications. So in alphabetical order here is a list of programming languages and how to create a temporary file securely. If I’m wrong, please let me know. Note: when searching for a secure temporary file creation function/method/etc. looking for “mkstemp” is a quick way to find most of them. Please note a lot of sites (e.g. http://rosettacode.org/wiki/Secure_temporary_file) contain old/wrong information.

O_CREAT and O_EXCL (and similar)

When opening a temporary file in C you MUST use O_CREAT and O_EXCL together to ensure that the file is only created if the file does not exist. Otherwise between the time you check for the existence of a file and the time you create the file an attacker may be able to create a file with the same name. The good news here is that virtually every secure temporary file creation function/library does this or an equivalent option. To quote mkstemp():

The mkstemp() function shall replace the contents of the string pointed to by template by a unique filename, and return a file descriptor for the file open for reading and writing. The function thus prevents any possible race condition between testing whether the file exists and opening it for use.

Why “unique” names are not enough, but are generally not a huge problem

People often think that creating a file with a “unique” name in /tmp (e.g. “/tmp/myprogram-output.log”) is sufficient to safely create a temporary file. However if you create the file with a known or easily guessed name (e.g. a static name set in the source code or a config file) an attacker can create the file first and then your application will be unable to, creating a denial of service condition potentially.

However the names don’t have to be terribly unique. For example if you use mkstemp() with 10 random characters (the default) gives on the order of 839,299,365,868,340,224 possible file names. Any attacker able to create enough files to force a collision of the name would be able to fill up the /tmp directory in any event (unless you have an absurdly large /tmp directory that is several exabytes in size, which won’t be a problem for some time).

Unexpected temporary files

It should also be noted that many programs create temporary files. Text editors and other file editors may create temporary file saves in /tmp or /var/tmp and so on.

The problem with $TMP, $TEMP, $TMPDIR, $TEMPDIR and so on

One note: if you’re going to use environmental variables you’d better make sure you sanitize them and ensure they aren’t overly long. User controlled environmental variables are just that, user controlled. I can’t find a good set of libraries or code to sanitize these variables before use, if anyone knows of such a thing please contact me ([email protected]).

Better list for lots of other languages:

Please see http://rosettacode.org/wiki/Secure_temporary_file

Bash

Simply use “mktemp” (“man mktemp” for details). Use “-d” or “–directory” for creating directories.

C

use mkstemp() (“man mkstemp” for details) for files

use mkdtemp() (“man mkdtemp” for details) for directories

tmpfile() is another option – Creates a temporary binary file, open for update (wb+ mode — see fopen for details). The filename is guaranteed to be different from any other existing file.

C++

use mkstemp() (“man mkstemp” for details)

use mkdtemp() (“man mkdtemp” for details) for directories

tmpfile() is another option – Creates a temporary binary file, open for update (wb+ mode — see fopen for details). The filename is guaranteed to be different from any other existing file.

On Windows use GetTempPath() and GetTempFileName () (same names in C#)

C#

Path.GetTempFileName() http://msdn.microsoft.com/en-us/library/system.io.path.gettempfilename(v=vs.80).aspx

Cocoa

http://stackoverflow.com/questions/215820/how-do-i-create-a-temporary-file-with-cocoa

Google Go (golang)

So ioutil.TempDir and ioutil.TempFile automatically appends a uint32 and has default permissions of 0600. Well done.

http://golang.org/pkg/io/ioutil/#TempDir

Use this and you’re safe. Just a note: io.TempDir returns the value of the temporary directly (e.g. /tmp).

Java

use java.io.File.createTempFile() – some interesting info at http://www.veracode.com/blog/2009/01/how-boring-flaws-become-interesting/

for directories there is a helpful posting at http://stackoverflow.com/questions/617414/create-a-temporary-directory-in-java

Java 7

for files use java.io.File.createTempFile()

for directories use createTempDirectory()

http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html

Lisp

http://stackoverflow.com/questions/1384972/common-lisp-function-or-idiom-for-creating-a-temporary-file-name

nodejs

http://stackoverflow.com/questions/7055061/nodejs-temporary-file-name

Perl

use mkstemp()

http://perldoc.perl.org/File/Temp.html#MKTEMP-FUNCTIONS

Python

Simply use “mkstemp” for files and “mkdtemp” for directories from the “tempfile” module:

http://docs.python.org/library/tempfile.html#tempfile.mkstemp

QT

use QTemporaryFile for files:

http://qt-project.org/doc/qt-4.8/qtemporaryfile.html

use  for QTemporaryDir directories:

http://qt-project.org/doc/qt-5.0/qtemporarydir.html

Ruby

use Tempfile for files:

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/tempfile/rdoc/Tempfile.html#method-c-new

use tmpdir for directories (require ‘tmpdir’ and then you can “Dir.mktmpdir”):

http://www.ruby-doc.org/stdlib-1.9.3/libdoc/tmpdir/rdoc/index.html

Making per user /tmp directories

Using PAM you can also make per user /tmp directories using polyinstantiation http://www.ibm.com/developerworks/linux/library/l-polyinstantiation/

If you have a system with many users (e.g. a shell server or web host) this is a great way to avoid the whole /tmp mess at the system level rather than trying to ensure your applications are properly written.

Monitoring /tmp for activity

So how can we be sure our changes work and temporary directories and files are being created safely? Conversely how can we monitor /tmp to watch for programs that use /tmp improperly or in unsafe ways? Linux has an inotify subsystem that allows you to monitor a file(s) or directory(s) (including recursively) for file and directory related activity (creation, deletion, modification, etc.). The downside of inotify is that, as far as I can tell, there is no way to list which process was responsible (so if you have a large application and multiple applications running it may be difficult to track down which one specifically created the file/etc.

To use inotify use either the “inotify-tools” or “pyinotify” programs, I prefer pynitofy, the output is really easy to read:

# /usr/bin/pyinotify /tmp/
<Event dir=True mask=0x40000100 maskname=IN_CREATE|IN_ISDIR \
name=foo.ooCHP2tb1adt path=/tmp pathname=/tmp/foo.ooCHP2tb1adt wd=1 >

You can also use SELinux, running permissive mode simply disable all access to /tmp and then run your application(s). The log files will show any accesses of /tmp including the process information.

Auditing for /tmp file vulnerabilities

It’s not hard, mostly I just do:

find ./ -type f -exec grep /tmp {} +

and if they wrote the code using the above techniques it is probably safe, if it is written any other way it’s probably wrong.

Which directory should you use?

You should be using /var/run/something/ or /run/something/ that is setup in advance and secured for the users/groups that require it.