Monday, 30 June 2014

10 Tips to those applying for translation jobs

Running a small translation office I am bombarded with requests from would be translators looking for work. It is perhaps a sad reflection of the times that I get ten times as many such requests as I have jobs coming in, and often these people find me  through advertising channels which I end up having  to pay for (e.g. Google AdWords, linkedIn etc.).
So here i have compiled a list of tips for those applying for work based on my experience looking at such prospective applications.
1: Make sure the application is in good English. You are a translator offering language services, and even if  English is not your mother tongue, it tends to leave a bad impression if it has errors strewn all over it. Also take care of punctuation and presentation, part of your work involves presenting a document in an acceptable format and if you get this wrong.....well...
2. Don’t make overhyped and overambitious claims. Nobody is perfect, I certainly am not, and when I looked at one translator who claimed to offer “perfection” it was hilarious to see how many errors he made in his pitch letter. Bidirectional translators do exist but my experience is that people are best at translating into their mother tongue. So even if  you are bidirectional, I would play this down at first. And don’t try to claim you can take any amount of work on at any notice, this is also completely unrealistic and leads to mistrust from the off.       
3: Don’t forget to mention your language combination, preferably in the subject of the email. . This is THE most important information when filing applications, and you would be amazed at how invisible this information is in many translator’s applications.   
4: Differentiate yourself. Don’t try and say you do everything under the sun at a low price in the hope of catching as much work as possible. I want to be safe with someone who I hire and I would rather have someone who knows a lot about comparatively little. Once you establish a working relationship you might be asked to go beyond those limits and do other work, but offer yourself as a specialist first.
5: Don’t send paper CVs in. It takes time (and therefore money) to file this information, and if a company has a mask on a website for entering your details into a database, use it. You will be more respected for it too. If you have to send an electronic  CV in, make sure its easy to copy and paste information from it. Don’t send references or certificates unless asked.  
6: Be straight to the point. There are a lot of people looking for work. The information people need is what is your language combination? what is your specialty? What is your education and experience background? What translation tools do you use? And How much do you cost? Remember, no claims of unerring reliability or total perfection which merely distract and annoy whoever is trying to assess your application.
7: Tell the office how you heard of them. This is very well respected because it provides information about what marketing measures used by the translation company are successful. If you got to the company’s website by clicking on a Google ad, you already cost that company advertising costs, so a little feedback in the way of information helps to soothe those pains. As I said, ten times as many people click on those ads looking for work rather than looking for a service, so the costs do mount up.
8: Don’t expect an immediate response. Many applications are filed away for a rainy day...i.e. when someone looks for work to be done in a certain language combination. Sometimes people will only get back to you after years.   
9: Try to remember that when you are a freelancer, the company you apply to will see you as a service provider, even if you do not see yourself that way. You have to pitch yourself to people that way. You won’t be seeing people 8 hours a day, so a CV need not include information about clubs, organisations and activities. Stick to the information that is important. You are expected to be reliable, punctual  and offer material of sufficient quality (95-98% and not 100% perfection), so there really is no point even mentioning whether you have any of these qualities.

Dr. Julian P. Keogh

Script for detecting malicious injected script in joomla databases

Many malicious individuals exploit loopholes in forms on your website to try to gain  control of your website, using it as a zombie to send out spam mails, or for other malevolant purposes.

Such scripts are often stored and hidden deep in your Joomla database, but the problem is finding them, which can take a great deal of time. Once you have found them, you can gain valuable information about any vulnerabilities you might have on your website and correct your website accordingly.

The problem is, there dont seem to be that many (free) facilities out there for scanning your website database, so I thought i'd write a very simple script to do just this. Please note, you also need to have the Jumi application installed for it to work properly (though with some modifications you might be able to run it as a standalone PHP script).

Instructions are,

  1. Open up the Jumi component
  2. Create new application
  3. Copy code below into the code window  
  4. Save application 
  5. Add the application to one of your menus (assigning it as only executable by admin if necessary) 
  6. Run the application from the front end by clicking on the menu point
 The program is extremely basic, and will only provide the record number in the database, providing that the first column of the table being scanned contains a unique numeric identifier for the record (most, but not all do).

Depending on interest, I may try to improve it, perhaps with hyperlinks from the record numbers to display a javascript popup containing the questionable code, but for now, this shall do.  

In any case, it should help you detect if you have any hidden problems on your website. You can also use it to run general string searches on your webiste, if for example, you need to globally change any phone numbers etc.

Here is the code


/* A short script for detecting site injections, or generally searching for specific strings, in your entire database. If you have Jumi for Joomla, simply create a new Jumi application from the Jumi Component, paste this code into the code window, save it, and assign this application to a menu so you can run it from the front end of your site.
this is a very basic script slapped up in a couple of hours, and is ony intended to help those who may be looking fior problems in their database. I make no guarantees, and users use it at their own risk.     
Copyright 2014 Dr. Julian P. Keogh

//The search form

echo '
<H3>Injected code detector:</H3>
<form name="variable" action="" method="post">
Use this form to sniff out nasty script injections in your joomla database. Search for terms such as php, script or eval which are often used by miscreants to create general havoc on your website. 
This script searches each field of each table for the string, and then returns the first column value if a match is found (usually, but not always the record number in your database).   
Enter the string to search for below:
<input type="text" name="varname" SIZE="40" MAXLENGTH="40" value=""><br>
<input type="submit" NAME="findstring" VALUE="Search for string">

//Once the form is submitted, the page reloads executing the script below
if(isset($_POST["findstring"])) {

$varname = $_POST["varname"];

echo "Results<br>";
$db2    = &JFactory::getDBO();
$tables = $db2->getTableList();

//script below scans each table for columns
foreach($tables as $table)
      $db3    = &JFactory::getDBO();

      $showcolumns = "SHOW COLUMNS FROM ".$table."";

      $columns = $db3->loadAssocList();

//script below scans each column row for dodgy text
      foreach($columns as $column)
              if (is_array($column)) {
              foreach ($column as $field)
              $db4    = &JFactory::getDBO();
              $showrows = "SELECT * FROM ".$table." WHERE `".$field."` LIKE '%".$varname."%'";
              $rownum = $db4->getNumRows();
              $rows = $db4->loadRowList();
 //if no rows are repoerted containing string, loop breaks, otherwise instances are printed out
              if ($rownum==0) {break 1;}
              else {echo $table." ".$field."<br><font-color='red'>"; foreach ($rows as $row){echo $row[0]." ";}}              
              echo "<p><font-color='black'>";
              break 1;}





Thursday, 15 May 2014

Disinfecting my website of a hacked spamming application

Many of you ay have had the unpleasant experience of your server administrator disabling your mail function, because some unscrupulous hacker has broken into your website to use it as a spamming zombie. 

This is a nightmare because very time consuming to route out the cause of the problem, and also to rid your website of all offending files. 

My first step was to check my logfiles using the Weblog Expert Lite tool. Simple enough, you go to the logs folder and download the most recent logfile. Once downloaded, you can then open it with the Weblog tool. 

When you click Analyze, the results appear in your web browser. The first sign there was something wrong  came when I looked at Pages under Access Statistics. 

On the third line I could see a file named index.php hidden deep within the website which had been accessed an inordinate number of times.

Thinking this could be a likely culprit, I downloaded the file via filezilla to look at its contents, and sure enough there was some evil looking code within it...I certainly wont post it, but buried within the php code were randomly alphanumeric variables which were assigned random alphanumeric values, such as $ryv3h7gd = "ajg4ks98" etc., you wouldn't think any normal php file would have a use for this sort of variable assignment.

I deleted the file thinking this would solve the problem, but this was not the case of course. Several months later my mail command was suspended again for more malicious spamming.

It was only now that I decided to go into the problem more deeply. After all, I cant use any of the forms on my website, which can certainly be a frustrating experience for my visitors.


I then started looking for php programmes to scan and disinfect your server space, and much to my disppointment I found that there was very little out there. I downloaded one open source php utility "phpantivirus", but this detected nothing.

I then dug a little further and found this utility by Mike Stowe which scans all the files on your directory for the presence of a simple php command which hackers use, namely the <?php @eval(base64_decode($_GET[q])); ?> command.

This did indeed reveal the presence of a number of files, which upon closer inspection were clearly of a malevolent nature.. here is some example code  of one file 



$auth = 0;





I deliberately obfuscated the random variable above, it was originally about 20 times longer. this file was located within the templates/system directory of my Joomla website, where there were also two other malicious files at that location which used the base64 hack. You can see the purpose of this file however, simply to open up your website to attack.  Needless to say, I deleted those files.

I also found numerous php files and identically named and sized gif files in my /images subdirectory. These also had the eval command, so I deleted these (the gif files were simply renamed php files) 

 Since I realised that, good though Mike Stowes utility is, there were other suspicious files on the computer which didnt have the eval command, I chose to modify the file to look for other features used by malicious spamming files. 

One of these features was that they used the fopen, fwrite and fclose commands, and the other was that they used if(isset($_REQUEST['blahblah'])).

So using the code modified as below

Plugin Name: php Malicious Code Scanner
Plugin URI:
Description: The php Malicious Code Scanner checks all files for one of the most common malicious code attacks, the eval( base64_decode() ) attack...
Version: 1.3 alpha
Author: Michael Stowe
Author URI:
Credits: Based on the idea of Er. Rochak Chauhan (, rewritten for use with a cron job
License: GPL-2

// Set to your email:

############################################ START CLASS

class phpMalCodeScan {

public $infected_files = array();
private $scanned_files = array();

function __construct() {

function scan($dir) {
$this->scanned_files[] = $dir;
$files = scandir($dir);

if(!is_array($files)) {
throw new Exception('Unable to scan directory ' . $dir . '. Please make sure proper permissions have been set.');

foreach($files as $file) {
if(is_file($dir.'/'.$file) && !in_array($dir.'/'.$file,$this->scanned_files)) {
} elseif(is_dir($dir.'/'.$file) && substr($file,0,1) != '.') {

function check($contents,$file)

$this->scanned_files[] = $file;
if(preg_match('/eval\(base64/i',$contents) || preg_match('/eval\($_/i',$contents))
$this->infected_files[] = $file;
echo "EVAL ";
echo $file;
echo "<br>";
echo "Was last modified: " . date ("F d Y H:i:s.", filemtime($file));
echo "<br>";

if(preg_match('/_REQUEST/i',$contents) && preg_match('/fwrite/i',$contents))
$this->infected_files[] = $file;
echo $file;
echo "<br>";

$filecontent = file_get_contents($file);
echo substr_count($filecontent,"_REQUEST");

echo " occurences of REQUEST<br>";
echo "Was last modified: " . date ("F d Y H:i:s.", filemtime($file));
echo "<br>";


function sendalert() {
if(count($this->infected_files) != 0) {
$message = "== MALICIOUS CODE FOUND == \n\n";
$message .= "The following files appear to be infected: \n";
foreach($this->infected_files as $inf) {
$message .= " - $inf \n";
mail(SEND_EMAIL_ALERTS_TO,'Malicious Code Found!',$message,'FROM:');


############################################ INITIATE CLASS

new phpMalCodeScan;
echo "scan complete";

Basically, I uploaded a php file containing this code ("eval64scanner.php") to the root of my domain directory, and ran it by calling in my browser.  

Rather than sending the report to an email address (unless you set up the email address correctly in the script), this just dumps the result to the screen, also providing the date when the file was added or modified. The modification date also provides valuable clues as to whether a file is malicious or not, since they will all tend to have the same creation date.

Although the scan produced quite a few few false positives, it did consistently find about 25 index.php files that were buried deep within the website at different locations, and all with the same creation date. Needless to say, I deleted these too.

I do not know how successful the cleaning procedure has been, the above script does not pick up normal eval strings, and many of the suspect gif and php files in the /images folder were not successfully detected with this script since they only had eval strings.  

The only thing to do is wait, my attackers will surely strike again. 

The next step is to find out how these miscreants got in. I suspect they may have got in by parking a php script on my server via a form. I shall now put some proper validation on those forms to make sure that no script files are uploaded.    

Wednesday, 24 April 2013



While in  the UK or US an employee will normally write character references as addresses at the end of his CV when they want to leave a job , this is not the modus operandi in German speaking countries (Germany, Switzerland and Austria). Typically at the end of a contract, or when an employee resigns from his post, he or she is legally entitled to obtain a written reference which he or she also has full access to. When applying for jobs he then inserts the reference at the back of his application portfolio.

This represents a special challenge to the writer of such a reference, since there are strict legal guidelines regarding what he can write.

In Germany Section 109 of the Industrial Code (Gewerbeordnung) states

 § 109 Employers Reference
(1) The employee is entitled to a written reference at the termination of his/her employment relationship. The reference must at least contain (simple reference) details on the nature and duration of his/her employment. The employee may also demand that additional details be provided  regarding performance and conduct within the employment relationship (qualified reference).
(2) The reference must be clear and understandable. It must not contain any features or formulations that are intended to make statements about the employee other than that which follows from its appearance or wording.
(3) The reference may not be granted in electronic form.
In Switzerland the requirement is covered in the fifth part of the Civil Code under the Code of Obligations

Art. 330a
1. The employee may at any time request from the employer a reference
concerning the nature and the duration of the employment relationship,
the quality of his work and his conduct.

2. At the employee’s express request the reference must be limited to
the nature and duration of the employment relationship.
In Austria the obligation is covered under the General Civil Code (ABGB; § 1163) as well as the Employment Law (AngG; § 39). Unlike Switzerland and Germany however, one is only entitled to demand a simple reference.    


All this means that employees also have the right to return the reference for revision if there is anything in it that they don't like or feel is misrepresenting.

In an attempt to combat this problem a system of coded statements has evolved to indicate how an employee might have performed on his job. On their own they all appear positive, but what is actually meant can be something quite different.

Although in its native country the system has somewhat been compromised due to more and more people becoming aware of it, it still remains in use, and translators need to be aware of it. Moreover, the translator needs a clear understanding of the relationship between the client and the translator. For agencies, project managers also need to be aware of the issues and communicate exactly what is needed to the translator. If the client is a company who is screening employees, then they will definitely want to know what the intended meaning actually is. If on the other hand the client is a private individual who wants his applications portfolio translated, it is likely that he would have no major problem with a more literal style of translation.

It is also quite likely that an employer outside of these countries would prefer a telephone reference anyway, making the translation of a written reference a moot activity.

And not all testimonials are prepared in this coded manner. A good proportion are just written with honest praise. The translator also needs to be aware of this and check for the signs.  

Moreover, any certification of such a translation would also be complicated. A literal translation would almost certainly be adequate for a prospective employee, but  a screening employer should also be made aware of what these intended meanings are.


Here is an example of how the overall performance is conveyed

Der Arbeitnehmer hat die ihm übertragenen Aufgaben
stets zu unserer vollsten Zufriedenheit
stets zu unserer vollen Zufriedenheit
zu unserer vollen Zufriedenheit
zu unserer Zufriedenheit
im Großen und Ganzen zufriedenstellend
mit großem Fleiß und Interesse

The employee fulfilled the duties assigned to him
always to our utmost satisfaction
always to our full satisfaction
to our full satisfaction
to our satisfaction
overall to our satisfaction
with great diligence and interest

Excellent (1 or A)
Good (2 or B)
Satisfactory (3 or C)
Adequate (4 or D)
Poor (5 or E)
Unsatisfactory (6 or F)

I have put the english translations in for guidance only. However, even if they appear somewhat "germanified", I would tend to use these translations since they do provide some direct reference to the original. 

Often one needs experts to decode the meaning of many coded statements, the website provides a whole range of statements that are used to describe an employees performance, categorised according to grade, but even this list is not comprehensive. 

Here are some more examples:

GER: Sie zeigte stets Engagement für Arbeitnehmerinteressen außerhalb der Firma

ENG: She always showed commitment to worker's issues outside the company. 

WHAT IT MEANS: She went on strike

GER: Er trat engagiert für die Interessen der Kollegen ein

ENG: He was committed to representing the interests of his colleagues

WHAT IT MEANS: He was on the works committee (Betriebsrat)

GER: Bei Kunden war sie schnell beliebt

ENG: Customers quickly endeared themselves to her

WHAT IT MEANS: She admitted too many faults and had no negotiation skills

GER: Er war seinen Mitarbeitern jederzeit ein verständnisvoller Vorgesetzter

ENG: He was always an understanding superior to his deputies

WHAT IT MEANS: He could not assert himself and was not respected

GER: Sie hat mit ihrer geselligen Art zur Verbesserung des Betriebsklimas beigetragen

ENG: With her convivial manner she always helped to improve the atmosphere in the workplace

WHAT IT MEANS: She got drunk on the job

The statement „war bemüht“ (endeavouring) or "bestrebt war" (striven)  should never appear, with both being a sign of total incompetence. 

However, a harmless statement such as "er war sehr hilfsbereit" (he was very helpful) is in contrast an absolute praise. 

GER: Das Verhalten gegenüber Kollegen war einwandfrei

ENG: His conduct towards his colleagues was faultless

WHAT IT MEANS: His conduct towards his superiors on the other hand took a lot to be desired 

For employees with responsibilities over monetary assets the phrase "Ehrlichkeit" (honesty) should be mentioned.

The date of an employment reference might also harbour information. If it is anything other than the end or the ides of the month it could be a sign of an immediate dismissal.

As can be seen, not everything is what it seems to be. Any wrong formulation can have negative consequences for someone looking for a job without him even being aware of it.

An employer who doesn't want to misrepresent an individual as an alcoholic should therefore never state. 

"Er stand stets voll hinter uns!" (Intended: he always stood by us, Perceived: He always stood drunk behind us !!).


Dr. Julian P. Keogh