How can I protect my asp.net Handler page - asp.net

I'm using this practice to add comments using AJAX , by sending the data to an ASP.NET Handler which collect the information and then insert the comment, but I am afraid that any one could use it , am I wrong !?
//AddComment.ashx
public void ProcessRequest (HttpContext context) {
CommentsDB db = new CommentsDB();
db.InsertComment(new Comment(context.Request["name"].ToString(), context.Request["comment"].ToString(), "no", int.Parse(context.Request["id"].ToString())));
context.Response.ContentType = "text/plain";
context.Response.Write("succeed");
}
//Comments.js
function AddComment()
{
n = document.getElementById('txtName').value;
c = document.getElementById('txtComment').value;
i = document.getElementById('ctl00_ContentPlaceHolder1_thread').value;
m = document.getElementById('ctl00_ContentPlaceHolder1_Label1');
if(n == "" || c == "" || n.length > 100 || c.length > 400)
{
m.innerHTML = "<center><font color=black size=3><b><font color=red>*</font> An error has occurred</b></font></center><br>";
return;
}
m.innerHTML = "";
document.getElementById('btn').disabled = true;
$.post("./Handlers/AddComment.ashx", {'name':n, 'comment':c, 'id':i}, function(Response){
m.innerHTML = "<center><font color=black size=3><b>accepted</b> <img src=./Images/success-icon.png></font></center><br>";
});
}

Your assumption is correct, that your users can potentially make their own HTTP requests to your handler, and provide bogus data. They could also manipulate your page markup in their browsers (with any developer toolbar) and do the same.
So, you're going to want to do some validation on your server side if you're worried about this. If your application requires authentication, just look up the current user's name in the handler's ProcessRequest method, rather than posting it.
I think that's what your question is getting at. Also, clean up your markup, center and font tags are deprecated.

If you require that the commenters to be logged in than check for the actual user (stored on the web server - in session for example).
Or if you allow non authenticated comments, than consider using some captcha to protect against automated requests.

Related

how to read additional parameters in alfresco 5.1.1- aikau faceted search

Custom Search UI will be populated when user selects Complex asset in the Advance search screen drop down(apart from Folders,Contents) where 12 fields will be displayed .So when user clicks search button ,need to read those values and redirect to the alfresco repo files(org/alfresco/slingshot/search/search.get.js).We have already customized these files(search.get.js,search.lib.js) existed in the repository to suit out logic and working fine in 4.2.2;As we are migrating to 511,so we need to change this logic in customized faceted-search.get.js to read these values.How to write this logic in customized facted-search.get.js?
It's not actually possible to read those URL hash attributes in the faceted-search.get.js file because the JavaScript controller of the WebScript does not have access to that part of the URL (it only has information about the URL and the request parameters, not the hash parameters).
The hash parameters are actually handled on the client-side by the AlfSearchList widget.
Maybe you could explain what you're trying to achieve so that I can suggest an alternative - i.e. the end goal for the user, not the specifics of the coding you're trying to achieve.
We will be reading the querystring values something like below in the .get.js file.
function getNodeRef(){
var queryString = page.url.getQueryString();
var nodeRef = "NOT FOUND";
var stringArray = queryString.split("&");
for (var t = 0; t < stringArray.length; t++) {
if (stringArray[t].indexOf('nodeRef=') > -1) {
nodeRef = stringArray[t].split('=')[1];
break;
}
}
if (nodeRef !== "NOT FOUND") {
nodeRef = nodeRef.replace("://", "/");
return nodeRef;
}
else {
throw new Error("Node Reference is not found.");
}
}
It may be help you and we will wait for Dave Drapper suggestion also.

Spoofing HTTP Referrer data using ASP.NET

Answers on here and various other sites are often full of warnings not to trust HTTP Referrer headers because they are 'so easily' spoofed or faked.
Before I go any further - no, I'm not up to no good - but I do want to run some referrer-dependant tests.
Whilst I don't doubt that the warnings about fake referrers are true, I can't really find much detailed info on how they can be manipulated. Even the Wikipedia article only talks about it in general terms.
I'm about to play with the RefControl addin for FireFox.
Programatically (in ASP.NET specifically) the UrlReferrer is a read-only property, so I don't see how I can fire off requests with fake referrer data if I can't set it? Do I really have to do it manually?
How would I use ASP.NET to send a request to my site with a user-supplied variable to populate the referrer header?
EDIT : As per my comment below, I ideally want to take an incoming request, manupulate the referrer data and then pass the request on to another page, intact. If I can make it appear intact by building a new one from scratch and copying the original properties, then that is fine too.
I don't know if this exactly what you want, but in general, you should be able to spoof the value of the UrlReferer property (even if it's read-only) in HttpContext.Current.Request by using a bit of reflection.
For example:
FieldInfo fi = HttpContext.Current.Request.GetType().GetField("_referrer", BindingFlags.NonPublic | BindingFlags.Instance);
string initialReferer = HttpContext.Current.Request.UrlReferrer.ToString();
if (fi != null)
fi.SetValue(HttpContext.Current.Request, new Uri("http://example.com"));
string fakedReferer = HttpContext.Current.Request.UrlReferrer.ToString();
On VS; these are the values before and after changing the UrlReferrer:
initialReferer
"http://localhost/Test/Default.aspx"
fakedReferer
"http://example.com/"
If you open the System.Web assembly using ILSpy you'll notice that the UrlReferrer property looks something like this:
public Uri UrlReferrer
{
get
{
if (this._referrer == null && this._wr != null)
{
string knownRequestHeader = this._wr.GetKnownRequestHeader(36);
if (!string.IsNullOrEmpty(knownRequestHeader))
{
try
{
if (knownRequestHeader.IndexOf("://", StringComparison.Ordinal) >= 0)
{
this._referrer = new Uri(knownRequestHeader);
}
else
{
this._referrer = new Uri(this.Url, knownRequestHeader);
}
}
catch (HttpException)
{
this._referrer = null;
}
}
}
return this._referrer;
}
}
This likely isn't going to get you what you want. But you can edit the Referror of an HttpWebRequest. I don't think there is a way of editing the referrer of your request in context.
using System.Net;
HttpWebRequest Req= (HttpWebRequest)System.Net.HttpWebRequest.Create("http://somewhere.com/");
Req.Referer = "http://www.fakesite.com";

Graph api, C# to share data from app to my wall

i am trying to develop an app which can allow me to share data on Facebook wall.
For eg: consider the Facebook Canvasapp "Run with Friends". This is a canvas app using Python and Php.
https://developers.facebook.com/docs/samples/. I will be able to share data from this app to my wall./me
Before doing this v need a access token. I was able to get the authorization, accesstoken using Graph api, Oauth2.0, C#, asp.net
public string AuthorizationLinkGet(bool bUserInfo, bool bFriends, bool bfeed, bool bPhotos, bool bEvents, bool bMessages)
{
string url = string.Format("{0}?client_id={1}&redirect_uri={2}", AUTHORIZE, this.ConsumerKey, CALLBACK_URL);
if (bUserInfo == true || bFriends == true || bfeed == true || bEvents == true || bPhotos == true || bMessages == true)
{
url += "&scope=email";
if (bUserInfo == true)
{
url += ",user_about_me,user_interests,user_likes,user_location,user_notes,user_education_history,user_hometown";
}
if (bFriends == true)
{
url += ",read_friendlists,user_groups";
}
if (bfeed == true)
{
url += ",read_stream";
}
if (bEvents == true)
{
url += ",user_events";
}
if (bEvents == true)
{
url += ",user_photo_video_tags";
}
if (bMessages == true)
{
url += ",read_mailbox";
}
}
return url;
}
<add key="APIKey" value="*************************"/>
<add key="Secret" value="**********************"/>
So now how do I be able to share data from the app onto my FB wall.
I've tried Sharekit but look like Sharekit is for mobile apps.
public void AccessTokenGet(string authToken)
{
this.Token = authToken;
string accessTokenUrl = string.Format("{0}?client_id={1}&redirect_uri={2}&client_secret={3}&code={4}",
ACCESS_TOKEN, this.ConsumerKey, CALLBACK_URL, this.ConsumerSecret, authToken);
string response = WebRequest(Method.GET, accessTokenUrl, String.Empty);
if (response.Length > 0)
{
//Store the returned access_token
NameValueCollection qs = HttpUtility.ParseQueryString(response);
if (qs["access_token"] != null)
{
this.Token = qs["access_token"];
}
}
}
does any one know how to develop this canvas app in C# using Graph Api
I have no idea abt all the curls and things in Php
Also, I see people using REST, facebookservice, facebook SDK. Where would these fit it?
Thanks
Sun
Ask for the publish stream permission.
You need to POST to https://graph.facebook.com/USER_ID/feed/access_token=lerolero, posting a json like this:
{"name": "name"
"link": "http://www.link.com/",
"caption": "title",
"description": "description",
"picture": "http://www.link.com/image.jpg"}
http://developers.facebook.com/docs/reference/api/, read the publishing section, you can send a lot of other information.
Edit:
I see two possibilities.
If the facebook integration its not part of your bussiness rules (if you will not use the user information), you can just add the SHARE widget, in this case, the user will se a button, and when he click the button, the facebook authentication page will open, and when the authentication is done, the share widget will popup automatically.
If you gonna access the user information (if will be somehow attached to the user account), then, when the user clicks the button, you have to check the user account forward a facebook account, if theres not one, you have to open a authentication popup, if the user succeeds to login into facebook, the authentication popup will return you a verification code. You must exchange the verication code for a access token and attach the access token to the user account in your database. In the authentication step, you have to ask for two special permissions, the stream publish permission and the offline access permission. The first one is about the resource to publish in the user wall, and the second one its about the access token life cycle (if you dont ask for this permission, the access token will have a short life cycle, and you will need to reauthenticate the user into facebook again and again, we dont want that).
Into the code:
When the user clicks a button, call a ajax function that checks if there's a access token in the user account. If theres, return the access token (take care here, if you create a ajax that return a access tokem based on a user id, you will have a very bad security issue), if theres not, return false.
If the code returned is false, call a function that opens a popup with the facebook authentication url. In the facebook authentication popup callback url, just exchange the verification code for a access token and store it in the database. You need to keep listening the popup.closed state, to know when the process is done and call another ajax function that checks if now theres a access token in the user account or not, if not, the user just closed the popup.
If the code returned is an access token, call a ajax function that post in the user wall, its very easy, like this:
string facebookurl = "https://graph.facebook.com/me/feed?access_token=32423"
string parameters = "message=aaaa&link=bbbb";
WebRequest req = WebRequest.Create(facebookurl);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(parameters);
req.ContentLength = bytes.Length;
Stream stream = req.GetRequestStream();
stream.Write(bytes, 0, bytes.Length);
stream.Close();
WebResponse res = req.GetResponse();
StreamReader streamReader = new StreamReader(res.GetResponseStream());
If you need any other piece of code, let me know.

cookie isn't updated until page refresh... how to avoid that?

I have some asp.net pages that read and write cookie values. During the life cycle of a page it may update the cookie value and then need to read it again further in the code. What I've found is that it's not getting the latest value of the cookie until a page refresh. Is there a way around this? Here's the code I'm using to set and get the values.
public static string GetValue(SessionKey sessionKey)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[cookiePrefix];
if (cookie == null)
return string.Empty;
return cookie[sessionKey.SessionKeyName] ?? string.Empty;
}
public static void SetValue(SessionKey sessionKey, string sessionValue)
{
HttpCookie cookie = HttpContext.Current.Request.Cookies[cookiePrefix];
if (cookie == null)
cookie = new HttpCookie(cookiePrefix);
cookie.Values[sessionKey.SessionKeyName] = sessionValue;
cookie.Expires = DateTime.Now.AddHours(1);
HttpContext.Current.Response.Cookies.Set(cookie);
}
What you're missing is that when you update the cookie with SetValue you're writing to the Response.Cookies collection.
When you call GetValue you're reading from the Request.Cookies collection.
You need to store the transient information in a way that you access the current information, not just directly the request cookie.
One potential way to do this would be to writer a wrapper class that with rough psuedo code would be similar to
public CookieContainer(HttpContext context)
{
_bobValue = context.Request.Cookies["bob"];
}
public Value
{
get { return _bobValue; }
set {
_bobValue = value;
_context.Response.Cookies.Add(new Cookie("bob", value) { Expires = ? });
}
}
I ran into needing to do similar code just this week. The cookie handling model is very strange.
Start using Sessions to store your information, even if it's only temporary.
Cookies rely on a header being sent to the browser before the page has rendered. If you've already sent information to the client then proceed to set a cookie, you're going to see this "page refresh delay" you've described.
If it's necessary to have this value, use a session variable between the time you set the cookie and when you refresh the page. But, even then I would just recommend avoiding settings cookies so late in the processing step and try to set it as early as possible.

Setting the Content-Type of an empty response in ASP.NET MVC

In order to support a legacy application that's in the field, I need my ASP.NET MVC app to return an empty response that also has a Content-Type. One of IIS, ASP.NET, or ASP.NET MVC is removing my Content-Type when I send back a null response. Is there any way around this?
(While not requiring an empty response with a set Content-Type would obviously be the ideal solution, the clients are already out there, and many of them cannot be upgraded.)
EDIT: Since there was a request for code: I'm proxying the request from the new web application to the one that older clients rely on. To do this, I have a subclass of ActionResult, called LegacyResult, that you can simply return for those methods that need to be handled by the old software. This is the relevant part of its code:
public override void ExecuteResult(ControllerContext context)
{
using (var legacyResponse = GetLegacyResponse(context))
{
var clientResponse = context.HttpContext.Response;
clientResponse.Buffer = false;
clientResponse.ContentType = legacyResponse.ContentType; /* Yes, I checked that legacyResponse.ContentType is never string.IsNullOrEmpty */
if (legacyResponse.ContentLength >= 0) clientResponse.AddHeader("Content-Length", legacyResponse.ContentLength.ToString());
var legacyInput = legacyResponse.GetResponseStream();
using (var clientOutput = clientResponse.OutputStream)
{
var rgb = new byte[32768];
int cb;
while ((cb = legacyInput.Read(rgb, 0, rgb.Length)) > 0)
{
clientOutput.Write(rgb, 0, cb);
}
clientOutput.Flush();
}
}
}
If legacyInput has data, then Content-Type is set appropriately. Otherwise, it's not. I can actually kluge the old backend to send an empty v. non-empty response for exactly the same request, and observe the difference in Fiddler.
EDIT 2: Poking around with Reflector reveals that, if headers have not been written at the time that HttpResponse.Flush is called, then Flush writes out the headers itself. The problem is that it only writes out a tiny subset of the headers. One of the missing ones is Content-Type. So it seems that, if I can force headers out to the stream, I can avoid this problem.
You have to trick the response into writing the headers, by falsely telling it there's content, then suppressing it:
/// [inside the writing block]
var didWrite = false;
while ((cb = legacyInput.Read(rgb, 0, rgb.Length)) > 0)
{
didWrite = true;
clientOutput.Write(rgb, 0, cb);
}
if (!didWrite)
{
// The stream needs a non-zero content length to write the correct headers, but...
clientResponse.AddHeader("Content-Length", "1");
// ...this actually writes a "Content-Length: 0" header with the other headers.
clientResponse.SuppressContent = true;
}

Resources