Есть ли в java библиотеки, позволяющие эскейпить shell-токены?
Стоит задача выполнения различных операций по SSH. Например, записать текст по SSH в файл, используя
echo userInput > file
Текст является вводом пользователя. Какие есть готовые решения, чтобы заэскейпить пользовательский ввод, дабы не возникло bash инъекции? В питоне для этого есть встроенный модуль shlex с нужным методом shlex.quote, для Java чего-то подобного не нашёл.
Ответы (1 шт):
Автор решения: Михаил Муругов
→ Ссылка
Оказалось, что shlex написан на самом питоне (ожидал, что это скомпилированная C библиотека) и нет проблем посмотреть реализацию метода quote:
_find_unsafe = re.compile(r'[^\w@%+=:,./-]', re.ASCII).search
def quote(s):
"""Return a shell-escaped version of the string *s*."""
if not s:
return "''"
if _find_unsafe(s) is None:
return s
# use single quotes, and put single quotes into double quotes
# the string $'b is then quoted as '$'"'"'b'
return "'" + s.replace("'", "'\"'\"'") + "'"
Моя Java имплементация:
import java.util.regex.Pattern;
public class Shlex {
private static final Pattern UNSAFE_SYMBOLS = Pattern.compile("[^\\w@%+=:,./-]");
private Shlex() {
}
public static String quote(String token) {
if (token.isEmpty()) {
return "''";
}
if (!UNSAFE_SYMBOLS.matcher(token).find()) {
return token;
}
return "'" + token.replace("'", "'\"'\"'") + "'";
}
}
Тесты:
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class ShlexTest {
@Test
public void quoteUnsafeString() {
assertEquals("'sp ace'", Shlex.quote("sp ace"));
String command = String.format("ls -l %s", Shlex.quote("somefile; rm -rf ~"));
assertEquals("ls -l 'somefile; rm -rf ~'", command);
String remote_command = String.format("ssh home %s", Shlex.quote(command));
assertEquals("ssh home 'ls -l '\"'\"'somefile; rm -rf ~'\"'\"''", remote_command);
}
@Test
public void quoteSafeString() {
assertEquals("string", Shlex.quote("string"));
}
}