Obfuscating Silverlight XAP - silverlight

I am wondering any efficient way to hide our Silverlight code. I know there are some obfuscators available but it looks like people can hack that too. Anybody have any success on this front?

Pragma No-Cache on the page hosting the silverlight application will prevent the the browser from caching the xap, instead it will read it by streaming from the web server. That will make it harder for peeps to get the xap. Obfuscation will make it harder still.
Also make sure the app is hosted in https, have authentication take place outside the main application. This way the xap stream is encoded on the way down.

You really can't hide anything that gets transmitted to the client. If people want to figure it out, they will.
You need to put any proprietary code in your back-end where client machines can't get at it.

No. The client browser must be able to read the code, therefore it is hackable.

Here is a short article on how to obfuscate a xap file
http://www.rudigrobler.net/Blog/obfuscating-silverlight

You could complicate the potential hacker's job by downloading obfuscated fragments of your app during execution, using MEF for instance. Needless to say that it's interesting if your application is big enough so that this astuce speed up startup time rather than hindering the user's experience.
It won't prevent a valorous hacker from getting your code (in the hand no method can prevent this, as the Silverlight plugin must be able to execute it), but the astuce will complicate his task greatly.
preventing the browser from caching the XAP is useless, like using HTTPS, as it's far easier for the attacker to use something as complicated as firebug to get the XAP than looking for it in the browser cache or using a Man in the Middle Attack.
I imagine that if you had lot of motivation, you could:
obfuscate every assemblies
use dynamic loaded XAPs
encrypt the dynamic loaded XAP serverside and decrypt it client side using a dynamicly generated key sent by a webservice (Not in the same request. And don't reuse the key.)
It won't prevent the attacker from getting your code, but he will have to analyse your initial (obfuscated) xap to understand the decryption code, get the key, get the encrypted (obfuscated too) dynamic loaded XAP, decrypt it, then manage to unobfuscate it, then understand how it plugs itself in the application.
It's not the same as using HTTPS, because here the encryption and decryption process is done in the application so that tools like firebug or fiddler become useless.
Hem. Nothing can prevent anyone from reading your code. BUT you can make it not worth his time. You don't have to use all the ideas here and I am sure that you can find others, but make sure that implementing such measures are worth your time too.
Either way, it was rather funny to write this :p

You cannot hide (at least not non-trivially) XAP files. But you can obfuscate them. Obfuscation is not a definitive answer, but its a start and can give pretty good protection.

Related

Medium to large file uploads with progress updates in AspNet Core

By medium to large I mean anything from 10mb -> 200mb (sound files if that is important)
basically I want to make an API that does some spectral analysis on the file itself, this would require a file upload. But for UI/UX reasons it would be nice to have a progress bar for the upload process. What are the common architectures for achieving this interaction.
The client application uploading the file will be a javascript client (reactjs/redux) and the API is written in ASP.NET Core. I have seen some examples which use websockets to update the client on progress, and other examples where the client polls for status updates given a resource url to query the status. Are there any best practices (or the "modern way of doing this") for doing such a thing that I should know of? TIA
In general, you just need to save progress status while reading the input stream in your controller to some variable (session-specific variable, because there might be a few file uploading sessions at the same time) and then get this status from the client-side by ajax requests (or signalr).
You could take a look at this example: https://github.com/DmitrySikorsky/AspNetCoreUploadingProgress
I have tried 11 MB files with no problems. There is line
await Task.Delay(10); // It is only to make the process slower
there, don't forget to remove it in the real solution.
In this sample files are loaded by the ajax, so I didn't try really large files, but you can use iframe solution from this sample:
https://github.com/DmitrySikorsky/AspNetCoreFileUploading
The other part will be almost the same.
Hope this helps you. Feel free to ask if have any additional questions.

GWT RPC Data Encryption and gwt-crypto issue

I have a GWT app, which is deployed on the app engine. The application is basically an exam simulator. All the exam questions and answers are stored in an XML file on the server. I use JAXB parser to parse the XML file and send a list of objects to the client through GWT RPC.
I noticed that during the transit (server -> client), the entire data is visible in plain text in Firebug. Since the data (exam questions and answers) are my intellectual property (IP) and something that I give lot of value to, I'm concerned that it's very easy to steal that data. Therefore, I'm trying to find ways to do some basic encryption and obfuscate the content when it's being sent over from the server to the client.
After Googling, I came across gwt-crypto project, and within a few minutes, I was able to achieve the exact result that I wanted. The server would encrypt the data, and the client would decrypt it. In Firebug, it would show the data in encrypted format, and not as plain text.
However, I ran into an issue. After implementing encryption/decryption, I noticed that my application would not load inside my company's network, which is obviously protected by a firewall. The application works perfectly from home or even on a 3G network on my phone. Another version of the application, which does not use encryption/decryption works perfectly from within my company's network. I confirmed this by creating 2 exact same versions of the app, with the only difference between a boolean flag, that determines whether encryption/decryption is enabled or disabled.
I have the following questions here:
What is the best way to achieve the result that I want to achieve? Is gwt-crypto a good solution for that? I'm fine with any simple approach to obfuscate the data during transit. It doesn't have to be a sophisticated algorithm.
What could be the possible reason for a GWT app, with encryption/decryption enabled, not working inside a firewall? I'm really clueless on this.
I'll appreciate any help on this issue.
Using SSL is the right way to go.
In your case, given AppEngine SSL limitations, you should load your HTML normally from non-SSL domain and use cross-site RPC to load your data via SSL domain.
Update:
What is the best way to achieve the result that I want to achieve?
If you want to secure the data in transit then the only secure option is SSL/HTTP. Usually it's also the simplest one as it does not require you to change the application code, just server configuration. In your particular case (appengine with private domain), it takes more work as described above.
Is gwt-crypto a good solution for that?
No. gwt-crypto uses a key to encrpt/decrypt the data. You also need a secure way to discribute this key.
I'm fine with any simple approach to obfuscate the data during transit.
Security through obscurity in not security. It's a false sense of security, which is even more dangerous than no security. It's enough that only one of the technically capable students cracks this and soon everybody would do it.
Possible attack would go like this:
Snoop the network, get username/password of user.
Login as that user, have browser load exam data, which is now unencrypted in memory.
Dump the DOM and inspect it for exam questions.
-
What could be the possible reason for a GWT app, with encryption/decryption
enabled, not working inside a firewall?
Use firebug to make sure network connections are identical, except for the encrypted content. Firewalls should not work that deep. Talk to sysadmin about it.

Does Silverlight 4's WriteableBitmap *really* cripple legit cross-domain access in the name of DRM?

In this thread from a year ago it's explained that WriteableBitmap will block read access when any part of it comes from an outside domain - say a free image server.
It's further elaborated upon that this is for "DRM". I guess there's some big threat of someone writing a movie-ripper in Silverlight that includes a movie from another domain and then re-captures it... except for the realization you can just rewrite the bloody xap as it comes down the wire and then it's same-domain! But that's neither here nor there.
Anyway, obviously I'm trying to use WritableBitmap to export a screenshot of the user's current setup; but I'm stopped by this cross-domain issue.
Is there really no supported way to do this in the latest version of Silverlight? No crossdomain.xml or clientaccesspolicy.xml? Isn't this crippling for Silverlight - a giant "Screw You", putting half-hearted security roadblocks in that impede developers but don't stop attackers?
Edit: This question is identical to this question here.
Your sentiment is shared by many, many devs trying to do this for legit purposes. There are some work-arounds out there, all of them either hacky or bizarro. But this is probably the best one I've seen: Screen Capture in SIlverlight 4.0.
Just read again and saw that you're not looking for a crossdomain.xml solution. This page has some other options (again, no solution out there is "great"): http://betaforums.silverlight.net/forums/t/118030.aspx
Also, not sure if this is an option, but your app as an OOB app will not be restricted to security checks in ClientAccessPolicy.xml or CrossDomain.xml. Is Out-of-Browser an option for you?
EDIT:
Upon further review of the post and comments, I believe (Tom, please confirm this) that the need isn't to get a screenshot of the user's instance of the SL app running on their own box (which something like Customer Support in Silverlight would take care of pretty well).
Rather, it is to take picture of the user's screen (same as PrtSc-ish). In this case, it is a lot tougher, but not impossible. Rui show's how he does it here, but it relies on a component already being on a user's machine. Jeremy get's even more creative with Silverlight 4 Hack: Use Native/Desktop CLR Without COM Registration, which would effectively allow access.
This WritableBitmap behavior have nothing to do with DRM and everything to do with security. If the screenshot you trying to take shows image element with content from different domain then that domain must have crossdomain.xml file with appropriate permissions. You can contact domain owner and ask them to place crossromain.xml in the root of their domain.
Alternatively, Full-Trust OOB application should do the trick since it doesn't check for crossdomain.xml.
Ok, If you have <Image Source="http://crossdomain.com/someimage.jpg" /> in your visual tree and you try to create WriteableBitmap from it, that WriteableBitmap's pixel access will be locked, crossdomain.xml or not. (Shame on you microsoft). Good news (sorta) is, you can use following workaround: Load image using WebClient; call SetSource on image with stream from OpenReadCompleted handler. Create your WriteableBitmap and notice how Pixels property doesn't throw security exception anymore. Far from ideal, but manageable.
As explained in the identical question the only way to get silverlight to allow you to get the content out of a Writeable Bitmap without any of the following:
Out-of-browser
Service/Code/App/Rooted GAC otherwise installed on the user's Machine
Elevated Trust
is to proxy the content and trick silverlight into thinking it's all from the same domain.

Logging when application is running as XBAP?

Anybody here has actually implemented any logging strategy when application is running as XBAP ? Any suggestion (as code) as to how to implement a simple strategy base on your experience.
My app in desktop mode actually logs to a log file (rolling log) using integrated asop log4net implementation but in xbap I can't log cause it stores the file in cache (app2.0 or something folder) so I check if browser hosted and dont log since i dont even know if it ever logs...(why same codebase)....if there was a way to push this log to a service like a web service or post error to some endpoint...
My xbap is full trust intranet mode.
I would log to isolated storage and provide a way for users to submit the log back to the server using either a simple PUT/POST with HttpWebRequest or, if you're feeling frisky, via a WCF service.
Keep in mind an XBAP only gets 512k of isolated storage so you may actually want to push those event logs back to the server automatically. Also remember that the XBAP can only speak back to it's origin server, so the service that accepts the log files must run under the same domain.
Here's some quick sample code that shows how to setup a TextWriterTraceListener on top of an IsolatedStorageFileStream at which point you can can just use the standard Trace.Write[XXX] methods to do your logging.
IsolatedStorageFileStream traceFileStream = new IsolatedStorageFileStream("Trace.log", FileMode.OpenOrCreate, FileAccess.Write);
TraceListener traceListener = new TextWriterTraceListener(traceFileStream);
Trace.Listeners.Add(traceListener);
UPDATE
Here is a revised answer due to the revision you've made to your question with more details.
Since you mention you're using log4net in your desktop app we can build upon that dependency you are already comfortable working with as it is entirely possible to continue to use log4net in the XBAP version as well. Log4net does not come with an implementation that will solve this problem out of the box, but it is possible to write an implementation of a log4net IAppender which communicates with WCF.
I took a look at the implementation the other answerer linked to by Joachim Kerschbaumer (all credit due) and it looks like a solid implementation. My first concern was that, in a sample, someone might be logging back to the service on every event and perhaps synchronously, but the implementation actually has support for queuing up a certain number of events and sending them back to the server in batch form. Also, when it does send to the service, it does so using an async invocation of an Action delegate which means it will execute on a thread pool thread and not block the UI. Therefore I would say that implementation is quite solid.
Here's the steps I would take from here:
Download Joachim's WCF appender implementation
Add his project's to your solution.
Reference the WCFAppender project from your XBAP
Configure log4net to use the WCF appender. Now, there are several settings for this logger so I suggest checking out his sample app's config. The most important ones however are QueueSize and FlushLevel. You should set QueueSize high enough so that, based on how much you actually are logging, you won't be chattering with the WCF service too much. If you're just configuring warnings/errors then you can probably set this to something low. If you're configuring with informational then you want to set this a little higher. As far as FlushLevel you should probably just set this to ERROR as this will just guarantee that no matter how big the queue is at the time an error occurs everything will be flushed at the moment an error is logged.
The sample appears to use LINQ2SQL to log to a custom DB inside of the WCF service. You will need to replace this implementation to log to whatever data source best suits your needs.
Now, Joachim's sample is written in a way that's intended to be very easy for someone to download, run and understand very quickly. I would definitely change a couple things about it if I were putting it into a production solution:
Separate the WCF contracts into a separate library which you can share between the client and the server. This would allow you to stop using a Visual Studio service reference in the WCFAppender library and just reference the same contract library for the data types. Likewise, since the contracts would no longer be in the service itself, you would reference the contract library from the service.
I don't know that wsHttpBinding is really necessary here. It comes with a couple more knobs and switches than one probably needs for something as simple as this. I would probably go with the simpler basicHttpBinding and if you wanted to make sure the log data was encrypted over the wire I would just make sure to use HTTPS.
My approach has been to log to a remote service, keyed by a unique user ID or GUID. The overhead isn't very high with the usual async calls.
You can cache messages locally, too, either in RAM or in isolated storage -- perhaps as a backup in case the network isn't accessible.
Be sure to watch for duplicate events within a certain time window. You don't want to log 1,000 copies of the same Exception over a period of a few seconds.
Also, I like to log more than just errors. You can also log performance data, such as how long certain functions take to execute (particularly out-of-process calls), or more detailed data in response to the user explicitly entering into a "debug and report" mode. Checking for calls that take longer than a certain threshold is also useful to help catch regressions and preempt user complaints.
If you are running your XBAP under partial trust, you are only allowed to write to the IsolatedStorage on the client machine. And it's just 512 KB, which you would probably want to use in a more valuable way (than for logging), like for storing user's preferences.
You are not allowed to do any Remoting stuff as well under partial trust, so you can't use log4net RemotingAppender.
Finally, under partial trust XBAP you have WebPermission to talk to the server of your app origin only. I would recommend using a WCF service, like described in this article. We use similar configuration in my current project and it works fine.
Then, basically, on the WCF server side you can do logging to any place appropriate: file, database, etc. You may also want to keep your log4net logging code and try to use one of the wcf log appenders available on the internets (this or this).

Whats a good way to protect a link database from automatic scrapers?

I have a large link database, that I would want to protect against others who would want to copy them. Is there anything I can do other than force people to enter a CAPTCHA before each link?
you can output the links using ROT13, and then use javascript to put them back to normal.
this way, the scrapers must support javascript in order to steal your links, which should cut down on the number of eligible scrapers
bonus points: replace ROT13 with something harder, and obfuscate your 'decode' javascript.
The javascript suggestion could work, but you would render your page inaccessible to those using assistive technologies like screen readers as well as anyone without javascript.
Another possible option would be to generate a cryptographic nonce. This technique is currently used to protect against CSRF attacks, but could also be used to ensure that the scraper would have to request a page from your site before accessing a link. This approach may not be appropriate if you support hotlinking, but if you just want to make sure that someone went to your site first, it could work.
Another somewhat ghetto option would be use referrers. These can be easily faked, but it might prevent some of the dumber scrapers. This also requires that you know where your users came from before they hit your site.
Can you let us know if you are hotlinking or if the user comes to your site before going to the protected link? We might be able to provide better advice that way.

Resources