I am trying to establish the best practice for handling the creation of child objects when the parent object is incomplete or doesn't yet exist in a web application. I want to handle this in a stateless way so in memory objects are out.
For example, say we have a bug tracking application.
A Bug has a title and a description (both required) and any number of attachments. So the "Bug" is the parent object with a list of "Attachment" children.
So you present a page with a title input, a description input, and a file input to add an attachment. People then add the attachments but we haven't created the Parent Bug as yet.
How do you handle persisting the added attachments ?
Obviously we have to keep track of the attachments added, but at this point we haven't persisted the parent "Bug" object to attach the "Attachment" to.
Create the incomplete bug and define a process for handling incompleteness. (Wait X minutes/hours/days, then delete it/email someone/accept it as it is.) Even without a title or description, knowing that a problem occurred and the information in the attachment is potentially useful. The attachment may include a full description, but the user just put it somewhere other than you'd attended. Or it may only contain scattered data points which are meaningless on their own - but could corroborate another user's report.
I would normally just create the Bug object and its child, the Attachment object, within the same HTTP response after the user has submitted the form.
If I'm reading you right, the user input consists of a single form with the aforementioned fields for bug title, description, and the attached file. After the user fills out these fields (including the selection of a file to upload), then clicks on Submit, your application receives all three of these pieces of data simultaneously, as POST variables in the HTTP request. (The attachment is just another bit of POST data, as described in RFC 1867.)
From your application's end, depending on what kind of framework you are using, you will probably be given a filename pointing to the location of the uploaded file in some suitable temporary directory. E.g., with Perl's CGI module, you can do:
use CGI qw(:standard);
my $query = CGI->new;
print "Bug title: " . $query->param("title") . "\n";
print "Description: " . $query->param("description"). "\n";
print "Path to uploaded attachment: " . $query->param("attachment") . "\n";
to obtain the name of the uploaded file (the file data sent through the form by your user is automatically saved in a temporary file for your convenience), along with its metadata. Since you have access to both the textual field data and the file attachment simultaneously, you can create your Bug and Attachment objects in whatever order you please, without needing to persist any incomplete data across HTTP responses.
Or am I not understanding you here?
In this case I would consider storing the attachments in some type of temporary storage, be it Session State, a temp directory on the file system, or perhaps a database. Once the bug has been saved, I would then copy the attachments to their actual place.
Careful with session though, if you let them upload large attachments you could push memory issues depending on your environment.
One approach I saw before was as soon as the user opens the new bug form, a new bug is generated in your database. Depending on your app this may or may not be a good thing. If your collecting data from a user for example, this is useful as you get some intelligence even if they fail to enter the data, and leave your site. You still know they started the process, and whatever else you collected like user agent etc..
Related
This is a pretty straightforward situation. We have a database table that has a VARBINARY(MAX) field, this field contains a text file. On the .NET side the user can download the text file from the database. It's just plain text and coming from a trusted source. However, fortify/checkmarx complains about Stored XSS. The code is pretty straightforward.
Response.Clear()
Response.ContentType = "text/plain"
Response.AddHeader("content-disposition, $"attachment;filename=FileToDownload.txt")
Response.BinaryWrite(datafromDB)
Response.[End]()
The vulnerability scan points to the Response.BinaryWrite() and complains of Stored XSS, of course this is silly considering it's coming from a trusted source. However, I want to find a way to remediate this Is there a way to filter out the "datafromDB" object or sanitize this before it hits the response.BinaryWrite.
If the response is text, escaping it should not change the content to a form that would be potentially exploitable. You should escape data before it is sent to the client, here is why:
"Trusted data" does not exist. You are not considering:
A disgruntled employee may change the data in the DB and inject exploitable content.
There may be more than one path for data to get into the database. Not all of those paths may perform sanitization on the data before it is written to the DB. It is often common to have applications where data is imported into the back end database via an off-line mechanism.
The vulnerability analysis is not going to consider the content-type since setting the content type is essentially "control flow" analysis. The current vulnerability analysis technique (Data flow analysis) looks at the path of the data from source (DB) to sink (response stream) to recognize the exploit pattern. Setting the content type is not on that data flow path; even if it was, the static string content is not evaluated for how it affects state of a response object because it is a control flow change.
If you mark it as "Not Exploitable" as-is, it is true for the code in the current state that it is not-exploitable. However, if someone comes along later and changes the encoding value without changing the code involved in the data flow, the NE marking is maintained. You will therefore have an undetected "False Negative" because the control flow changed that now made the code exploitable.
Reliance on "compensating controls" such as setting response headers or relying on deployment configuration/environment controls works until it doesn't. Eventually, someone may decide to make a change that removes a compensating control (e.g. changing the response content type in this case) that was used to justify marking something Not Exploitable rather than remediating the issue properly. It then becomes a security hole that may be sitting in the open waiting for someone to find and exploit.
I'm all for relying on compensating controls, but with that comes the need to ensure changes to compensating controls are detected. It is often easier to implement the proper remediation rather than add more automation around detecting changes to compensating controls. The software implementation is the last line of defense when all else fails.
I am trying build an api which conforms to the json:api spec.
My api has three resources /task, /item and /result. A task has the fields name, description and state. A item has the fields itemName. A count is kept server-site for the item and the count is returned when a user retrieves the item with a GET request. The count is incremented server-side when the item is updated. There is a one-to-many relationship between task and item. In a sense an item is appended to a task. When the tasks state changes a script runs server-side to do some processing on the associated items. Once the script finishes the output is available in the result resource.
Per the spec, I am using the POST verb to create a task and the PATCH to update a task. I just want one endpoint which handles both the create /update (appending) of an item. But, I'm not sure which verb to use? Can I use PATCH to update the item but also create an item if it doesn't exist?
I also thought that perhaps I should be using the PUT verb. But, my understanding here is that this verb is used to simply replace a resource rather than update it. I don't think this is right for my user-case as an items count is incremented when updated, so replacing it is not what I want todo. But, the count is handled server-side so a user doesn't have the option of "replacing" the count anyway.
my understanding here is that this verb is used to simply replace a resource rather than update it.
This is a common understanding - wrong, but common.
The IANA registry documents the authoritative reference for the semantics of http methods. Most of the common ones are defined by RFC 7231; PATCH is defined by RFC 5789.
PUT is an appropriate choice when the message body is a complete representation of what you want the resource to be. It may be easier to think about "saving a file"; PUT describes what the client expects the document to look like when it has been saved.
It's appropriate to use PUT for either updating a document or creating one, provided that the client knows the identifier for the document (just in the same way that we can use save to create a file, or replace a file, but we need to know the file name).
If you read the text of the specification, you'll see that - while the semantics of the request are to save the new representation "as-is", the server isn't required to do that -- the server, after all, is in control of its own documents -- so there is room to cover read only fields, or fields that should be updated by the server only. You need to have a little bit of care with the response headers to avoid implying that you saved the representation as is, but other than that you should be fine.
I'm new to the concept of DDD and CQRS and can't find a final solution how to upload images, or files in general, in a clean way.
Imagine the following scenario:
In an online portal there is a support request formular where a file (image in specific) could be attached to.
The posted data will raise a CreateSupportRequestCommand. Then the required aggregates will be loaded and changed.
I have three ideas to solve this, but I'm not very satisfied with them.
Way 1:
1. Post all data including the image (multipart) in a single request
2. Create a FileUploadCommand, which is returning the FileUploadId.
3. After that create a CreateSupportRequestCommand and pass the FileUploadId with the root data in the constructor.
Drawback: A single request will trigger two commands. In terms of CQRS one user interaction should be only one command.
Way 2:
1. Post the image to a seperate endpoint, create a temporary file and return the id or a file handle.
2. Post the formular with the attached tempfile id.
3. Invoke the CreateSupportRequestCommand with all root data including a file handle which points to the physical file.
4. Inside the command persist the tempfile into a FileUpload aggregate (by FileUploadRepository) then
5. Create the SupportRequest aggregate, assign the FileUploadId and persist.
Drawback: I handle 2 aggregates in the same command. Creating a support request is not responsible for uploading the file.
Way 3:
1. Post the image to a seperate endpoint, create a temporary file and return the id or a file handle.
2. Post the formular with the attached tempfile id.
3. Invoke the CreateSupportRequestCommand with all root data including a file handle which points to the physical file.
4. Only persist the root data to the SupportRequest aggregate. Raise a SupportRequestCreatedEvent and attach the file handle.
5. Inside the event process and assign the file handle.
Drawback: The SupportRequestCreatedEvent should not really care about a file handle.
Is there a better way to solve this?
I do not think handling File upload is a Domain Concern. The file metadata like FileContentId may be part of your domain but not the actual file upload. I would perform the file operation before the CommandHandler is executed. Probably in a middleware or perhaps before queing up the Command onto the message bus.
CreateSupportRequestCommandHandler would then only be invoking an operation like CreateSupportRequest on your aggrerate (say SupportRequest). Within that CreateSupportRequest method you will have all your business rule pretaining to the operation. SupportRequest then eventually would be saved in your repository.
This is somewhat a duplicate of this question, but that question has no (valid) answer and is 1.5 years old so asking my own with hopes people have more info now.
If you are using multiple instances of a WebBrowser control, MSHTML, IHTMLDocument, or whatever... from inside the APP instance, mostly IInternetProtocol::Start, is there a way to know which instance is loading the resource? Or is there a way to use a different APP for each instance of the control, maybe by providing one via IDocHostUIHandler or ICustomDoc or otherwise? I'm currently using IInternetSession::RegisterNameSpace to make it process wide.
Optional reading below, don't feel you need to read it unless above isn't clear.
I'm working on a legacy (Win32 C++) email client that uses the MS ActiveX WebBrowser control (MSHTML or other names it goes by) to display HTML emails. It was saving everything to temp files, updating the cid: URLs, and then having the control load that. Now I want to do it the correct way, using APP. I've got it all working with some test code that just uses static variables/globals and loads one email.
My problem now is, the app might have several instances of the control all loading different emails (and other stuff) at the same time... not really multiple threads so much, just the asynchronous nature of the control. I can give each instance of the control a unique URL to load the email, say, cid:email-GUID, and then in my APP code I can use that URL to know which email to load. However, when it comes to loading any content inside the email, like attached images using src="cid:", those will not always be unique so I will not always know which image it is, for which email. I'd like to avoid having to modify the URLs of the HTML before displaying it (I'm doing that now for the temp file thing, but want to do it a better way).
IInternetBindInfo::GetBindString can return the referrer, BINDSTRING_XDR_ORIGIN, or the root URL, BINDSTRING_ROOTDOC_URL, but those require newer versions of IE and my legacy app must support older XP installs that might even have IE6 or IE7, so I'd rather not use these.
Tagged as TWebBrowser because that is actually what I'm using (Borland Builder 6 C++), but don't need answers specific to that platform.
As the Asynchronous Pluggable Protocol Handler us very low level, you cannot attach handlers individually to different rendering controls.
Here is a way to get the referrer:
Obtain BINDSTRING_HEADERS
Extract the referrer by parsing the line Referer: http://....
See also How can I add an extra http header using IHTTPNegotiate?
Here is another crazy way:
Create another Asynchronous Pluggable Protocol Handler by calling RegisterMimeFilter.
Monitor text/plain and text/html
Scan the incoming email source (content comes incrementally) and parse store all image links in a dictionary
In NameSpaceHandler you can use this dictionary to find the reference of any image resources.
I would like to clarify how do ext 4 models correlate to form panels.
Suppose I have a model, e.g. "User", which has a REST proxy attached.
When I want to modify user parameters, i use form's
loadRecord( Ext.data.Model record ) : Ext.form.Basic
method, to set form's field values.
After modification, I call "updateRecord" method, to send changes from form to loaded model, and then use model's "save" method, to send changes to server. This works quite well, and seems to fit Ext MVC concepts.
Question
But, the question is: how should I conform to MVC, in case I need to upload file, while modifying user's data (e.g. avatar). According to what I learned from docs, I should switch to using form's "submit" method to send updated data so server, including the file.
In this case, I see several drawbacks:
The original model, loaded to the form, will not be updated.
If I update the model (using "updateRecord", or other way), the model will stay in dirty state, however, changes have already been sent to server.
The same proxy configuration should be applied to form, as to model, so that I would not need to change server side.
Is this a correct way of implementing file-upload through ext forms?
Is there any way to do this using model.save method, to be more MVC-stylish?
I don't think you can combine two thing together. File upload will always be something different than submitting the rest of the data. What you can do however:
Have a button to select and upload file to the server. But don't save file into the same place where you save your user (for example you can have separate file storage and save just file name into the user record)
When sending user record update to the server send new file name. This way your avatar update and other data update will be in the same transaction.