-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sanitizing payload filename #194
Conversation
Thanks for your contribution. Could you please add some units tests? |
Hi Nick, will look into it asap |
I'm also not quite sure whether "path traversal" should be sneaked or a certain type of exception must be thrown. The exception might reveal the fact of an attack even keeping in mind that the training partner is known. @uhurusurfa what do you think or prefer? |
The vulnerability is currently exploitable for certain configs of MessageFileModule in config.xml so, the exploitability should definitely be addressed. Personally, I do like the idea of the of ringing the bell with a suitable exception. The most likely attack scenario would be a compromised trading partner rather than a malicious one. Another possibility is a bogus filename generated because of bugs or wrong settings at the TP's end, non trivial heuristics would be required to distinguish between this and an actual attack... but warning everybody that something is not right feels like the right thing to do. |
I agree an exception should be thrown but the server should silently log it
and not terminate from it but continue working. We definitely want the
trace to ring the bell and act upon the error but we can't stop hackers and
PTA actors from trying. Therefore uptime should not be affected by this
neither feedback should be provided to the bad actor about success or
failure of the attack attempt.
My 2 cents. J
…On Sat, Aug 22, 2020 at 5:02 AM LuigiG ***@***.***> wrote:
The vulnerability is currently exploitable for certain configs of
MessageFileModule in config.xml so, the exploitability should definitely be
addressed. Personally, I do like the idea of the of ringing the bell with a
suitable exception. The most likely attack scenario would be a compromised
trading partner rather than a malicious one. Another possibility is a bogus
filename generated because of bugs or wrong settings at the TP's end, non
trivial heuristics would be required to distinguish between this and an
actual attack... but warning everybody that something is not right feels
like the right thing to do.
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
<#194 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA2QND2BQAQA5XLW7PY2KG3SB6CTJANCNFSM4QHONIJA>
.
--
Javier Muñoz
CTO
Ingeniería | Greicodex Software C.A.
(+58) 212-7629120 <(+58)+212-7629120>
javier@greicodex.com
greicodex.com
Av. Francisco Solano con Calle La Iglesia. Torre Centro Solano Plaza I.
Piso 9, Oficina PH-A., Urb. Sabana Grande. Municipio Libertador. Dtto.
Capital. Código postal 1050.
[image: facebook] <http://facebook.com/greicodex>
[image: twitter] <https://twitter.com/greicodex>
|
@igwtech Why would you store a malicious file? Even its name has been "silently" sanitized. Somebody might want that an another system reads it or somebody will try to execute it somehow. To me, it makes no sense to such files. Thus, I propose introduce kind of "filename sanitizer" interface which would be part of the configuration. For instance:
or
|
Having reflected on this, I have reviewed the IETF AS2 spec and the related ones that it relies on for guidance. Specifically this line: So th e method should be changed to ensure all path information is always stripped. from the filename parameter along with any other characters that are deemed unusable for the target system. An exception should only be raised if the filename includes path information and not if the filename itself contains reserved characters since different file systems have different requirements regardin reserved characters. |
I think we can (mostly) leverage the JDK to implement the behavior outlined in Chris' comment. Specifically
A quick look at OpenJDK suggests the existing implementations do a good job at dealing with OS-specific conventions&requirements, see the Windows and Unix getFileName implementations as well as the Windows PathParser catching illegal chars:
So, please review the below pseudocode:
|
I would prefer sanitization checks to be done against whitelist charsets
instead of checking for bad characters. There are too many Unicode and
multibyte character combinations cases that can be used for transversal
that seems simpler to check for only what's allowed instead of what's
invalid.
Regards, J
…On Sun, Aug 23, 2020 at 8:18 AM LuigiG ***@***.***> wrote:
I think we can (mostly) leverage the JDK to implement the behavior
outlined in Chris' comment.
Specifically
1. Use a combination of FileSystem.getPath + catching
InvalidPathException to detect illegal characters in filenames.
2. Compare the proposed payload filename with the result of
Path.getFileName() to detect directory paths embedded within it.
A quick look at OpenJDK suggests the existing implementations do a good
job at dealing with OS-specific conventions&requirements, see the Windows
<https://github.com/openjdk/jdk/blob/39c023612dbdd1016ad24b60fdef464bf21d1016/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java#L310>
and Unix
<https://github.com/openjdk/jdk/blob/270674ce1b1b8d44bbe92949c3f7db7b7c767cac/src/java.base/unix/classes/sun/nio/fs/UnixPath.java#L285>
getFileName implementations
as well as the Windows PathParser catching illegal chars:
// Reserved characters for window path name
private static final String reservedChars = "<>:\"|?*";
private static final boolean isInvalidPathChar(char ch) {
return ch < '\u0020' || reservedChars.indexOf(ch) != -1;
}
So, please review the below pseudocode:
// tmpFilename = filenamed obtained from payload
// Check for illegal chars
try tmpPath = fileSystem.getPath(tmpFilename)
if InvalidPathException thrown then
log.warn("invalid chars in filename")
tmpFilename = org.openas2.utils.IOUtil.cleanFilename()
endif
// Note the below could theoretically throw IPE again... Generate new filename in that case?
try tmpPath = fileSystem.getPath(tmpFilename)
// No illegal chars, check for directory path in filename
baseName = tmpPath.getFileName()
if NOT baseName.equalsIgnoreCase(tmpFilename)
throw IllegalPayloadFilenameException(?)
endif
// fall-through, everything cool
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#194 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA2QNDYLRFTUGH2526HSYILSCECIPANCNFSM4QHONIJA>
.
--
Javier Muñoz
CTO
Ingeniería | Greicodex Software C.A.
(+58) 212-7629120 <(+58)+212-7629120>
javier@greicodex.com
greicodex.com
Av. Francisco Solano con Calle La Iglesia. Torre Centro Solano Plaza I.
Piso 9, Oficina PH-A., Urb. Sabana Grande. Municipio Libertador. Dtto.
Capital. Código postal 1050.
[image: facebook] <http://facebook.com/greicodex>
[image: twitter] <https://twitter.com/greicodex>
|
Hi Javier @igwtech Yes, for 'own use', I always stick to that approach and restrict the name to [ A-Z 0-9 -_. ] only ,which is enough as far as I'm concerned, esp for EDI. But I'm not so sure about OpenAS2 as it is meant to be generally deployable/usable anywhere in the world. I think we can trust the JRE/JDK here: for path traversal protection I think Path.getFileName is good enough as well as InvalidPathException for catching any illegal characters for a given platform, given how wildly the requirements differ between the various OS, it is unlikely that we would do a better job than the JDK developers if we try to reimplement those checks... |
Hi LuigiG,
You have a very good point there. I stand corrected.
J
…On Mon, Aug 24, 2020, 12:22 PM LuigiG ***@***.***> wrote:
Hi Javier @igwtech <https://github.com/igwtech>
Yes, for 'own use', I always stick to that approach and restrict the name
to [ A-Z 0-9 -_. ] only ,which is enough as far as I'm concerned, esp for
EDI. But I'm not so sure about OpenAS2 as it is meant to be generally
deployable/usable anywhere in the world. I think we can trust the JRE/JDK
here: for path traversal protection I think Path.getFileName is good enough
as well as InvalidPathException for catching any illegal characters for a
given platform, given how wildly the requirements differ between the
various OS, it is unlikely that we would do a better job than the JDK
developers if we try to reimplement those checks...
Thanks
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#194 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA2QNDY3EZZGVBSEO7TROHTSCKHUHANCNFSM4QHONIJA>
.
|
@citizenTwice - happy with that |
will get coding and add a new commit to this PR |
added IOUtil.getSafeFilename, this is invoked from BaseMessage when assigning an inbound msg filename
@uhurusurfa @VboxNick @igwtech Added new commits, please review. Updates: The filename sent by partner is now passed to IOUtil::getSafeFilename, 1 - known, bad characters (e.g. 0x0d, 0xa, 0x00) are removed automatically I've also tried to add a few unit tests. This turned out to be a bit tricky for me because rejection of some filenames is platform-dependent and the tests need to be deterministic. I've opted to let the tests run only on the platforms where I was able to directly verify the test results myself, that's the three main desktop/server OS's (Mac,Linux,Windows) ...but still, I am unsure as to whether better solutions for handling such cases exist. And sorry for the delay following-up on this. |
Awesome - thank you for the contribution. |
@uhurusurfa sorry to bother you with that but, shouldn't a CVE being created associated to this issue? |
@adioss It was not a vulnerability |
@uhurusurfa thanks a lot for the feedback. In fact, to be 100% transparent, I'm an AppSec engineer and Snyk reports this as a security issue.
Adrien |
@adioss - although that getSafeFielname() method was added to parse file names, there was already a filename check done in IOUtil.cleanFilename() that is called further downstream when the received file is actually persisted in the storage module handler and it is still called to this day so there was never a security vulnerability in OpenAS2. |
@adioss @uhurusurfa just jumping in to confirm what Christopher said about the filename filtering logic. However, a correction: I did 100% test the vulnerability with that version of OpenAS2, dropping a an arbitrary, executable payload in the bin/ directory. |
@citizenTwice - Thanks for the clarification. I am surprised and will cross check that the exploit does work without the getSafeFilename() invocation. |
@uhurusurfa @adioss just LMK if there's anything I can do to help, this was a while ago but I think I could probably dig up my notes & screenshots. |
For review: proposed mitigation of path traversal vulnerability, as per separate discussion vie email with developer Christopher Broderick.